VBA 命名规则及代码规范
马维峰 ([email protected] )
一个好的命名规则可以提高程序的可读性,减少错误发生的概率,命名规则不是一定的,不同的人有不同的规则和习惯,但在编程过程中,对于个人或工作组,一定要遵守相同的命名规则。
表 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
过程和函数命名一般使用“名词 + 动词”的方式,首字母大写,也可以使用“动词 + 名词”方式,对于过程和函数的参数,命名方式见前,为了和局部变量区别,可以不使用表示参数变量类型的前缀。例如,我们可以命名如下的过程:
GetUserName(id as long) As String
模块使用类似过程的命名,用几个表示其用途的首字母大写的短语来表示,例如“ PlotChartTools ”;类模块增加前缀“ C ”,以与标准模块相区别,例如“ CIniTools ”、“ CEmployee ”等;用户窗体则以“ frm ”为前缀,如“ frmAbout ”、“ frmRegTools ”。这样,在代码中我们可以这样使用类模块:
Dim clsMyClass As CMyClass
Set clsMyClass = New CMyClass
类模块与其对象差别一目了然。由于 VBA 对于窗体可以使用缺省窗体,不需要创建实例,在代码中可以直接使用,因此,使用了与变量定义一样的前缀。例如:
frmRegTools.Show
VBA 工程一般使用与其文件名同名的名字,一方面,当打开几个工程的时候可以方便的区分工程,另一方面,在工程之间引用的时候,需要不同的名称。
代码规范表示了如何定义变量、过程、函数(见前),如何组织 代码,控制缩进,添加注释等内容。代码规范的目的在于产生一致的代码,提高代码的可读性,使其易于修改和交流。以下规范并非必须遵守,当使用规范破坏了代 码的可读性,那么就没有必要遵从代码规范了,这种情况需要自行判断。
缩进
一般来说,代码的缩进应该为 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 允许将多条语句放在一行,但不推荐这么做。
书写程序的同时,应该同时对关键代码,模块,过程增加注释,更改程序的同时,必须同时更改注释。必须时刻保证注释与程序代码一致,否则还不如不加注释。对于简短的注释,不需要加句号,否则应该增加句号,组成段落。
如果可能,建议尽量使用英文书写注释,因为这样会带来交流的便利,特别是在正式的开发中。
区块注释
区块注释通常描述其下的部分或全部代码,例如模块说明或者过程说明。其缩进要和它所描述的代码一致。模块的注释应该位于模块的所有代码之前, 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 ‘ 姓名
建议在模块注释中包括作者,修改时间,版本等信息,例如:
' 模块名称:气压计算模块
' 描述: …
' 作者: Mars
' 创建时间: 2004 年 4 月 23 日
' 修改时间: 2005 年 7 月 13 日
' 版本: 2.5
此类注释应该形成自己的风格,在所有的工程中保持一致。对于团队工作和正式开发,应该严格要求在模块注释中包括这些内容。
明确说明作用范围
在代码中,对于模块级的变量,过程,函数,应该总是使用“ Public ”、“ Private ”等关键字明确说明其范围。
使用有意义的名称
一定要使用有意义的名称,而不要使用简单的 A 、 B 、 C 之类的名称(循环变量约定俗成使用 i 、 j 等名称除外)。
明确参数和变量的数据类型
在定义过程参数的时候,一定要明确指定其数据类型和传递方式( ByRef 或者 ByVal ),这不仅仅是考虑效率,而是为了方便对这些过程的使用。对于变量定义,也应该养成明确说明其数据类型的习惯。
模块内的过程排序
模块内部的过程应该按照“ Public ”、“ Private ”的顺序排序,公有的过程在前,私有在后;然后再按照过程名称字母顺序排序。
使用常量和枚举
应该尽量使用常量和枚举,而不要在程序代码中使用数字(幻数)。
语句的选择
对于 True 、 False 的判断,使用 If 语句,对于多种可能的判断,使用 Select 语句。对于循环,对于确定循环次数的循环,使用 For 语句,对于不确定循环次数的循环,使用 Do While 语句,尽量对集合使用 For Each 语句。
Goto 语句
除了错误处理,不要使用 Goto 语句。