收藏 分享(赏)

编写高效Excel VBA代码的最佳实践.doc

上传人:scg750829 文档编号:8989115 上传时间:2019-07-19 格式:DOC 页数:22 大小:119.50KB
下载 相关 举报
编写高效Excel VBA代码的最佳实践.doc_第1页
第1页 / 共22页
编写高效Excel VBA代码的最佳实践.doc_第2页
第2页 / 共22页
编写高效Excel VBA代码的最佳实践.doc_第3页
第3页 / 共22页
编写高效Excel VBA代码的最佳实践.doc_第4页
第4页 / 共22页
编写高效Excel VBA代码的最佳实践.doc_第5页
第5页 / 共22页
点击查看更多>>
资源描述

1、很多 Excel VBA 文章和图书都介绍过如何优化 VBA 代码,使代码运行得更快。下面搜集了一些使 Excel VBA 代码运行更快的技术和技巧,基本上都是实践经验的总结。如果您还有其它优化 Excel VBA 代码的方法,可以在本文后留言或给出链接,与大家分享。对于应用程序属性,在代码运行时关闭除必需属性以外的其它所有属性在代码运行时关闭不需要的 Excel 功能。其原因是,如果通过 VBA 更新不同的单元格区域,或者从不同的单元格区域复制/ 粘贴来创建汇总表,则不希望 Excel 浪费时间和资源来重新计算公式、显示粘贴进度或者重绘网格,尤其在每次单独的操作后(更有甚者,如果代码使用了循

2、环,则每次单独操作后 Excel 都会在后台运行这些功能)。只需要在代码执行结束时进行一次重新计算和重绘就足以使工作簿更新。下面的代码将帮助您提高代码的执行速度。(1)放置在主代码前的一段代码,获取 Excel 当前的属性状态,然后将其关闭获得当前的 Excel 设置状态,将其放置在代码的开头screenUpdateState = Application.ScreenUpdatingstatusBarState = Application.DisplayStatusBarcalcState = Application.CalculationeventsState = Application.E

3、nableEventsdisplayPageBreakState = ActiveSheet.DisplayPageBreaks 注:这是工作表级的设置关闭一些 Excel 功能使代码运行更快Application.ScreenUpdating = FalseApplication.DisplayStatusBar = FalseApplication.Calculation = xlCalculationManualApplication.EnableEvents = FalseActiveSheet.DisplayPageBreaks = False 注:这是工作表级的设置(2)放置在主代

4、码结束后的一段代码,用来将 Excel 恢复到代码运行前的设置代码运行后 ,恢复 Excel 原来的状态; 将下面的代码放在代码的末尾Application.ScreenUpdating = screenUpdateStateApplication.DisplayStatusBar = statusBarStateApplication.Calculation = calcStateApplication.EnableEvents = eventsStateActiveSheet.DisplayPageBreaks = displayPageBreaksState 注:这是工作表级的设置下面简

5、要解释这些设置:Application.ScreenUpdating:将该属性设置为 False,告诉 Excel 不要重绘屏幕。其优点是不需要 Excel 花费资源来绘制屏幕,因而其改变会更快而不致让用户察觉其变化。因为如此频繁地绘制屏幕需要大量的资源,所以关闭绘制屏幕直到代码执行结束。在代码结束前,确保重新开启了该属性。Application.DisplayStatusBar:将该属性设置为 False,告诉 Excel 停止显示状态栏。例如,如果使用 VBA 复制/粘贴单元格,当粘贴执行时 Excel 将在状态栏中显示操作的进度。关闭屏幕更新不会关闭状态栏显示,因此,如果需要的话,可以禁

6、用屏幕更新而仍然可以通过状态栏给用户提供反馈。记住,如果将该属性设置为 False,在代码结束前应该将其设置为 True。Application.Calculation:该属性允许编程设置 Excel 的计算模式。“手工的”(xlCalculationManual)模式意味着 Excel 等待用户(或代码)来触发计算;默认为“自动的”(xlCalculationAutomatic )模式,意味着由 Excel 来决定何时重新计算工作簿(例如,当在工作表中输入新公式时)。由于重新计算工作簿将花费时间且浪费资源,因此可能不希望每次改变单元格值时 Excel 都触发重新计算。当代码执行时关闭重新计算

7、,在代码结束前再设置回重新计算模式。Application.EnableEvents:将该属性设置为 False,告诉 Excel 不要触发事件。你可能不希望 Excel 为每个正在通过代码发生改变的单元格触发事件,关闭事件将加速 VBA 代码的执行。ActiveSheet.DisplayPageBreaks:当在较新版本的 Excel 中运行 VBA 时,则可能比在早期版本的 Excel 中需要更长的时间完成。例如,需要几秒钟在早期版本的 Excel 中完成的宏可能需要几分钟才能在更高版本的 Excel 中完成。或者,第二次运行一个宏可能比第一次运行需要的时间更长。这是由于 VBA 宏修改了

8、多行或列的属性,或者必须强制执行计算Excel 分页符。如果宏设置了任何 PageSetup 属性或者手动设置了 PageSetup 属性,接着运行较大区域的行或列属性设置时会出现这样的问题。您可以将该属性设置为 False 来提高代码的运行速度。当然,在代码运行结束前,应将该属性恢复为原设置。在单个操作中读/写大块的单元格区域本技巧用于优化在 Excel 和代码之间转换数据的次数。使用数组变量存储所需要的值并执行取值或赋值操作,而不是一次遍历单个单元格并获取或设置单个值。例如,下面的代码在单元格区域 A1:C10000 中放置随机数。代码段一:运行速度较慢的代码Sub testSlow()D

9、im DataRange As RangeDim Irow As LongDim Icol As IntegerDim MyVar As DoubleSet DataRange = Range(“A1:C10000“)For Irow = 1 To 10000For Icol = 1 To 3MyVar = DataRange(Irow, Icol) 从 Excel 单元格中读取值 30K 次If MyVar 0 ThenMyVar = MyVar * MyVar 改变值DataRange(Irow, Icol) = MyVar 将值写入 Excel 单元格中 30000 次End IfNex

10、t IcolNext IrowEnd Sub代码段二:运行速度更快的代码Sub testFast()Dim DataRange As VariantDim Irow As LongDim Icol As IntegerDim MyVar As DoubleDataRange = Range(“A1:C10000“).Value 一次从 Excel 单元格中读取所有的值, 将其放入数组For Irow = 1 To 10000For Icol = 1 To 3MyVar = DataRange(Irow, Icol)If MyVar 0 ThenMyVar = MyVar * MyVar 改变数

11、组中的值DataRange(Irow, Icol) = MyVarEnd IfNext IcolNext IrowRange(“A1:C10000“).Value = DataRange 一次将所有结果写回单元格End Sub避免选取/激活对象使用选取的方法更新单元格区域是最慢的。在试验了使用 Range 对象、使用 Variant 类型和使用 Select 方法对一个大的单元格区域读写数据的操作后, Select 方法是最慢的。再来看一个例子:在工作表中有 40 个形状,在每个形状中写入 “Hello”。使用 Select 方法的代码为:Sub testSlow()Dim i As Inte

12、gerFor i = 0 To ActiveSheet.Shapes.CountActiveSheet.Shapes(i).SelectSelection.Text = “Hello“Next iEnd Sub运行速度更快的方法是完全避免使用选取并直接引用形状:Sub testFast()Dim i As IntegerFor i = 0 To ActiveSheet.Shapes.CountActiveSheet.Shapes(i).TextEffect.Text = “Hello“Next iEnd Sub在使用宏录制器时,所生成的程序代码在应用任何方法或属性之前都会激活或者选择对象。但是

13、,并不是在所有的情况下都需要这样做。所以,在您编写 VBA 程序代码时,不需要在对对象执行任何任务之前都激活或者选择每个对象。例如,在 Excel 中,我们如果要使第一行变成粗体就必须先选项中它。但在 VBA 中(除在图表操作时需要选中图表对象外),很少需要这样做,即 VBA 可以在不选中第一行的情况下,将它变成粗体。宏录制器的代码:Rows(“1:1“).SelectSelection.Font.Bold = True改编后的代码为:Row(“1:1”).Font.Bold=True这样做还可以使程序代码更简洁,并且程序可以运行得更快。工作簿设计好的工作簿设计和数据组织有助于编写运行良好的代

14、码。良好设计的工作簿,其执行效率和维护量将大大优化。可以说,工作簿设计是从大的宏观方面进行优化,而对代码的优化只是一些微观的细节上的优化。其他 尽量简化代码通过简化代码,可以提高程序的性能。您可以将通用过程编写为子过程来调用。例如,假设有一个应用程序需要在不同的地方实现查找一定范围内的某个特殊条目,在一个没有简化代码的应用程序中,不同的过程可能需要应用各自的算法以实现在某个范围内查找某一条目,修改每个过程使其采用一个更有效的算法并不是一件很容易的事。而一个简化的程序则只有一个查找算法,即将该查找算法编写成通用的子程序,需要查找某个范围的过程都调用该子程序,通过在查找方法的子程序中优化查找算法,

15、使得调用该方法的所有过程都享受性能提高所带来的好处。另外,删除所有无关的代码,这在所录制宏中表现得尤为明显。在录制宏时,经常会产生一些与所实现的功能无关的代码,您可以将这些代码删除,以使得代码得以简化。宏录制器生成无效代码的一个原因是它不知道在对话框中您选择了哪些选项,因此,当您关闭对话框时它将直接记录所有可用的选项。例如,选择单元格区域 G2:G20,然后在单元格格式对话框中改变字体样式为粗体,使用宏录制器生成的代码如下: Sub NowThis1()Dim Start As Double, Finish As DoubleStart = Timer-为了进行测试 ,将循环 100 次Dim

16、 N As LongFor N = 1 To 100*Range(“G2:G20“).SelectWith Selection.Font.Name = “Arial“.FontStyle = “Bold“.Size = 10.Strikethrough = False.Superscript = False.Subscript = False.OutlineFont = False.Shadow = False.Underline = xlNone.ColorIndex = xlAutomaticEnd With*Next-Finish = TimerMsgBox “本次运行的时间是 “ &

17、Finish - StartEnd Sub您能只用下面的一行代码为指定的单元格设置字体样式,不需要选择单元格区域。Range(“G2:G20“).Font.FontStyle = “Bold“如果您考虑到您想要宏所做的事情(本例中为使字体加粗),那么您可以查阅应用到 Font 对象的属性和方法列表,您将知道只需使用 Bold 属性编写这个宏代码以实现所需的功能。代码如下:Sub NowThis2()快约 10 倍Dim Start As Double, Finish As DoubleStart = Timer-为进行测试 ,将循环 100 次Dim N As LongFor N = 1 To

18、 100*Range(“G2:G20“).Font.Bold = True*Next-Finish = TimerMsgBox “本次运行的时间为 “ & Finish - StartEnd Sub您也能在用户界面中通过执行不同的方法来录制产生结果相同的操作对宏录制器进行试验。例如,如果您通过标准工具栏上的粗体按钮格式化某区域为粗体,那么宏录制器将使用Bold 属性。下面将要讲到的设置对象变量代替长对象引用,使用 WithEnd With 语句、执行 For EachNext 循环语句,根据程序环境尽量减少 OLE 引用,等等,均是简化代码的好方法。 强制声明变量在 VBE 编辑器中的菜单 “

19、工具选项”对话框中“ 编辑器” 选项卡中,您应该始终保持“要求变量声明”复选框被选中,这样将在模块代码顶部出现 Option Explicit 语句,要求您在编写代码时对所有出现的变量均进行声明,这样,在使用变量时减少内存需求并加速性能。(1)要节省内存资源,必须始终用特定的数据类型声明所有变量。如果不使用特定的数据类型声明变量,VBA 会创建 Variant 类型的变量,这将比任何其他数据类型要求更多的内存。(2)清楚每种数据类型需要多少内存以及它可以存储的值的范围。除使用较小的数据类型会导致隐性转换的情况外,应始终使用尽可能小的数据类型。例如,因为 Integer 类型的变量将被转换成 L

20、ong 类型的变量,应该将那些存储整型值的变量声明为 Long 类型,而不是Integer 类型。(3)除非确实需要,应避免使用浮点数据类型。尽管 Currency 数据类型更大,但它比 Single 数据类型快,因为 Currency 数据类型不使用浮点处理器。(4)如果在一个过程中多次引用一个对象,可以创建对象变量,并将对给对象的引用指派给它。因为对象变量存储对象在内存中的位置,VBA 将不必再次查找其位置。(5)将对象变量声明为特定的类型 (不是 Object 类型) ,以便利用早期绑定。(6) 减少”Variant”类型变量的使用虽然您可能发现在您的代码中使用 Variant(变体)变

21、量是方便的,但是如果您将变量清楚地声明为特定的数据类型,然后用 VBA 处理存储在该变量中的值,要比处理存储在 Variant变量里的值快。如果执行不涉及分数值的数学运算,那么在您的代码中使用 Long 型变量比使用 Variant 变量更快。Long 型变量也是在 ForNext 循环中索引值变量类型的最好选择。然而,您要注意到,您使用特定类型变量所获取的速度是以失去灵活性为代价的。例如,当使用特定数据类型时,您可能遭到变量溢出或类型不匹配的情形,而不会像 Variant 变量会自动进行类型转换处理。(7) 声明时指定特定的对象类型当您的宏被编译或者是运行(后台编译) 时,会解析对象及它们的

22、方法和属性的引用。经过宏编译解析的引用比在程序运行时必须被解析的引用要更快,因此,您最好跳过后台编译。如果您声明变量和参数为特定的对象类型(比如 Range 或 Worksheet),VBA 在编译您的程序时将解析引用为这些对象的属性和方法。(如果要查找指定对象类型列表,请参见” 对象浏览器”) 减少变量的作用范围并及时释放变量主要是对象变量,在其使用完后,及时释放。例如, Dim TempObj As AnyObject,AnObj As AnyObjectSet TempObj=New AnyObjectSet AnObj=TempObjSet TempObj=Nothing 释放对象变量

23、 使用常量变量会发生变化,因此 VBA 在程序运行时必须获取当前变量的值。在应用程序中使用常量会使程序运行更快。在编译您的代码时,常量仅计算一次并被存储。常量也能使您的宏程序更易阅读和维护。如果在您的程序中有一些不变的字符串或数值的话,您可以声明它们作为常量。 尽可能使用早期绑定绑定是指将程序调用与实际代码相匹配。为了实现早期绑定,先应创建对对象库的引用。早期绑定可以在代码中使用定义在对象库中的常量,可以自动列出对象的方法和属性,但早期绑定只有在所控制的对象拥有独立的类型库或对象库文件才适用且还需要已安装了特定的库。而后期绑定则只是在运行时才知道对象的类型并对对象进行引用,因此不具备上述特点。

24、使用早期绑定创建对象通常更有效率,使代码能获得更好的性能。因为对象的早期绑定引用在编译时可以通过 VBE 的解析,而不是通过运行时模块解析,因此早期绑定的性能要好得多。虽然在程序设计时不可能总是使用早期绑定,但应该尽可能使用它。 使用 For EachNext 循环可以使用 For EachNext 循环来保证程序代码更快地执行。在使用 For EachNext 循环时,对于存储在集合或数组中的每个对象执行一组语句,程序更简洁,也更容易阅读、调试和维护。当 For EachNext 语句迭代集合时,自动指定一个对集合当前成员的引用,然后在到达集合的尾部时跳出循环语句。与使用计数进行循环相比,在

25、遍历集合或数组时使用 For EachNext 循环将更快。在多数情况下,使用 For EachNext 循环也更方便,并且使您的宏更简洁、更容易阅读和调试。下面的示例运行很慢,因为在每次循环重复时它设置并调用了行变量.Row(i)。 Sub DoSomethingSlow()Dim Start As Double, Finish As DoubleStart = Timer-Dim Cell As Range, i As LongWith Sheet1.Range(“A1:A10000“)For i = 1 To 10000Set Cell = .Rows(i)If Cell 0 ThenC

26、ell.Font.ColorIndex = 5End IfNextEnd With-Finish = TimerMsgBox “本次运行的时间是 “ & Finish - StartEnd Sub下面的示例代码更简洁,其运行速度大约是上面代码的 23 倍。因为 For EachNext 循环自动记录行数并定位,而不需要调用变量 i。Sub DoSomethingFaster()快两至三倍Dim Start As Double, Finish As DoubleStart = Timer-Dim Cell As RangeWith Sheet1For Each Cell In .Range(“A

27、1:A10000“)If Cell 0 ThenCell.Font.ColorIndex = 5End IfNextEnd With-Finish = TimerMsgBox “本次运行的时间是 “ & Finish - StartEnd Sub 在执行循环时考虑如何能够尽可能地节省资源(1)分析循环以查看是否正在不必要地执行一些消耗内存的重复操作。例如,是否可以在循环外(而不是在循环中)设置某些变量?每次都通过循环执行的转换过程是否可以在循环之外执行?(2)考虑是否必须在满足特定的条件时才执行循环。如果是,也许可以更早地退出循环。例如,假设正在对一个不应该包含数字字符的字符串进行数据验证。如

28、果循环要检查字符串中的每个字符以确定其中是否包含数字字符,那么您可以在找到第一个数字字符时立即退出循环。(3)如果必须在循环中引用数组的元素,可以创建一个临时变量存储该元素的值,而不是引用数组中的值。从数组中检索值比从相同类型的变量读取值要慢。(4) 将属性和方法放在循环外部在代码运行时,获取变量的值快于获取属性的值。因此,如果您的代码在循环内部获取属性的值,您可以在循环外部将该属性的值先指定给一个变量,然后在循环内部使用此变量代替属性的值,这样的代码将运行得更快。下面所示的代码运行较慢,因为在每次重复循环时都必须获取 Sheet 的 Range 属性的值。Sub TryThisSlow()D

29、im Start As Double, Finish As DoubleStart = Timer-Dim MyLoop As LongFor MyLoop = 2 To 4001Cells(MyLoop, 2) = Sheet1.Range(“B1“)Next-Finish = TimerMsgBox “本次运行的时间是 “ & Finish - StartEnd Sub下面的示例与上面所产生的结果相同,但比上面的要更快,因为在循环开始以前我们已经将 Sheet 的 Range 属性的值指定给了单独的变量 MyVar。这样,代码将在每次重复循环时利用该变量的值,而不必每次都要调有属性。Sub

30、 TryThisFaster()快约 35%以上Dim Start As Double, Finish As DoubleStart = Timer-Dim MyVar As String, MyLoop As LongMyVar = Sheet1.Range(“B1“)For MyLoop = 2 To 4001Cells(MyLoop, 2) = MyVarNext-Finish = TimerMsgBox “本次运行的时间是 “ & Finish - StartEnd Sub如果您在一个循环内部使用多个对象访问,您也可以使用 WithEnd With 将您能够移动的对象移到循环外部。下面

31、的示例在每次循环重复时都调用 Sheets 对象和 Cells 属性。Sub NowTryThisSlow()Dim Start As Double, Finish As DoubleStart = Timer-Dim c As LongFor c = 1 To 8000Sheet1.Cells(c, 5) = cNext-Finish = TimerMsgBox “本次运行的时间是 “ & Finish - StartEnd Sub对上面的代码改写如下,使用 With 语句将调用 Sheets 对象移到循环外部,只剩余调用Cells。Sub NowTryThisFaster()约快 3 倍D

32、im Start As Double, Finish As DoubleStart = Timer-Dim c As LongWith Sheet1For c = 1 To 8000.Cells(c, 5) = cNextEnd With-Finish = TimerMsgBox “本次运行时间为 “ & Finish - StartEnd Sub注:您也能通过使用对象变量在循环外部调用该对象。 使用 WithEnd With 语句可以使用 WithEnd With 语句来尽量减少对象引用。使用 With 语句对指定的对象完成一系列的任务,而不用重复引用对象。也可以使用嵌套的 With 语句进

33、一步提高程序代码的效率。例如,下面的使用 WithEnd With 语句是在同一个单元格中执行多个操作。 With Workbooks(“Book1.xls“).Worksheets(“Sheet1“).Range(“A1“).Formula=“=SQRT(20)“With .Font.Name=“Arial“.Bold=True.Size=10End WithEnd With同理,可使用 WithEnd With 语句在同一个单元格区域中执行多个操作。 尽量减少 OLE 引用调用每个 VBA 方法或属性都需要一个或多个 OLE 引用,这样在代码中会有多个点运算符,而每次代码调用都需要对这些点

34、运算符进行解析,这将花费更多的时间。因此,在调用方法或属性时减少引用长度将是使您的程序运行更快的一种好方法。可以通过尽量减少在 VBA 程序代码中使用 OLE(对象链接与嵌入自动识别)引用来优化程序代码。VBA 语句中所调用的方法和属性越多,执行语句所用的时间就越多。例如下面的两个语句:语句 1: Workbooks(1).Sheets(1).Range(“A1“).value=“10“语句 2:ActiveWindow.Left=200执行时,语句 2 比语句 1 快。同样,上面所讲的对重复使用的对象引用指定一个变量,通过调用变量从而保证避免多次进行对象引用。 尽可能少使用“.”,使用对象变

35、量在前面已经介绍过的对长对象引用使用对象变量以及使用 WithEnd With 等都是简化”.”的方法。因为在代码中的每个句点都表示至少一个(而且可能是多个) 过程调用,而这些过程调用必须在后台执行。真正好的做法是在局部进行缓存对象引用,例如,应该把对象模型中较高层次的对象引用保存到局部对象变量中,然后用这些对象引用创建其他较低层次的对象引用。例如,引用某单元格数据时,可用如下代码: Dim i As LongFor i=1 to 10Workbooks(“Book1.xls“).Worksheets(“Sheet1“).Cells(1,i).Value=iNext i但下面的代码运行效率更高

36、,因为代码中引用 Workbook 对象和 Worksheet 对象的调用命令只执行一次,而上面的代码中却要执行 10 次。Dim ws As WorksheetDim i As LongSet ws= Workbooks(“Book1.xls“).Worksheets(“Sheet1“)For i=1 to 10ws.Cells(1,i).Value=iNext i当您一遍又一遍的使用相同对象引用时,您可以将该对象引用设置成一个变量,然后使用该变量代替对象引用。这样,您在代码中只需对该对象变量进行引用即可。例如,下面的示例在每行中调用 Workbook 对象的 Sheets 属性、Range

37、 属性和 Value 属性三次,当您循环 1000 次时,总共要调用属性 6000 次。Sub DoThis1()Dim Start As Double, Finish As DoubleStart = Timer-Dim N As LongFor N = 1 To 1000Workbooks(“Book1“).Sheets(1).Range(“c5“).Value = 10Workbooks(“Book1“).Sheets(1).Range(“d10“).Value = 12Next-Finish = TimerMsgBox “本次运行的时间是 “ & Finish - StartEnd S

38、ub您能在循环开始前通过设置 Workbooks(“Book1”).Sheets(1)作为一个对象变量来优化上面的例子,下面的示例在每行仅调用一个 Range 属性,当循环 1000 次时,总共只调用该属性 2000 次。注意,“Value”是一个缺省属性,通常不需要明确指定它,它将被自动调用。因此,该属性在下面的代码中被忽略。然而,就养成良好的编程习惯而言,还是建议您最好写明该属性。Sub DoThis2()快约 35%以上Dim Start As Double, Finish As DoubleStart = Timer-Dim ThisBookSheet As Object, N As

39、LongSet ThisBookSheet = Workbooks(“Book1“).Sheets(1)For N = 1 To 1000ThisBookSheet.Range(“c5“) = 10ThisBookSheet.Range(“d10“) = 12Next-Finish = TimerMsgBox “本次运行的时间是 “ & Finish - StartEnd Sub您可以比较这两个示例的运行速度,它们都得到同样的结果,但在我的机子上运行时,第二个示例比第一个快 60%。当然,您还能使用 WithEnd With 语句获得相同的结果。您也能不设置明确的对象变量,而是使用 With

40、语句减少对象的重复引用。上面的示例也能使用下面的代码,该代码仅调用 Workbooks 属性和 Sheets 属性一次,当循环 1000 次时,总共调用 1000 次属性。Sub DoThis3()快约 35%以上Dim Start As Double, Finish As DoubleStart = Timer-Dim N As LongWith Workbooks(“Book1“).Sheets(1)For N = 1 To 1000.Range(“c5“) = 10.Range(“d10“) = 12NextEnd With-Finish = TimerMsgBox “本次运行的时间是

41、“ & Finish - StartEnd Sub上述三个示例均得到相同的结果,但在我的机子上运行时,本示例比第一个示例快 50%以上。 在一个语句中进行复制或者粘贴在用宏录制代码时,首先是选择一个区域,然后再执行 ActiveSheet.Paste。在使用 Copy方法时,可以在一个语句中指定复制的内容及要复制到的目的地。例如,将 B5:C6 区域的内容复制到以单元格 B8 开始的区域中,使用宏录制器的代码为: Range(“B5:C6“).SelectSelection.CopyRange(“B8“).SelectActiveSheet.Paste经修改后的最佳代码是:Range(“B5:

42、C6“).Copy Destination:=Range(“B8“) 合理地使用消息框和窗体在一个很长的程序中,尝试着将消息框或者窗体安排显示在程序的最开始或最后面,避免干扰用户。此外,尽管窗体提供了许多功能,但它们能够导致文件大小迅速增加。还有就是尽量避免给工作表单元格链接用户窗体控件,因为这样将会导致链接更新操作,影响程序运行速度。 尽可能加速对数字的运算(1)当对整数进行除法时,您可以使用整型除法运算符() 而不是浮点除法运算符 (/),因为无论参与除法运算的数值类型如何,浮点除法运算符总会返回 Double 类型的值。(2)在任何具有整数值的算术表达式中使用 Single 或 Doub

43、le 值时,整数均将被转换成Single 或 Double 值,最后的结果将是 Single 或 Double 值。如果要对作为算术运算结果的数字执行多次操作,可能需要明确地将该数字转换为较小的数据类型。 提高字符串操作的性能(1)尽可能少使用连接操作。可以在等号左边使用 Mid 函数替换字符串中的字符,而不是将它们连接在一起。使用 Mid 函数的缺点是替换字符串必须与要替换的子字符串的长度相同。例如, Dim strText As StringstrText = “this is a test“Mid(strText, 11, 4) = “tent“(2)VBA 提供许多可用来替换函数调用的

44、内部字符串常量。例如,可以使用 vbCrLf 常量来表示字符串中的回车/换行组合,而不是使用 Chr(13) & Chr(10)。(3)字符串比较操作的执行速度很慢。有时,可以通过将字符串中的字符转换为 ANSI 值来避免这些操作。例如,下列代码会检查字符串中的第一个字符是否为空格:If Asc(strText) = 32 Then上面的代码会比以下代码更快:If Left(strText, 1) = “ “ Then 使用 Asc()检验 ANSI 的值在 VBA 中,可以使用 Chr$()函数把数转换成字符,并确定 ANSI 的值,但是更好的是使用Asc()函数把字符串转换成数值,然后确定

45、它的 ANSI 值。如果需要进行有限次数的这种检验,对程序代码的效率可能不会产生很大影响,但是,如果需要在多个循环内进行这种检验时,这将节省处理时间并且有助于程序代码更快地执行。 使用 Len()检验空串尽管有多种方法可检验空串,但首选的是使用 Len()函数。为了测试零长度的串,可以选择把串与”相比较,或者比较串的长度是否为 0,但这些方法比用 Len()函数要用更多的执行时间。当对字符串应用 Len()函数并且函数返回 0 值时,说明该字符串是空的或者是零长度的字符串。并且,因为在 If 语句内非零值被认为是 True,所以直接使用 Len()函数而不必与” 或 0 比较,减少了处理时间,

46、因此执行更快。 有效地使用数组用 VBA 数组而不是单元格区域来处理数据,即可以先将数据写入到某个数组,然后用一个语句就可以将数组中的数据传递到单元格区域中。(前文已述)在创建已知元素的确定数组时,使用 Array 函数对于节约空间和时间以及写出更具效率的代码是非常理想的。例如, Dim Names As VariantNames=Array(“Fan“,“Yang“,“Wu“,“Shen“)此外,应该尽量使用固定大小的数组。如果确实选择使用了动态数组,应该避免数组每增加一个元素就改变一次数组的大小,最好是每次增加一定数量的元素。 使用 Excel 的内置函数对于要实现的某一功能,如果有 Excel 的内置函数能够实现,那么就用 Excel 的内置函数,不需要另外自定义函数,因为自定义的函数总比 Excel 内置的函数慢。考虑在 VBA 代码中使用工作表函数操作单元格区域的 Excel 工作表函数通常比完成同样任务的 VBA 程序更快(但不能确保总是这样,您可以对它们进行速度测试)例如,在代码中使用 SUM 工作表函数比用 VBA 代码在单元格区

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 企业管理 > 管理学资料

本站链接:文库   一言   我酷   合作


客服QQ:2549714901微博号:道客多多官方知乎号:道客多多

经营许可证编号: 粤ICP备2021046453号世界地图

道客多多©版权所有2020-2025营业执照举报