优化代码
1 强制声明变量
VBA并不要求用户必须声明每个变量,VBA会自动为每个变量分配数据类型。 这是相对于其它程序软件的一个优点,即兼容性好。然而同时也是一个缺点,不声明变量其类型时程序在执行时将会消耗更多的内存。相当于牺牲效率换取兼容性。
为了提升程序的效率,在编写代码时,应尽量将所有变量显示声明,除非某个变量的类型无法把握(初学者较常见)。
2 善用常量
如果某个数值或者字符串在程序中反复出现,那么尽量声明一个常量做取代该
值,将后在代码中直接调用常量。
3 关闭屏幕更新
在单元格中写入数据或者批量插入图形对象时,每执行一句代码屏幕会更新一次,而更新屏幕需要时间。在大多数情况下,完全没有必要更新屏幕的状态。开发者可以关闭屏幕更新来提升效率,等所有过程执行完毕后再恢复屏幕更新即可。
VBA提供了一个可以控制屏幕更新开、关的属性:ScreenUpdating。它的语法如下:
Application.ScreenUpdating=True/False
如果将该属性值设为True则允许屏幕更新,否则禁止屏幕更新。
4 利用WITH减少对象读取次数
利用WITH减少对象读取次数
VBA中读取对象需要花费一定的时间,而且对于多级对象(同时列出父对象与子对象)时需要的时间更长。例如以下两句代码:
[a1]
ThisWorkbook.Sheets(1).[a1]
虽然它们都指向同一个单元格对象,对A1读写后的结果也完全一致,然而前者圆点更少,读取时间也相应更少。在VBA中引用对象时,每出现一个圆点就需要去读取一个对象。
5 利用变量减少对象读取次数
如果某个变量在一个过程中多次出现,应考虑用一个变量来替换该对象。因为变量存在内存中,VBA读取内存数据远远快于对象。
6 善用带$的字符串处理函数
在VBA中,有两套字符串处理函数,包括带“$”和不带“$”的函数,例如Mid和Mid$,Left和Left$,Right和Right$。
如果使用不带“$”符号的函数计算字符串,那么VBA将字符串作为变体型数据进行计算,而使用带“$”的函数时则将字符串当做String类型进行计算。显示变体型数据在计算时需要更多的内存空间。
例如以下两句代码,第二句在执行效率上会稍占优势: Reault = Mid("中华人民共和国", 3) Reault = Mid$("中华人民共和国", 3)
7 善用循环中的步长减少循环次数
当使用有针对性的For循环,即仅仅需要对循环对象中的部分对象进行操作时,应该调整循环的步长来减少循环的次数。
例如将奇数行添加背景色,步长为1的For循环代码如下:
Sub 前10000行背景着色() tim = Timer
For i = 1 To 100000
IF i Mod 2 = 1 Then Cells(i, 1).EntireRow.Interior.ColorIndex = 15 Next i
MsgBox Format(Timer - tim, "0.00") & 秒 End Sub
本代码需要循环的次数是10000次
Sub 前10000行背景着色2() tim = Timer
For i = 1 To 100000 Step 2
Cells(i, 1).EntireRow.Interior.ColorIndex = 15 Next i
MsgBox Format(Timer - tim, "0.00") & 秒 End Sub
本代码需要循环的次数是5000次,其执行结果与前一个过程完全一致。读者可以分别执行两个过程测试其时间。
8 利用数组代替单元格对象
VBA处理数组的速度远远大于处理对象的速度,对于可以利用数组来替换对象的都尽量使用数据,例如1000个图片的名称,或者1000个单元格,或者不确定个数的工作表名称。
9 不重复调用自定义函数时不使用自定义函数
在VBA中,对于一些较短小的自定义函数,调用函数往往比函数过程的执行时间都长。对于简单的运算尽量不使用自定义函数,而是直接将函数的过程写在Sub过程中。
10 将不改变值或者属性的语句放到循环语句外
循环语句都需要反复运行,如果错误将不需要循环执行的语法置于循环体中将会消耗额外的内存,占用不必要的时间。
11 将不改变值或者属性的语句放到循环语句外
循环语句都需要反复运行,如果错误将不需要循环执行的语法置于循环体中将会消耗额外的内存,占用不必要的时间。
12 尽量调用内置功能
有很多操作,可以编写VBA代码计算来实现,也可以调用Excel的内置的功能实现。开发者应尽量借用内置功能实现,除了速度快之外,调用内置功能的代码也简单许多。
例如对一列数据排,虽然可以对数据逐个进行大小比较,然后再按大小顺序排列来完成需求,但在写法上以及效率上较一句代码调用内置排序功能Sort会差一些。
13 利用对象循环替代单元格循环
如果对当前表中与单元格关联的对象进入某项操作时,如果循环单元格方式可以完成,循环其它对象也可以完成,那么尽量对其它对象进行循环,从而减少循环次数。