Excel VBA入门(8): 代码调试/错误处理/代码优化
VBE有丰富的调试工具, 比如立即窗口, 本地窗口, 监视窗口, 断点调试...
第一个博文中已经讲过调试的基本操作: 设置断点, F5运行, F8逐条运行
断点就是程序中暂停停止运行的位置, 设置断点之后, 当运行到断点行所在的语句程序就进入中断模式,
此时在本地窗口和立即窗口中 可以查看变量以及对象的属性值.
1. debug 介绍: 调试工具的基石
debug.print x 在不中断程序的情况下输出x 的值
debug.assert 与if 类似, 用与判断一个条件是否成立, 但是if 语句不会暂定程序的执行, 如果assert方法的参数不成立,
程序会暂停进入中断模式.
Function assert_test(x As Integer, y As Integer) As Double
Debug.Assert y <> ' y=0则进入中断模式
If y <> Then
assert_test = x / y
End If
End Function
Sub test()
MsgBox assert_test(, ) ' 正常运行
MsgBox assert_test(, ) ' 在Debug.Assert y <> 0 程序会中断
End Sub
立即窗口的使用 : 立即窗口的输出如果超过200行, 就只显示最后200行的内容
打印的关键字是 print 或者?
print assert_test(,)
3.33333333333333
?sqr() ' 按下Enter
1.4142135623731
其他
for each sh in sheets: debug.Print sh.name: next ' Enter
Sheet8
Sheet9
Sheet10
其他
for i = to : debug.Print i*i: next i
本地窗口的使用: 单步调试下, 本地窗口可以查看当前过程的所有变量和对象的状态(视图-->本地窗口), 很简单不叙述了...
监视窗口比本地窗口灵活, 可以自己选择想要查看的变量, 这个在Excel入门系列第一篇博文中已经讲过...
2. 错误处理
一般错误分为三种:
(1) 编辑错误: 不正确的代码导致的, 没有end if 等
(2) 运行时错误: 试图执行一个不可能完成的任务: 重命名已经打开的文件, 被除数是0....
(3) 逻辑错误: 语法正确, 操作正当情况下还是没有出想要的结果
on error 语句捕捉错误并进行处理, 告诉程序发生错误时需要转到哪个地方进行处理
on error goto line | resume next | goto 0
on error goto line 启动错误处理程序, line 参数表示行标签或者行号, 必须和 on error 在同一个过程中.
Sub errtest()
On Error GoTo errhandle 'errhandle为标签
ChDrive "A"
Exit Sub
errhandle:
MsgBox "程序出错, 请联系技术人员" & vbCrLf & "错误编号:" & _
Err.Number & "," & Err.Description, vbInformation, "错误提示"
Err.Clear
End Sub
vbcrlf 表示换行
chDrive "A" 表示磁盘驱动器A没有插入软盘时将弹出 设备不可用的 提示
得到结果:
或者用行号表示, 随便一个数字就行! 不是真的行号
Sub errtest()
On Error GoTo 'errhandle为标签
ChDrive "A"
Exit Sub
MsgBox "程序出错, 请联系技术人员" & vbCrLf & "错误编号:" & _
Err.Number & "," & Err.Description, vbInformation, "错误提示"
Err.Clear
End Sub
如果发生错误不影响后面的程序, 那么直接就写 on error resume next
3. 代码优化
实例1: 一般工作表函数比普通VBA代码更有效率
Sub test()
Dim num As Long, i As Integer, tm As Date
Dim Cell
tm = Timer
For i = To ' 只是为了增加循环次数
For Each Cell In Range("A1:A80")
num = num + Cell.Value
Next
Next i
Debug.Print "普通运行时间1:" & Format((Timer - tm), "0.0000") & "秒" tm = Timer
For i = To
num = WorksheetFunction.Sum(Range("A1:A80"))
Next i
Debug.Print "用sum函数的运行时间2:" & Format((Timer - tm), "0.0000") & "秒"
End Sub
普通运行时间1:0.3359秒
用sum函数的运行时间2:0.0078秒.
实例2: 减少对象的激活或者选择
初学者很喜欢用录制宏, 但是录制宏得到代码很冗余, 有很多的select , activate 语句, 实际上很多对象的操作是不需要激活该对象的.
例如当前工作表是sheet1, 现在要给sheet2 的区域A1 赋值
' 录制宏得到的
Sheet2.Select
Range("A1").Select
ActiveCell.Value = "Hello"
' 实际很简单
Sheet2.Range("A1").Value = "Hello"
实例3: 少用variant 类型的变量
variant 比较省事, 但是variant 需要占用很多的内存,(integer 占用2个字节, long数据占用4个字节, 全数字的variant 数据占用16个字节)
你可以设置不同的变量进行运算10000次比较运行时间.
实例4: 减少用. 点的数量
对于对象属性的调用, 一般采用 object.method. 点的数量越少速度越快.
对同一对象的重复引用, 可以设置一个变量
ThisWorkbook.Sheets("try").Cells(, ) =
ThisWorkbook.Sheets("try").Cells(, ) =
ThisWorkbook.Sheets("try").Cells(, ) = ' set
Set w = ThisWorkbook.Sheets("try")
也可以用with 语句
With ThisWorkbook.Sheets("try")
.Cells(, ) =
.Cells(, ) =
End With
实例4: 用数组代替range
如果只对range对象中的单元格的值进行处理, 而不用到单元格的属性和方法, 可以使用数组处理range对象.
数组的处理速度远远快于range对象的运算速度
Dim arr()
arr = Range("A1:E400") ' 生成一个400行6列的二维数组
数组arr必须定义为variant 类型, 数组的下表下界是1, 并且不受option base 的影响.
注意, 即使引用的范围只有一行或者一列, 赋值的数组仍然是二维数组
arr(range("A1:A4"))
赋值之后, arr即为一个arr(1 to 44, 1 to 1)的二维variant 数组, 元素的下标为arr(1,1), arr(2,1), arr(3,1), arr(4,1).
经过数据处理之后, 把数组变量写入工作表区域中: range("A1:E400")=arr
实例5: 让代码"专注"运行--> 关闭屏幕刷新
在过程的一开始写: Application.ScreenUpdating = False
在结果的时候Application.ScreenUpdating = True 还原设置
实例6: 单元格/区域的表示方法
cells(1,1), range("A1"), [A1] 三种方法中cells(1,1)是最快的, [A1]最慢
但是三种方法各有各的优点, cells(1,1)可以精确的获得单元格的行列, range("A1") 可以获得属性与方法
对于工作表, sheets(1) 比sheets("sheet1") 速度快, 其实VBA看到名称时, 先把名称解析为索引.
Excel VBA入门(8): 代码调试/错误处理/代码优化的更多相关文章
- Excel VBA入门(七)注释、宏按钮及错误处理
系统性的知识前面已经讲完,从本章开始,本系列教程涉及的将会是一些相对凌散的内容. 1. 注释 代码注释是一件利人利己的事,为了方便自己在代码需要更新修改时,依然能够快速地看懂自己完的每一行代码到底是什 ...
- Excel VBA入门(九)操作工作薄
虽然我前面讲过,在VBA中操作工作薄并不是件明智的事,但有些时候,还是避免不了要这么做.绝大多数情况下,我们要做的是获取到某个工作薄对象,并以此来获得其中的工作表对象,然后再对工作表中的数据进行处理. ...
- Excel VBA入门(八)单元格边框
本文基于以下文件 http://pan.baidu.com/s/1nvJtsu9 (部分)内容预览: 1. 边框样式 Sub cell_format() Dim sht As Worksheet Di ...
- Excel VBA入门(六)过程和函数
前面讲过,VBA代码有两种组织形式,一种就是过程(前面的示例中都在使用),另一种就是函数.其实过程和函数有很多相同之处,除了使用的关键字不同之外,还有不同的是: 函数有返回值,过程没有 函数可以在Ex ...
- Excel VBA入门(五)Excel对象操作
本章是本系列教程的重点.但我觉得应该不是难点.从第零章开始到学完本章,应该可以把VBA用于实战中了. Excel对象主要有4个: 工作薄 Workbook 工作表 Worksheet 单元格区域 Ra ...
- Excel VBA入门(四)流程控制2-循环控制
所谓循环控制,即在循环执行一段代码,用于完成一些重复性任务. VBA中的循环控制语句主要有3种:for.while.loop.对于大多数人来说,for的使用频率最高,而我个人也觉得for是最为灵活的, ...
- Excel VBA 入门(零)
本教程所用系统环境: Windows 10 Excel 2013 1. 添加开发工具 打开Excel,依然找到"文件"->"选项"->"自 ...
- Excel VBA入门(十)用户窗体开发
VBA 中的用户窗体就是指带 UI 的用户界面,在运行的时候会单独弹出一个窗口,类似于在 windows 系统中运行的一个可执行程序一样(这个说法不太严谨,因为可执行程序也可能是只有命令窗口而没有 U ...
- Excel VBA入门(三) 流程控制1-条件选择
VBA中的流程控制分为两种,其一是条件结构式的,即根据条件判断的结果去选择性执行相应的语句(块):另一种是循环,即循环地执行语句(块).本节介绍第一种. 1. IF if 语句其实包含有几种形式: ① ...
随机推荐
- StatefulSet(一):拓扑状态
Deployment 实际上并不足以覆盖所有的应用编排问题. 造成这个问题的根本原因,在于 Deployment 对应用做了一个简单化假设. 它认为,一个应用的所有 Pod,是完全一样的.所以,它们互 ...
- Java多线程10:join()方法
一.前言 通过一个简单的例子引入join()方法 public class Thread01 extends Thread{ @Override public void run() { for(int ...
- 关于申请GMS认证来使用谷歌的一些服务应用及闭源API
房间内的主要大象正在获取Google移动服务(GMS)的许可证.这是指预先选择的谷歌应用程序阵列,它将谷歌本身的精髓包含在其配置中 - Google搜索,YouTube,Gmail,Chrome,G ...
- 【XSY3126】异或II 数学
题目描述 给你一个序列 \(a_0,a_1,\ldots,a_{n-1}\).你要进行 \(t\) 次操作,每次操作是把序列 \(x\) 变为序列 \(y\),满足 \(y_i=\oplus_{j=0 ...
- 深入理解JVM(5)——垃圾收集和内存分配策略
1.垃圾收集对象 垃圾收集主要是针对堆和方法区进行. 程序计数器.虚拟机栈和本地方法栈这三个区域属于线程私有的,只存在于线程的生命周期内,线程结束之后也会消失,因此不需要对这三个区域进行垃圾回收. 哪 ...
- 从线程池到synchronized关键字详解
线程池 BlockingQueue synchronized volatile 前段时间看了一篇关于"一名3年工作经验的程序员应该具备的技能"文章,倍受打击.很多熟悉而又陌生的知识 ...
- dubbo核心要点及下载(dubbo二)
一.dubbo核心要点 1):服务是围绕服务提供方和服务消费方的,服务提供方实现服务,服务消费方调用服务. 2):服务注册 对于服务提供方它需要发布服务,而由于应用系统的复杂性,服务的数量.类型不断的 ...
- 第三节:深度剖析各类数据结构(Array、List、Queue、Stack)及线程安全问题和yeild关键字
一. 各类数据结构比较及其线程安全问题 1. Array(数组): 分配在连续内存中,不能随意扩展,数组中数值类型必须是一致的.数组的声明有两种形式:直接定义长度,然后赋值:直接赋值. 缺点:插入数据 ...
- Beamer 跳到另外一页
\documentclass[english]{beamer}\usepackage{babel} \begin{document} \begin{frame}\frametitle{the refe ...
- Vorticity directions 1: self-improving property of the vorticity
在 [Li, Siran. "On Vortex Alignment and Boundedness of $ L^ q $ Norm of Vorticity." arXiv p ...