vba 日期加一年_VBA学习笔记47:程序优化与提速

117b7fea85a121ea4ee914d0b79abeb1.png

学习资源:《Excel VBA从入门到进阶》第47集 by兰色幻想


今天学习11个程序优化与提速的小技巧:

  1. 减少对象的调用

调用对象是非常非常的耗费资源的,所以一定要尽可能的少调用对象。包括:工作簿、工作表、单元格以及外引用对象。

而且在循环内外调用对象,对程序的运行速度也有影响。尽量在循环外调用对象。

2. 减少计算次数

程序的运算速度和计算次数有着很大的关系,所以要尽可能的减少计算的次数。

而且能在循环外计算出结果的,就不要在循环内计算。

3. 禁止闪屏

Application.ScreenUpdating当设置属性值为false时,可以禁止程序运行过程中的屏幕闪动,进而提高运行速度。

但是注意:只有对会引起闪屏操作的代码才有效,否则可能还会拖慢程序的速度。还有在关闭屏幕闪动后,记得在操作完或者程序的末尾,把屏幕闪动打开,否则平时的Excel也会禁止屏幕闪动,没有屏幕刷新。

Application.ScreenUpdating = False    '关闭屏幕闪动
Application.ScreenUpdating = True     '开启屏幕闪动

4. 增加变量的声明类型

声明变量时尽可能把变量的类型给一起声明了,否则计算机都会把它们默认为variant类型,然后据根它的赋值自动判断变量类型,易造成内存的浪费。

数组非常需要声明变量类型,养成习惯,给每个变量声明类型。

复习一下数据类型:

(1) 字符串 String,简写符号$,用于保存文本数据的,字符串内容应放置于双引号内。

(2) 数字类型:

① 整型 Integer,简写符号%,占用两个字节,表示的数据范围:-32768 ~ 32767。

② 长整型 Long,简写符号&,占用4个字节,表示的数据范围:-2147483648 ~ 2147483647。

③ 单精度浮点型 Single,简写符号!,占用4个字节,精度是6,只能保存小数点后最多6位的数据。

在表示负数时: -3.402823E38 ~ -1.401298E-45

在表示正数时: 1.401298E-45 ~ 3.402823E38

④ 双精度浮点型 Double,简写符号#,占用8个字节,精度是14,只能保存小数点后最多14位的数据。

在表示负数时: -1.79769313486231E308 ~ -4.94065645841247E-324

在表示正数时: 4.94065645841247E-324 ~ 1.79769313486231E308

——为避免浪费内存,定义数据类型时,要定义合适的类型。

(3) 日期型 Date,表示日期和时间,

表示的日期范围是:100年1月1日 ~ 9999年12月31日;

表示的时间范围是:0:00:00 ~ 23.59.59。

(4) 布尔型 Boolean,表示逻辑值:真、假 ,常用于条件判断语句。

其中“真”为True,“假”为False。

应当注意的是,当其它数据类型转换为布尔值时,0会转成False,其它值则变成True。当把布尔值转换成其他数据类型时,False会转换为0,True则是-1。

(5) 变体型 Variant, 几乎可以用于保存所有其它数据类型的数据。可以简单地理解为:当不知道变量所要表示的数据是什么类型时,就把它定义为Variant(但这种操作应当尽量避免)。

5. 减少工作表函数的使用

调用工作表函数可以让代码更简捷,但速度却不理想。减少对工作表函数的调用也是提升程序速度的方法之一。

例:统计A列中含有“加10分”的字符串次数。

①使用循环:

Sub C1()
 Dim x, arr, k, t, Y
 t = Timer
 For Y = 1 To 10
 arr = Range("a1:a6800")
 For x = 1 To UBound(arr)
   If InStr(arr(x, 1), "加10分") > 0 Then
     k = k + 1
   End If
 Next x
 Next Y
 Debug.Print Timer - t & "秒"
End Sub

用时:0.05秒

②使用函数:

Sub C2()
 Dim x, arr, k, t, Y
 t = Timer
 For Y = 1 To 10
 arr = Range("a1:a6800")
     k = Application.CountIf([a:a], "*加10分*")
     Next Y
 Debug.Print Timer - t & "秒"
End Sub

用时:0.52秒

使用工作表函数慢了十倍左右。

6. 减少VBA函数的使用

除了工作表函数,还有VBA函数,减少使用VBA函数也能提高程序的运行速度。

例:整除数值。

①用整除运算符

Sub D1()
Dim x, t, k
t = Timer
 For x = 1 To 1000000
   k = 10000  3
 Next x
 Debug.Print Timer - t
End Sub

用时:0.015秒。

②用VBA函数

Sub 用VBA函数算整除()
Dim x, t, k
t = Timer
 For x = 1 To 1000000
   k = Int(10000 / 3)
 Next x
 Debug.Print Timer - t
End Sub

用时:0.031秒。

使用VBA函数慢了一倍左右。

7. 用静态数组替换动态

直接声明足够大的静态数组,比声明动态数组再重新声明要快一点。一样是因为内存的原因,动态数组占用的内存较大,即使后面重新声明了,但按需操作吧。

8. 填充前先清空

填充新数据前,先把旧数据清空掉,再填充新数据会快一点。这也算是一个编程习惯,如果旧数据没用的话,就先清除再填充吧,以免出现某些数据没有更新而导致出错。

9. 批量替代个体

尽量想办法让程序做到批量操作,尤其是数据很多的时候,反复单个操作会出现不停调用内存的情况,会让程序变慢、甚至卡机。

例:判断工作表名称并隐藏。

① 循环判断每个工作表的名称再隐藏。

Sub T1()
 Dim x As Integer, t
 显示工作表
 t = Timer
 For x = 1 To Sheets.Count
   If Sheets(x).Name Like "Sh*" Then
     Sheets(x).Visible = False
   End If
 Next x
 Debug.Print Timer - t
End Sub

用时: 0.125秒。

② 把所有的工作表名称放到数组里判断,后再批量隐藏。

Sub 隐藏工作表2()
 Dim x As Integer, t, arr(), k
  显示工作表
 t = Timer
 For x = 1 To Sheets.Count
   If Sheets(x).Name Like "Sh*" Then
      k = k + 1
      ReDim Preserve arr(1 To k)
      arr(k) = Sheets(x).Name
   End If
 Next x
 Sheets(arr).Visible = False
 Debug.Print Timer - t
End Sub 

用时:0.047秒。

10. 减少循环次数

减少循环次数是最直接的优化速度方法,但操作起来有难度,需要学习相关的知识.如:

① 利用VBA字典,在查找时替代循环查找,相关方法参见VBA80集字典部分。

② 学习VBA算法,减少不必要的循环和运算,如:第45集的换位算法和29集下棋法。

另外,像26集的排序算法,也是通过排除不必要的运算和循环来加快程序运行速度。

11. 巧妙填充公式

向单元格输入公式,如果是连续的,就可以用填充的方法来完成。

例:在E列金额列填充公式,金额=数量*单价。

d15956465c0a14ac9faf594d8df723ae.png

① 平常是通过循环来填充公式:

Sub F1()
 Dim x, t
 t = Timer
 Range("e2:e1000") = ""
 For x = 2 To 1000
   Cells(x, "e") = "=C" & x & "*D" & x
 Next x
 Debug.Print Timer - t
End Sub

用时:0.125秒。

② 使用filldown方法,向下填充。

Sub 填充公式方法2()
 Dim x, t
 Range("e2:e2000") = ""
 t = Timer
   Cells(2, "e") = "=C2*D2"
   Range("e2:e2000").FillDown
 Debug.Print Timer - t
End Sub

用时:0.016秒。


在上个月,刚好和知友Erik H 讨论了一个数据类型的问题:

sub test()
dim x as Long
x=2000*365
end sub

程序报错:数据溢出了。

1b648a1413dc411ca241dc6e44b96cae.png

按理,x=2000*365=730000,是在Long的范围-2147483648 ~ 2147483647里,为什么还会溢出呢?

69818b35bb7fdb34ebffa402e6b6cf1e.png

调用watch框,查看数据类型,可以发现常量2000和365的数据类型是integer整型,也就是说系统会默认给常量进行分配数据类型了。

在VBA中,等式的运算逻辑是把等式右边的值赋值给等式左边的变量,即把2000*365的计算结果赋值给x。

试着把不给x赋值,看会怎么样。

9681db185852656ebb33b366d80a4cc4.png

依旧是溢出了,那就应该和x的类型没关系,在2000*365计算的时候就出错了,两个integer相乘,系统应该默认结果也为integer。而计算结果是730000,已经超出了integer的数值范围。

把2000和365都定义为Long之后就没有报错了。

Sub test()

Dim x As Long,a As Long,b As Long

a = 2000
b = 365
x = a * b

End Sub

所以在写程序时,还需要考虑运算式的计算结果的数值范围,以免数值溢出。


小结

上面有些例子可能举的不算太贴切,但只是为了作简单说明,希望大家能get到这些点。

我最近也有为工作写了一些程序,比如合并工作簿,自己写的还是不够周全,在公众号看到大神写的合并工作簿程序,会有检查的步骤,比如有没有选中要合并的工作簿已经被打开了。如果没写检查这一步,又出现了这种情况,程序会报错的。要逐渐去养成好的编程思维和习惯,多学多练。

以上,晚安。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
非常好的问题!让我来回答你的问题。 首先,关于VBA学习笔记(一):自动添代码,你可以使用VBA的宏来自动添代码。具体步骤如下: 1. 打开你要添代码的Excel文件,并按下Alt + F11进入VBA编辑器界面。 2. 在左侧的“项目资源管理器”窗格中,展开你的Workbook,并双击“这台电脑”(或“Microsoft Excel 对象”),打开相应的代码窗口。 3. 在代码窗口的顶部,选择“工具” > “宏” > “录制新宏”。 4. 在弹出的“新建宏”对话框中,为新宏命名,并选择一个快捷键,以便日后调用。 5. 点击“确定”后,VBA会自动开始录制你的操作。 6. 在代码窗口中,添你需要自动执行的代码。 7. 完成代码添后,点击“停止录制”按钮,保存你的新宏。 接下来,关于VBA修改注册表,你可以使用VBA的“WshShell”对象来实现。具体步骤如下: 1. 在VBA编辑器中,打开你要修改注册表的代码窗口。 2. 在代码窗口的顶部,添以下代码: ``` Dim WshShell As Object Set WshShell = CreateObject("WScript.Shell") ``` 这将创建一个名为“WshShell”的对象,用于执行后续的注册表修改操作。 3. 接下来,你可以使用该对象的“RegWrite”方法来修改注册表。例如,以下代码将修改Windows启动时自动运行的程序列表: ``` WshShell.RegWrite "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run\MyApp", "C:\MyApp.exe", "REG_SZ" ``` 该代码将在“HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run”键下添一个名为“MyApp”的值,其值为“C:\MyApp.exe”,类型为“REG_SZ”。 4. 完成代码添后,保存并执行你的代码。 希望这些步骤对你有所帮助!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值