分享

实战:单元格处理应用举例

 liuyunhe1954 2017-02-14

掌握了Excel中最常见的range对象的属性和方法过后,再利用上VBA里的判断和循环控制结构语句,我们就可以自己慢慢解决一些小的需求了。
今天A哥就带大家从实例出发,来把我们之前学习的知识给串起来。

案例:删除零值单元格所在行,在一个range区域,如果有任何一个单元格的值为零值,则删除本行。数据大家可以自行举例,可以使用rand函数配合int函数来随机生成含有零值的区域。

在解决实际需求前,我们都需要拟定大体的思路。对于这个问题,我们很直观的可以想到:遍历每一个单元格,判断如果是零的话,就删除行。

那么,我们可以写这样一个程序:

Sub delete_zero()Dim Rng As RangeDim i%, j%, Row_Num%, Col_Num%Row_Num = Range('a1').CurrentRegion.Rows.CountCol_Num = Range('a1').CurrentRegion.Columns.CountFor i = 1 To Row_Num    For j = 1 To Col_Num        If Cells(i, j).Value = 0 Then            Cells(i, j).EntireRow.Delete            Exit For        End If    NextNextEnd Sub

个中的逻辑也很简单,利用i循环行,j循环列。如果单元格的数值为0,那么就删除这行,并不再执行列的循环,跳出来继续执行行的循环。

看起来不错,运行一下看看吧!
F5结果执行如下图

等等,怎么里面还有零?

我们的逻辑似乎没有问题,但我们在执行过程中没有考虑excel删除行的执行方式问题。一般来说,执行行删除操作,下面的行会自动上移。因此,执行过一次行删除之后,每一行的行号相对于原始表已经发生了变化,自然会漏删一些行。

解决方法很简单,只要把行的循环进行倒序删除就可以。

Sub delete_zero()Dim Rng As RangeDim i%, j%, Row_Num%, Col_Num%Row_Num = Range('a1').CurrentRegion.Rows.CountCol_Num = Range('a1').CurrentRegion.Columns.CountFor i = Row_Num To 1 Step -1    For j = 1 To Col_Num        If Cells(i, j).Value = 0 Then            Cells(i, j).EntireRow.Delete            Exit For        End If    NextNextEnd Sub

F5运行看看,结果里面还有0吗?

这个需求的解决,到这里,似乎是结束了,然而并没有。我们刚才处理的是很小一部分数值,这种循环方式速度也还可以,但如果是大量数据,例如1000 行呢?

我们用上述方式,对1000 行数据进行了处理,处理时间为0.71秒,如果是处理10000条数据岂不是要更长?

有没有更快的运行方式呢?

我们再仔细观察一下上面的代码,我们发现,Excel每发现一行,就要执行一次删除操作,这会相当浪费时间。可不可以一次性把发现的单元格都删除呢?

这就要用到我们之前将的union方法了。

修改后的代码如下:

Sub delete_zero_new()Dim Rng As RangeDim i%, j%, Row_Num%, Col_Num%Row_Num = Range('a1').CurrentRegion.Rows.CountCol_Num = Range('a1').CurrentRegion.Columns.CountFor i = Row_Num To 1 Step -1    For j = 1 To Col_Num        If Cells(i, j).Value = 0 Then            If Rng Is Nothing Then                Set Rng = Cells(i, j)            Else                Set Rng = Union(Rng, Cells(i, j))            End If            Exit For        End If    NextNextRng.EntireRow.DeleteSet Rng = NothingEnd Sub

这里要注意的是object的使用。

  1. 一定要用set来给object赋值。例如这里,如果只写rng=cells(i,j),像函数那样赋值,则会出现对象错误报错。要改成 set rng =rn

  2. 在判断是否为nothing的时候需要用is,而不是用=。

改进了代码之后,F5运行程序只需要0.32秒,是不是比之前快了很多?

根据以上这个案例,我们可以直观的得到一个经验:在处理大量数据的时候,要尽量减少excel的固有操作,如select, activate, delete等等,这样可以大大提高运行速度。

总结一下:

  • 使用for来遍历所有单元格

  • 使用一次性excel操作,避免多次重复操作

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多