读者可能注意到,本书已经多次用到“可读性”或“便于阅读”等字样,反复强调要把代码写得清晰、易读。事实上,代码是否清晰、是否便于阅读,完全不影响计算机对它的理解,也不会对程序运行结果产生任何影响。那么为什么我们还是如此重视代码的可读性呢?简单来说,是因为 世界上没有不需要修改的程序!
由于编写程序时可能存在错误,或者由于用户的需求发生变化,经常要把自己或别人写好的程序找出来,仔细阅读以便找到需要完善的地方。然而实践证明,对于大多数人来说,哪怕是自己亲手编写的程序,过一段时间以后也会忘记当时的编写思路。假如这段代码中存在一些不容易被发现的错误,想把它找出来更是难上加难。所以软件工程领域最佳实践之一,就是要求开发者必须按照规范的格式和清晰的结构书写代码,并为其编写注释甚至说明文档,以备将来自己或其他人阅读代码之用。
不过相对于职业的软件开发人员来说,我们使用VBA主要是编写一些短小的日常办公程序,无论规模还是复杂度都远远低于商品化软件。所以一般情况下,VBA程序代码的规范性要求也没有那么高,只需要注意“缩进”与“注释”就可以满足大多数日常办公程序的要求。
所谓“缩进”,就是让程序中某些行的起始位置,相对于其他行更加靠右。比如下面的两段程序,左边代码所有行的起始位置都相同,而右边代码则各有缩进。比较这两段代码可以感受到,右边的代码逻辑结构看起来更加清晰,而其原因就在于对“缩进”的合理使用。
之所以可以用缩进让代码的逻辑更加清晰,是因为可以用缩进直观地表现出各行代码之间的包含关系。在VBA中,有一些语句结构都是由成对的关键词组成的。比如“For”与“Next”、“Sub”与“End Sub”,以及接下来要介绍的“If”与“End If”等。在程序中,所有位于这些成对关键词之间的代码,逻辑上都属于这个语句结构。比如在For和Next之间的所有代码,都是For循环的循环体,它们何时运行、运行多少次,都由所处的 For 循环来控制。如果在书写代码时能够让这些语句都比For和Next缩进一层,就会让人直观地看到它们都属于这个For循环。
同样,所有处于Sub和End Sub之间的代码也属于这个宏。它们何时运行、运行多少次也都由这个宏来统一决定。所以这些代码也应该相对于Sub和End Sub缩进一层,以示其从属关系。
而对于那些没有成对关键字的语句结构,比如上例中Dim所在的行或Points=0所在的行,就无法包含其他代码。因此它们之间不存在从属关系,也就不需要互相缩进。同样,Sub 与End Sub这两个词,以及For与Next两个词之间也互不从属,因为它们一个用于标明该结构的起始,另一个用于标明该结构的结束,地位完全平等,因而End Sub应该与Sub对齐,Next则与For对齐。
所以,代码缩进的原则可以总结为以下两点。
① 如果一个语句结构是由成对关键字构成的,二者分别代表该结构的起始行和结束行,那么二者之间的所有行都要相对于它们缩进一层。
② 如果一个语句不存在成对关键字,则不需要让后面的语句相对于它缩进。
要想在代码中实现缩进,可以连续输入多个空格,比如连续输入四个空格代表一层缩进。不过更好的方法是使用“Tab”键。“Tab”键英文全称为Tabulator,常被翻译为“制表符”,每按一下“Tab”键,光标就会自动向右移动若干位。读者可以根据自己的习惯,在VBE中指定每次按“Tab”键后光标移动几位。具体方法是在VBE的“工具”菜单中选择“选项”命令,并在弹出的“选项”对话框的“Tab宽度”文本框中修改数值即可,如图3.10所示。如果读者需要修改VBE的字号和颜色,也可以在这个对话框中实现,单击“编辑器格式”选项卡,设置相应格式即可。
图3.10 “选项”对话框
此外,在程序中适当加入一些空行,也会使代码格式变得清晰很多。比如下面左边所示的代码非常紧凑,没有空行,阅读起来比较吃力。而右边的代码则在不同功能的语句块间插入了空行,这些功能包括:
① 将第一行的变量定义视作一个单独的功能;
② 将第二行的初始值设定视作一个单独的功能;
③ 将负责单元格扫描的For循环(共包含四行代码)看作一个功能;
④ 将最后两句负责输出结果的赋值语句看作一个功能。
由于不同功能之间用空行隔开,右边的代码结构更加符合逻辑,看上去清晰了很多。
毕竟 VBA 不是人类的自然语言,因此无论其书写得多么清晰,阅读起来都不会很轻松,特别是篇幅较长、逻辑复杂的程序,往往需要花费很长时间才能理解。
与其他编程语言一样,为了提高程序的可读性,VBA也允许在代码中使用人类自己的语言随时对某段代码进行注释。比如在下面的程序中,每行中单引号“ ' ”后面的内容都属于注释语句。
注释语句可以书写在程序的任何一行,其作用仅限于帮助阅读者理解代码含义,并不是可以执行的程序语句。当计算机执行VBA程序时,会自动忽略每行中单引号后面的文字,所以注释语句并不会影响程序的运行结果 。
显然,在适当的地方插入注释,可以大幅降低程序的理解难度。因此强烈建议读者养成在关键语句前写注释的习惯,虽然这样会增加一些工作量,但是考虑到未来频繁的阅读和修改需求,这些付出将是非常值得的。本书在后面的示例程序中也会经常使用注释语句,以便于大家理解代码。
除了单引号,VBA 语法中还有一个注释语句标识,即“REM”。REM 是英文“Remark”的缩写,也是Basic系列语言中最早使用的注释符号。不过由于REM只能写在行首,不能像单引号一样写在一行代码的中间位置(比如上面的示例代码中Points=0 一行的注释语句),所以在实际开发中很少使用。
小技巧 除了帮助理解,注释语句还常用来实现另一个有趣的功能:屏蔽语句。有时候我们发现程序无法正确运行,会怀疑是否是其中某条语句出了问题,于是想暂时删除这条语句试一试。不过删除某些语句并调试程序之后,往往需要将其恢复回来,这个过程却比较麻烦,甚至会因为疏忽导致无法恢复,只能重新编写代码。但是使用注释语句却很简单:当需要删除某条语句时,直接在该语句的最前面输入一个单引号,它就从可执行代码变成了注释语句,再运行程序时就会被计算机完全无视,形如删除。当需要把它恢复回来时,只需将单引号删除即可,既方便又安全。