01-Excel VBA 学习总结 - 基础知识

时间:2024.5.4

Excel VBA 学习总结 - 基础知识

1.什么是VBA?

当前辈们使用Excel的时候,他们惊奇的发现:Excel那是相当的彪悍,几乎任何的数据分析与处理,它都可以"近乎完美"(实际上不可能完美)完成。但是在使用的过程中,他们也同样发现,有很多工作是要重复做的。如果要想自动重复的完成这些工作,必须要借助其他的编程语言和工具。微软为了简化这个过程,开发了一个通用的自动化语言,这个就是VBA(Visual Basic for Application)。所有支持VBA的应用程序都可以方便的自动化执行某些固定的步骤,除此以外,支持VBA的应用程序之间也可以通过VBA这个平台进行互操作。由于这里讨论的是Excel中的VBA,所以我后面的总结内容都是以Excel中的VBA为主。

VBA是VB的一个子集,它们之间有些地方是不同的:

? VB程序可以独立的部署和运行,但是VBA程序不能离开宿主

程序运行。

VB程序是一个编译型的语言,程序需要编译后执行,而VBA

程序是解释执行的脚本语言。 ?

通过VBA这个工具,Excel就可以完成许多自动化的任务,并且可以充分利用Office其它组件的功能。

2.VBA能做什么?

知道了VBA是什么东东后,那么它能干什么呢?确定的说,VBA基本能做一切Excel能做的事,比如打印,生成报表,分析数据,生成图表等,这是VBA最大的优点。不需要额外实现这些标准的功能,只需要简单的调用就可以了,Excel已经做好了一切准备。除了这个好处,VBA其实还能处理很多的任务:

? 自定义Excel的外观,菜单,工具栏等。

重复执行自动化操作。

操作文件和文件夹

访问数据库并执行相关操作

访问网络

操作XML

获取系统信息

操作和自动化Office其它组件(支持VBA的其他公司的产品也可

以操作) ? ? ? ? ? ? ?

除了上述的任务外,VBA还有很多其它的功能有待发掘。

3. VBA与Macro

Macro是一组Excel能理解并执行的命令集合。借助宏录制器,我们能得到这些宏命令翻译后的VBA代码。这是最简洁获得VBA代码的方式,也是VBA开发最主要的模式。

4. VBA小结

VBA的语法很简单,这里就不再详述了。我个人学习新语言的习惯都是,先了解一下这个语言出现的背景,然后了解一下语言改进的地方,最后是实践一下基本的语法,研究语言运行的机制和部署情况。经过这个步骤以后,我就做几个实际小例子巩固巩固。我学习VBA的小结如下:

? Module是VBA组织代码的最小单元。

VBA是不分大小写的,所以更要养成良好的编程习惯。

代码可以一行写多句,用":"隔开,也可以一句写在多行,行末

用"_"标识。

Module成员的访问限定: ? ? ?

Public: 当前程序中的所有模块都可以访问该成员,如果方法默认不加限定符的话,当Public处理;Public成员只能在Module中定义。

Dim/Private:只有本Module内部的所有方法才能访问这些成员。当然方法是不能用Dim定义的。

Friend:只能用于对象模块或者窗体模块,作用范围是当前程序中的其他对象模块可以访问该成员。

? Const定义恒定变量的时候,只能在Module中定义,不能在方

法内定义;前面可以加Public/Private限定。

有一点比较恶心,对象赋值用"Set...=",其余的一切赋值用"=",

包括对象的属性赋值。 ?

? 可以使用Type在模块级别中定义包含一个或多个元素的用户自定义

的数据类型。

? 根据使用情况(比如需要的存储大小)选用合适的变量类型,一般

都应该明确定义变量类型,不要使用默认的Variant类型。

当需要使用变长集合的时候,可以考虑使用动态数组(使用ReD

im和Preserve)。

Nothing、Empty与Null的比较: ? ?

Nothing:这是一个指向空对象的对象引用。将对象引用设置为Nothing,就释放了那个对象。如果没有其他的引用指向对象,VB/VBA就将销毁这个对象。可以使用“Obj is Nothing”的方式检查。

Empty:这是一个象Integer或者String一样的变量类型,它表示了一个还没有进行初始化的变量。它与Null的意义不同,Null表示没有合法数据。例如数组,集合刚定义,还没有赋值之前就是这个状态,可以使用内置方法IsEmpty检查。

Null:这是一个象Integer或者String一样的变量类型,它表示一个没有合法数据的变量。这有别于zero、Nothing、Empty或者vbNullString。Null参与的运算,都将产生Null结果。可以用内置方法IsNull检查。

? 使用"For Each"语句枚举集合成员。

使用"For"语句执行固定次数的循环。

使用"Do While/Until...Loop"或者"While...Wend"语句执行不定次数的循环。

使用"If"语句执行2分支的选择。

使用"Switch Case"语句执行n分支的选择。

使用"With"语句减少重复对象的书写。

在Module开始的时候,加上"Option Explicit"可以强制变量使用前必须声明。

类型定义的简短写法:例如定义整形,可简写为:Dim i% Integer %

Long &

Single !

Double #

Currency @

String $

String*size $ ? ? ? ? ? ? ?

? 方法调用可以加括号,也可以不加括号;如果要是加括号,特别

是含有多个参数的时候,则前面需要加上"Call"。

方法是支持可选参数的,参数前用"Optional"标识并用"="提供默认值。可选参数用"参数名:=值"的方式传值特别方便。 ?

? 连接多个变量时,尽量使用强制连接符"&",少使用混和连接符"

+"。

? 在合适的时候,尽量多使用位操作(XOR,OR,AND,NOT)等完成

多个Boolean类型的相关判断与操作,而不是直接使用"IF"判断。

? 最重要的两点:当你不知道如何下手的时候,请尝试录一个宏

看看;批判吸收多个人的知识,并不是所有写出来的都是对的,实践是检验真理的唯一标准。


第二篇:12-Excel VBA 学习总结 - 代码优化之道


Excel VBA 学习总结 - 代码优化之道

 每个问题都可以用不同的解决方案解决,不同的方案执行的效率却是不同的。同样一个问题,不同的程序执行的时间可能相差数十,甚至数百倍。所以学习一门语言,必须要了解其优化方法。下面从几个方面总结一下VBA中的代码优化之道。
一、运行环境的优化
  VBA是需要运行在运行环境中的,运行环境直接影响了VBA程序的执行效率,所以第一个方面,我们从干扰程序执行的因素,讨论运行环境的优化。
  若要提高VBA程序的性能,明确禁用代码执行时不需要的功能是极其有效的优化方法。通常,只需在代码运行后重新计算或重绘一次,这样做可以提高性能。代码执行后,将功能恢复到其原始状态即可。
1.关闭屏幕更新
  关闭屏幕更新是提高VBA程序运行速度的很有效的方法,能大幅缩短运行时间。原因很简单,后台的操作不需要反映到屏幕上了,当然就省去了很多的操作,所以可以节省很多时间。当然了,这个操作是可以控制粒度的,比如每次VBA程序的开始于结束可以设置屏幕更新,也可以在每个循环的开始与结束时设置,这个通常取决于用户的需要。

'关闭屏幕更新的方法:
Application.ScreenUpdate = False
'程序执行过程
'...
'请不要忘记VBA程序运行结束时再将该值设回来
Application.ScreenUpdate = True 

2.关闭自动计算
  函数的自动计算对Excel运行影响很大,尤其是有大量数组函数和易失性函数时,影响更为明显。这个方面优化的最简单的方法就是关闭自动重算,启用手动重算。通过减少重算量提高Excel速度。可以在进入主程序运行前,将计算模式设置为手动。Calculation 属性是对所有工作簿进行的设置,您也可以用工作表的EnableCalculation属性来设置对某个工作表是否进行重新计算。

'设为手动计算
Application.Calculation = xlCalculationManual
'程序执行过程
'...
'恢复为自动计算
Application.Calculation = xlCalculationAutomatic

3.禁用事件
  禁用事件可以避免事件触发时的连锁反应。例如在工作表的Change事件中,一个单元格的值改变影响两个以上的单元格值改变,因为事件的连续触发可以造成CPU耗尽。

'可以在Change事件中禁用事件
Application.EnableEvents = False
'程序执行过程
'...
'请不要忘记VBA程序运行结束时再将该值恢复
Application.EnableEvents = True

4.禁用状态栏
  状态栏设置与屏幕更新设置是分开的,这样即使屏幕不更新,您仍可以显示当前操作的状态。但是,如果您不需要显示每个操作的状态,则在代码运行时禁用状态栏也可以提高性能。

'不显示状态栏
Application.DisplayStatusBar=False,
'程序执行过程
'...
'恢复显示状态栏
Application.DisplayStatusBar=False,

5.禁用分页符
  如果 ActiveSheet.DisplayPageBreaks 设置为False,则 Excel 不显示分页符。代码运行时不需要重新计算分页符,在代码执行后计算分页符可以提高性能。
6.避免在频繁的事件中写代码

  这个道理很简单,例如频繁的Activate事件。


二、算法的优化
  算法代表解决问题的步骤,它直接影响了程序的执行效率,所以算法优化基本是所有语言优化代码最主要的过程;这是一个不断试验,不断总结,不断优化的过程。这个不是这里的重点,所以只是简单分享一下我知道的方式。
深刻挖掘和应用数学模型的特性
基本上都是缩小问题的规模,递推总结出数学模型的规律,然后用程序实现就可以了。例如下面的经典问题:
上台阶问题:http://www.cnblogs.com/flowerszhong/archive/2011/09/14/2176374.html。

如果空间允许的话,可以拿空间换时间
常见空间换时间算法:http://bbs.pfan.cn/post-227818.html

保存可以利用的中间结果
动态规划中用的最多了:http://www.cs.pitt.edu/~ztliu/wordpress/2011/04/algo-dynamic-programming/

采用合适的排序算法
海量数据查找:http://blog.csdn.net/lanphaday/article/details/3547776
常见排序算法:http://blog.csdn.net/ctang/article/details/37914

经常查询的集合数据,先排序
通常对于不怎么变化,但是又经常查询的数据,先排序是非常合算的,下面这个介绍了最快排序与最快搜索:http://blog.csdn.net/shendl/article/details/4053853


三、实现方式的优化
  算法确定以后,就是使用具体的代码实现算法,而对于同样的算法,使用不同的函数去完成,也会有不小的差异,这方面其实基本都是从减少内存使用量,加速编译器的执行的速度这两个方面优化代码。
1、合理使用变量与常量

(1)始终声明和使用大小合适的变量类型,这个原因很明显,可以节省内存,加速运行速度。
(2)除非确实需要,应避免使用浮点数据类型。尽管Currency数据类型更大,但它比 Single 数据类型快,因为Currency数据类型不使用浮点处理器。
(3)如果在一个过程中多次引用一个对象,可以创建对象变量,并将对给对象的引用指派给它。因为对象变量存储对象在内存中的位置,VBA将不必再次查找其位置。
(4)尽可能使用早期绑定,这样不仅方便编码,更方便编译器查找成员。
  绑定是指将程序调用与实际代码相匹配。为了实现早期绑定,先应创建对对象库的引用(这个我们在前面的COM对象使用中见得太多了)。早期绑定可以在代码中使用定义在对象库中的常量,可以自动列出对象的方法和属性。但早期绑定只有在所控制的对象拥有独立的类型库或对象库文件才适用且还需要已安装了特定的库。而后期绑定则只是在运行时才知道对象的类型并对对象进行引用,因此不具备上述特点。
  使用早期绑定创建对象通常更有效率,使代码能获得更好的性能。因为对象的早期绑定引用在编译时可以通过VBE的解析,而不是通过运行时模块解析,因此早期绑定的性能要好得多。虽然在程序设计时不可能总是使用早期绑定,但应该尽可能使用它。
(5)多次使用的数值尽量定义成常量,易于修改,易于查找。
(6)减少变量的作用范围并及时释放变量(特别是对象实例,对于Recordset的使用,我们已经见过多次了)

Dim AnObj As New AnyObject 
'使用对象...
Set AnObj=Nothing ‘释放对象变量 

2、尽量使用VBA内置函数与工作表函数
  充分利用VBA内置函数与WorksheetFunction中的函数是提高程序运行速度的极度有效的方法。

如求平均工资的例子: 

 For Each c In Worksheet(1).Range(″A1:A1000″)
  TotalValue = TotalValue + c.Value
 Next
 AverageValue = TotalValue / Worksheet(1).Range(″A1:A1000″).Rows.Count

而下面代码程序比上面例子快得多:

AverageValue=Application.WorksheetFunction.Average(Worksheets(1).Range(″A1:A1000″))

其它函数如Count,Counta,Countif,Match,Lookup等等,都能代替相同功能的VBA程序代码,提高程序的运行速度。

3、尽量使用Range对象的SpecialCellsAutoFillFormula等方式,替换循环单元格的做法
例如快速填充空行:

Sub Fill()
  Selection.SpecialCells(xlCellTypeBlanks) = "=r[-1]c"
End Sub

4、尽可能使用For Each…Next循环集合
  可以使用For Each…Next循环来保证程序代码更快地执行。在使用For Each…Next循环时,对于存储在集合或数组中的每个对象执行一组语句,程序更简洁,也更容易阅读、调试和维护。当For Each…Next语句迭代集合时,自动指定一个对集合当前成员的引用,然后在到达集合的尾部时跳出循环语句。

5、尽可能在执行循环时节省资源
(1)把与循环无关的操作拿出去。例如,是否可以在循环外(而不是在循环中)设置某些变量?每次都通过循环执行的转换过程是否可以在循环之外执行?
(2)考虑尽早退出循环。例如,假设正在对一个不应该包含数字字符的字符串进行数据验证。如果循环要检查字符串中的每个字符以确定其中是否包含数字字符,那么您可以在找到第一个数字字符时立即退出循环。
(3)如果必须在循环中引用数组的元素,可以创建一个临时变量存储该元素的值,而不是引用数组中的值。从数组中检索值比从相同类型的变量读取值要慢的多。
(4)有可能的话,减少循环的步长,也就是减少循环的次数。
  当使用有针对性的For循环,即仅仅需要对循环对象中的部分对象进行操作时,应该调整循环的步长来减少循环的次数。
对比下面两个循环:

For i = 1 To 10000
    If i Mod 2 = 1 Then Cells(i, 1).EntireRow.Interior.ColorIndex = 23
  Next i

For i = 1 To 10000 Step 2
     Cells(i, 1).EntireRow.Interior.ColorIndex = 23
Next i

实现同样的功能,但却循环的次数有差异,明显是第二个循环效率更高。

6、一次性完成赋值与粘贴
  在使用Copy方法时,可以在一个语句中指定复制的内容及要复制到的目的地。
例如:

Range("B5:C6").Select 
Selection.Copy 
Range("B8").Select 
ActiveSheet.Paste 

经修改后的最佳代码是:

Range("B5:C6").Copy Destination:=Range("B8") 

7、选用合适的操作符,加速对数字的运算
(1)当对整数进行除法时,您可以使用整型除法运算符(\)而不是浮点除法运算符(/),因为无论参与除法运算的数值类型如何,浮点除法运算符总会返回Double类型的值。
(2)在任何具有整数值的算术表达式中使用Single或Double值时,整数均将被转换成Single或Double值,最后的结果将是Single或Double值。如果要对作为算术运算结果的数字执行多次操作,可能需要明确地将该数字转换为较小的数据类型。

8、提高字符串操作的性能
(1)尽可能少使用连接操作。

  连接操作符很多时候可以使用Replace,Mid函数代替。例如,可以在等号左边使用Mid函数替换字符串中的字符,而不是将它们连接在一起。注意,使用Mid 函数的缺点是替换字符串必须与要替换的子字符串的长度相同。

Dim strText As String 
strText = "this is a test" 
Mid(strText, 11, 4) = "tent" 

(2)VBA提供许多可用来替换函数调用的内部字符串常量。例如,可以使用vbCrLf常量来表示字符串中的回车/换行组合,而不是使用Chr(13) & Chr(10)。
(3)字符串比较操作的执行速度很慢。
  在VBA 中,可以使用Chr$()函数把数转换成字符,并确定ANSI的值,也可以使用Asc()函数把字符串转换成数值,然后确定它的ANSI值。如果需要进行有限次数的这种检验,对程序代码的效率可能不会产生很大影响,但是,如果需要在多个循环内进行这种检验时,这将节省处理时间并且有助于程序代码更快地执行。 例如,下列代码会检查字符串中的第一个字符是否为空格:

If Asc(strText) = 32 Then 

上面的代码会比以下代码更快:

If Left(strText, 1) = " " Then 

 (4)、使用Len()检验空串
  尽管有多种方法可检验空串,但首选的是使用Len()函数。为了测试零长度的串,可以选择把串与””相比较,或者比较串的长度是否为0,但这些方法比用Len()函数要用更多的执行时间。当对字符串应用Len()函数并且函数返回0值时,说明该字符串是空的或者是零长度的字符串。 并且,因为在If语句内非零值被认为是True,所以直接使用Len()函数而不必与””或0比较,减少了处理时间,因此执行更快。
(5)、善用带$的字符串处理函数
  在VBA中,有两套字符串处理函数,包含带"$"和不带"$"的函数,例如mid 和mid$,Left 和Left$,Right 和Right$。如果不使用带"$"符号的函数计算字符串,那么VBA将字符串作为Variant类型来进行计算,而使用带"$"的函数时,则将字符串当作string类型来进行计算,显示Variant型数据在计算时需要更多的内存空间。
如下面两句代码:

Str=mid("Wise",2)
Str=mid$("Wise",2)

第二句在执行效率上会占优势。

9、只要有可能就使用集合索引值
  我们能在集合中使用名称或者数字来指定某个单一的对象,但使用对象的索引值通常是更快的。如果您使用对象的名字,VBA必须解析名字成为索引值;但如果您使用索引值,就能避免这个额外的步骤。
  但另一方面,我们要注意到在集合中通过名称指定对象有很多优点。使用对象名称能使您的代码更容易阅读和调试。此外,通过名称指定一个对象比通过索引值更安全,因为当您的代码运行时该对象的索引值可能变化。例如,某菜单的索引值表示它在菜单栏中的位置,但是如果在菜单栏中添加了菜单或者删除了菜单,该菜单的索引值会变化。这样,您就不应该考虑代码的速度,而应保证代码运行可靠。您使用索引值加快代码速度之前,应该确保该索引值在代码运行过程中或使用应用程序时不会改变。

分享一个代码优化的经典合集:http://club.excelhome.net/thread-509998-1-1.html


四、代码规范的优化
  优化了算法,采用了合适的函数和对象实现了算法后,代码其实还是有优化的空间,比如编程习惯,代码风格等,下面从这些方面总结一下。
1、尽量减少无用的操作,如对象的激活和选择
事实上大多数情况下激活和选择操作都只是有一点视觉效果,但很遗憾这对于VBA来说不是必需的。例如:

Sheets(″Sheet3″).Select
Range(″A1″).Value = 100
Range(″A2″).Value = 200

可改为:

With Sheets(″Sheet3″)
 .Range(″A1″).Value = 100
 .Range(″A2″).Value = 200
End With 

2、尽量减少使用对象引用,即减少“.”的使用,尤其在循环中
每一个Excel对象的属性、方法的调用都需要通过OLE接口的一个或多个调用,这些OLE调用都是需要时间的,减少使用对象引用能加快VBA代码的运行。例如
(1)使用With语句。

Workbooks(1).Sheets(1).Range(″A1:A1000″).Font.Name=″Pay″
Workbooks(1).Sheets(1).Range(″A1:A1000″).Font.FontStyle=″Bold″

则以下语句比上面的快:

With Workbooks(1).Sheets(1).Range(″A1:A1000″).Font
   .Name = ″Pay″
   .FontStyle = ″Bold″
End With 

(2)使用对象变量。
  如果你发现一个对象引用被多次使用,则你可以将此对象用Set 设置为对象变量,以减少对对象的访问。如:

Workbooks(1).Sheets(1).Range(″A1″).Value = 100
Workbooks(1).Sheets(1).Range(″A2″).Value = 200

则以下代码比上面的要快:

Set MySheet = Workbooks(1).Sheets(1)
MySheet.Range(″A1″).Value = 100
MySheet.Range(″A2″).Value = 200 

(3)在循环中要尽量减少对象的访问。

For k = 1 To 1000
 Sheets(″Sheet1″).Select
 Cells(k,1).Value = Cells(1,1).Value
Next k

则以下代码比上面的要快:

Set TheValue = Cells(1,1).Value
Sheets(″Sheet1″).Select
For k = 1 To 1000
 Cells(k,1).Value = TheValue
Next k 

3、有效地使用数组与变量,尽量少使用单元格直接参与计算

  通常单元格的操作都比较慢,可以先将单元格的值读入变量或数组变量,对变量进行运算,这样可以提高处理的速度。处理结束以后,只要用一个语句就可以将数组中的数据传递回单元格区域中。
  在创建已知元素的确定数组时,使用Array函数对于节约空间和时间以及写出更具效率的代码是非常理想的。例如:

Dim Names As Variant 
Names=Array(“Fan”,“Yang”,“Wu”,“Shen”) 

  此外,应该尽量使用固定大小的数组。如果确实选择使用了动态数组,应该避免数组每增加一个元素就改变一次数组的大小,最好是每次增加一定数量的元素。

下面是一些扩展读物,有兴趣的同学可以试试看:

更多相关推荐:
Excel学习总结

Excel学习总结Excel把电子表格文档称为工作薄,其扩展名为.xls。一个新建的工作薄有三张工作表(Sheet1、Sheet2、Sheet3)最多可有255个工作表。工作表用来存储和处理数据,一个工作表中有…

EXCEL学习总结

Excel20xx基础1、常用工具栏的显示。视图-----工具栏-----自定义。数据操作1、删除多个单元格中的内容,选中内容按,清除内容即可。2、快速录入数据,先用鼠标选中待录入数字的范围,(这里不用定位就可…

excel学习心得

学习心得:通过这门课程的学习,我首先充分认识到了excel在我们以后工作中的重要性,能够熟练的掌握excel软件是我以后从事教学工作不可缺少的一种专业技能。人们可以excel利用它方便地记录和分析数据,编辑数学…

excel学习总结

Excel学习总结1在数值与文本之间的相互转换a将文本转化为数值格式在excel中写一个数值1然后复制选中excel中需要转化的文本选择性粘贴选乘m确定即可b将数值转化为文本数值最多为15位身份证号要用文本形式...

学习excel的一些心得体会

学习excel的一些心得体会——写给EXCEL刚入门或者即将入门的同学(高手可以飘过)本人从事电商数据分析的工作,在工作中用得最多的软件当属Excel了,从数据的收集开始,经历数据的整理,数据的计算,数据的汇总…

excel学习小结

在excel表格中冻结了横标题就只能取消再使用了怎样使表格向上滚动可以看到最上面的标题而左右移动的时候也能看到最左边的信息呢答选择需要冻结的行下面一行需要冻结的列的右面一列的那个单元格然后选择冻结窗口比如你要第...

excel学习感想

Excel在教学与管理工作中的应用课程的学习即将结束通过这一阶段的学习我有一下几点收获一网上教学这种学习方式很有新意节省了时间又能充分学习提高了自学的能力同时还可以与教师通过网络互动达到了很好的教学效果二通过课...

word excel 操作方法学习

Word操作大全1在WORD文档中锁定部分编辑区域12制表位13WORD目录的制作2EXCEL同时进行多个单元格的运算2PPT全程背景音乐设置办法如下以POWERPOINT20xx为例3POWERPOINT自动...

excel实用技巧(学习心得,非常实用)

Excel实用技巧这是本人学习EXCEL函数时积累的学习心得和EXCEL的一些技巧以函数为主非常实用对学习EXCEL很有帮助1sum求和可以是不连续的多个区域它可以用来求和中间用英文逗号分隔开也可以用来作多条件...

Excel 学习心得

Excel学习心得1保护单元格1ctrla全选整个表格2菜单格式单元格在弹出的对话框中选quot保护quot选项卡取消其中的quot锁定quot勾选确定3菜单编辑定位定位条件公式4菜单格式单元格在弹出的对话框中...

excel实训报告

实训报告课程:EXCEL专业:营销与策划班级:S2010-4学号:39学生姓名:指导教师:20××年6月Excel实训报告一、实训目的:学习Excel在财务管理中怎样运用?学会做财务报表,掌握使用技巧,熟练Ex…

Excel实训报告

EXCEL实训报告课程专业班级学号学生姓名指导教师Excel营销与策划S20xx202何雨张拥华20xx年5月Excel实训报告一实训目的通过这几节课的练习让我们在了解EXCEL的基础功能上学会运用各种公式对数...

excel学习总结(38篇)