1. VBA命名规则
一个好的命名规则可以提高程序的可读性,减少错误发生的概率,命名规则不是一定的,不同的人有不同的规则和习惯,但在编程过程中,对于个人或工作组,一定要遵守相同的命名规则。
1.1. 变量、常量、自定义类型和枚举
表 1‑1概括了变量、常量的基本命名规则。
表 1‑1 变量、常量和枚举类型的命名规则
元素 |
命名规则 |
变量 |
<范围><数组><数据类型>描述(首字母大写) |
常量 |
<范围><数据类型>描述(全部大写) |
用户自定义类型 |
Type 描述名称 <数据类型>描述 End Type |
枚举类型 |
Enum <工程前缀>一般描述 <工程前缀><一般描述><具体名称1> <工程前缀><一般描述><具体名称2> End Enum |
<范围>表示了变量的作用域,对于Private类型和模块级变量,一般使用“m”前缀表示,对于Public类型的变量,一般使用“g”前缀表示,而对于过程内的局部变量,则不使用前缀。如果是数组,在范围前缀后增加“a”表示变量为数组。
对于数据类型,一般使用表 1‑2的前缀表示。
表 1‑2 命名规则常用前缀
前缀 |
数据类型 |
前缀 |
数据类型 |
前缀 |
数据类型 |
is |
Boolean |
cm |
ADODB.Command |
cmb |
MSForms.ComboBox |
byt |
Byte |
cn |
ADODB.Connection |
chk |
MSForms.CheckBox |
cur |
Currency |
rs |
ADODB.Recordset |
cmd |
MSForms.CommandButton |
dte |
Date |
|
|
fra |
MSForms.Frame |
dec |
Decimal |
cht |
Excel.Chart |
lbl |
MSForms.Label |
f |
Double,Single |
rng |
Excel.Range |
lst |
MSForms.ListBox |
i |
Integer,Long |
wb |
Excel.Workbook |
mpg |
MSForms.MultiPage |
obj |
Object |
ws |
Excel.Worksheet |
opt |
MSForms.OptionButton |
str |
String |
|
|
spn |
MSForms.SpinButton |
u |
User-defined type |
cbr |
Office.CommandBar |
txt |
MSForms.TextBox |
v |
Variant |
ctl |
Office.CommandBarControl |
ref |
RefEdit Control |
col |
VBA.Collection |
cls |
自定义类 |
frm |
用户窗体 |
变量的描述部分最好使用有意义的字符串,使用1-2个英文单词表示,首字母大写,例如“strUserName”、“iPeopleAge”。除了循环变量使用i、j,临时变量使用tmp之类的变量外,不要使用太短的命名,但也不要使用太长不易记忆的名称。
常量则一般使用全部大写的方式,以与变量区别。
对于枚举类型,整个工程一定要使用一致的规则,每个枚举常量都包含工程前缀,变量前缀和本身描述几部分,例如:
Private Enum schDayType
schDayTypeUnscheduled
schDayTypeProduction
schDayTypeDownTime
schDayTypeHoliday
End Enum
1.2. 过程和函数
过程和函数命名一般使用“名词 + 动词”的方式,首字母大写,也可以使用“动词 + 名词”方式,对于过程和函数的参数,命名方式见前,为了和局部变量区别,可以不使用表示参数变量类型的前缀。例如,我们可以命名如下的过程:
GetUserName(id as long) As String
1.3. 模块、类模块和用户窗体
模块使用类似过程的命名,用几个表示其用途的首字母大写的短语来表示,例如“PlotChartTools”;类模块增加前缀“C”,以与标准模块相区别,例如“CIniTools”、“CEmployee”等;用户窗体则以“frm”为前缀,如“frmAbout”、“frmRegTools”。这样,在代码中我们可以这样使用类模块:
Dim clsMyClass As CMyClass
Set clsMyClass = New CMyClass
类模块与其对象差别一目了然。由于VBA对于窗体可以使用缺省窗体,不需要创建实例,在代码中可以直接使用,因此,使用了与变量定义一样的前缀。例如:
frmRegTools.Show
1.4. VBA工程
VBA工程一般使用与其文件名同名的名字,一方面,当打开几个工程的时候可以方便的区分工程,另一方面,在工程之间引用的时候,需要不同的名称。
2. VBA代码规范
代码规范表示了如何定义变量、过程、函数(见前),如何组织代码,控制缩进,添加注释等内容。代码规范的目的在于产生一致的代码,提高代码的可读性,使其易于修改和交流。以下规范并非必须遵守,当使用规范破坏了代码的可读性,那么就没有必要遵从代码规范了,这种情况需要自行判断。
2.1. 代码的排版
缩进
一般来说,代码的缩进应该为4个空格,在VBA IDE中选中自动缩进,并设置为4个字符。一个过程的语句要比过程名称缩进4个空格,在循环,判断语句、With语句之后也要缩进。例如:
If strText = " " Then
NoZeroLengthString = Null
Else
NoZeroLengthString = strText
End If
行的长度
一行代码尽量不要过长,对于大多数编程规范,建议一行代码的最大长度为80个字符,在VBA中,可以使用续行赋“-”将长的代码行分为数行,后续行应该缩进以表示与前行的关系。例如:
AverageValue = TotalValue / _
Worksheet(1).Range(″A1:A1000″).Rows.Count
空行
一个模块内部,过程之间要使用空行隔开,模块的变量定义和过程之间也应该空1行。过程内部,变量定义和代码应该空1行。在一组操作和另一组操作之间也应该空1行显示其逻辑关系。空行可以很好的提高程序的可读性,但同时,空行没有必须遵守的规则,其使用的目的就是要显示程序的逻辑关系。
不要将多个语句放在同一行上
虽然VBA允许将多条语句放在一行,但不推荐这么做。
2.2. 注释
书写程序的同时,应该同时对关键代码,模块,过程增加注释,更改程序的同时,必须同时更改注释。必须时刻保证注释与程序代码一致,否则还不如不加注释。对于简短的注释,不需要加句号,否则应该增加句号,组成段落。
如果可能,建议尽量使用英文书写注释,因为这样会带来交流的便利,特别是在正式的开发中。
区块注释
区块注释通常描述其下的部分或全部代码,例如模块说明或者过程说明。其缩进要和它所描述的代码一致。模块的注释应该位于模块的所有代码之前,Option语句之后,过程的注释位于过程定义之后,并保证缩进一致。对于模块的注释,注释结束后应该有一空行,其前后可以加一些修饰以区别与其他注释,而过程注释则不需要。例如:
#001 Option Explicit
#002
#003 '***************************************************
#004 '主程序模块,提供按钮调用,对话框弹出等服务
#005 '***************************************************
#006
#007 Public Const strVer As String = "0.31"
#008
#009 Public Sub GeoDrawMain()
#010 '主程序模块,单击按钮后弹出
#011 frmMain.Show vbModal
#012 End Sub
行内注释
行内注释的形式是在语句的同一行中加注释,行内注释应该简单明了,并不要描述显而易见的事情。行内注释和语句至少应该有2个以上空格。可以在语句和注释之间使用多个Tab使注释对齐,例如:
Dim iAge As Long ‘年龄
Dim strName As String ‘姓名
2.3. 程序版本
建议在模块注释中包括作者,修改时间,版本等信息,例如:
' 模块名称:气压计算模块
' 描述:…
' 作者:Mars
' 创建时间:2004年4月23日
' 修改时间:2005年7月13日
' 版本:2.5
此类注释应该形成自己的风格,在所有的工程中保持一致。对于团队工作和正式开发,应该严格要求在模块注释中包括这些内容。
2.4. 一些基本原则
明确说明作用范围
在代码中,对于模块级的变量,过程,函数,应该总是使用“Public”、“Private”等关键字明确说明其范围。
使用有意义的名称
一定要使用有意义的名称,而不要使用简单的A、B、C之类的名称(循环变量约定俗成使用i、j等名称除外)。
明确参数和变量的数据类型
在定义过程参数的时候,一定要明确指定其数据类型和传递方式(ByRef或者ByVal),这不仅仅是考虑效率,而是为了方便对这些过程的使用。对于变量定义,也应该养成明确说明其数据类型的习惯。
模块内的过程排序
模块内部的过程应该按照“Public”、“Private”的顺序排序,公有的过程在前,私有在后;然后再按照过程名称字母顺序排序。
使用常量和枚举
应该尽量使用常量和枚举,而不要在程序代码中使用数字(幻数)。
语句的选择
对于True、False的判断,使用If语句,对于多种可能的判断,使用Select语句。对于循环,对于确定循环次数的循环,使用For语句,对于不确定循环次数的循环,使用Do While语句,尽量对集合使用For Each语句。
Goto语句
除了错误处理,不要使用Goto语句