理解了VBA程序的基本结构,我们接下来就仔细研究一下这个示例程序中的代码“Cells(2,3)=5”到底是什么意思。
想在VBA程序中读取或修改单元格的内容,就必须知道怎样使用VBA代码表示一个单元格。熟悉Excell公式的读者都知道,在表格公式中我们可以直接用单元格的地址(如C2)代表一个单元格的内容。但是VBA程序并不支持这种表示方法,而是提供了若干种方法在代码中表示Excell单元格,Cellllss属性就是其中之一(关于“属性”的概念,本书后面讲解Excell对象体系时会详细介绍)。
Cells属性的写法很容易理解:用两个数字分别表示该单元格所在的行号和列号,对应关系如图1.13所示。需要特别注意的是:这两个数字必须使用逗号(如前所述,必须使用半角符号,下同)隔开,并用一对圆括号将它们括起来,紧随在“Cells”的后面。
图1.13 使用Cells属性表示单元格
这种用括号把若干个数值包含起来的写法,在 VBA 程序中十分常见。一般情况下,括号中用逗号隔开的每个数值称作一个“参数”。在上面的例子中,我们可以说“Cells 属性需要指定两个参数,第一个参数代表行号,第二个参数代表列号”。关于参数的更多知识,在讲解子过程与函数时会深入介绍。
熟悉表格公式的读者,可能对这种完全使用数字表示单元格的方式有些不习惯。其实Cells的第二个参数也可以使用字母表示,比如上例也可以写成 Cells(2 ,“C”)=5,同样能够将C2单元格的内容设置为5(注意字母两边必须有双引号)。不过在实际开发中,使用数字定位单元格会更便利,因为数字通过简单的计算就可以得到,便于批量处理或快速定位。读者可以比较一下,“将C5单元格右边第47列涂成红色”与“将第5行第3列单元格右边第47列涂成红色”,哪一个处理起来更加简单。显然,第二种方法只要计算一下“3+47”,就能知道只需将 Cells(5 ,50)设置为红色即可。而使用第一种方法,则需要想办法计算出字母 C 后面第47列的名称——AX,才能处理这个单元格,过程相对复杂许多。
Cells属性如同一个连接VBA代码与Excel表格的桥梁,使我们能够用VBA表示任何一个单元格,接下来的问题就是怎样修改单元格中的内容。
所谓修改单元格中的内容,就是让单元格中的内容等于某个数值(或文字等)。因此,VBA程序就使用等号“=”来实现这个功能。比如Cells(2,3)=5这句代码,翻译为自然语言就是“让第2行第3列单元格的内容等于5”。
这种操作在VBA语言中被称为“赋值操作”,也就是将等号右边的值赋予等号左边的元素。当计算机执行到赋值操作的语句时,会首先计算等号右边的部分,得到一个确切的结果后再把这个结果赋值给等号左边的元素。比如对于 Cells(2,3)=5+3 这个语句,计算机会首先处理等号右边的“5+3”,待计算出最终结果“8”后,再将其赋值给等号左边的Cells属性,让C2单元格的内容变成“8”。
对于初学程序设计的读者来说,理解“赋值”的含义,以及赋值语句“先右后左”的执行过程十分重要。否则,如果将等号误解为“等式”的意思,会很容易对类似下面的代码感到困惑。
如果将等号理解为数学中的“等式”符号,那么“Cells(2,3)=Cells(2,3)+1”永远无法成立。但是在VBA程序中,等号是赋值的标识,所以根据前面的描述,计算机会先计算等号右边表达式的结果,也就是C2单元格当前数值与数字1的和。假如在运行程序前C2单元格的数值是5,那么等号右边的最终计算结果就是 5+1,也就是6。接下来,计算机会将等号右边的最终结果赋值给等号左边的元素,也就是将6赋给C2单元格,于是C2单元格的内容变为6,实现了“自动增一”的效果。
换言之,虽然等号左右两边的“Cells(2,3)”看上去完全相同,但其实计算机用到它们的时间及目的都是不同的。等号右边的Cells(2,3)会先被使用,从该单元格中读取当前数值以便计算最终结果;而等号左边的Cells(2,3)则要到最后才被使用,将该单元格内容修改为前述结果。
读者可以将这段代码输入VBE中,并运行这个程序(注意:在单击“运行”按钮前,先用鼠标单击Example内的任意位置),以观察C2单元格的变化——每运行一次Example,C2单元格的数字就会自动增加1。
Excel最常见的用途就是对各种数字进行计算汇总,同样,VBA程序中最常用到的语句也离不开算术运算。
在 VBA 中编写算术运算语句,与数学中列算式的方法几乎相同,无非就是加、减、乘、除各种符号的使用。只不过受电脑键盘设计的限制,有些符号的写法略有不同,如表1-1所示。
表1-1 VBA算术运算符
关于算术运算,以下几点需要初学者特别注意:
★ 所有运算符必须写成英文半角符号,误写为全角符号会导致计算机无法理解。
★ 当一个表达式中包含多个运算符时,VBA 程序的计算顺序同样遵循“先乘除后加减”的算术运算优先级。比如3+2*7的计算结果是17(先计算2乘以7,再加上3),而不是35(先计算3加2,再乘以7)。
★ 可以使用半角圆括号来改变计算优先级。比如(3+2)* 7 的计算结果就是35,而非17。但是与数学中的算术式不同,VBA中没有“大括号”“中括号”的概念。如果需要使用多层括号来改变优先级,所有括号都要写成半角圆括号,比如(3+(5 – 4)* 2)* 7。这一点与Excel公式的要求是一样的。
★ 有一些简单的算术运算语句无法正确执行。比如 Cells(3,2)=30000*5,看起来没有任何问题,可是单击“运行”按钮后却会报出错误,这是计算机内部对数据类型、数据精度等方面的限制所导致的。为降低初学门槛,本书将这部分内容放在后面相关章节中详细讲解。
★ 很多读者可能对模运算(Mod)比较陌生。事实上,在很多涉及“周期性变化”的应用场景中,使用模运算都能够非常巧妙地解决问题。本书安排了特定章节讲述模运算的使用技巧。
理解了算术运算的写法,读者可以在Excel工作簿中写一个小程序作为练习。练习的要求是:编写一个名为“Demo2”的VBA程序,每当执行它时,就会将C2单元格与C3单元格中的内容相加,并把结果写入C4单元格中。请读者先自己思考并编写运行该程序,然后参考图1.14所示的答案。