2.2 案例03:标记2020年所有周日
案例03要求先在工作表的一列中输入“2020年1月1日”至“2020年12月31日”,如图2-8所示,再用深色填充色将所有是周日的日期标记出来。

图2-8 2020年全年的日期
2.2.1 案例解析
如果使用键盘和鼠标,那么,首先需要找到2020年的第一个周日,也就是2020年1月5日,并将该日期的单元格的填充色改成深色,然后每隔6个单元格改一次填充色,重复操作,直至2020年所有的周日被标记。
既然本案例需要执行大量重复操作,那么可以考虑使用录制宏。在录制宏之前,先介绍绝对引用和相对引用的概念。
宏执行的操作一定会在录制时选中的单元格或区域中进行,这被称为 绝对引用 。例如,在绝对引用下,开始录制宏,然后选中A1单元格,改变其填充色,停止录制。在其他任意工作表上执行该宏,A1单元格都会被选中并改变填充色。
但是,绝对引用仅针对选中操作。如果录制过程中没有选中操作,那么绝对引用将不起作用。还是以改变单元格填充色为例,在录制开始前,首先选中某个单元格;然后,开始录制宏;接着,改变单元格填充色;最后,停止录制。在执行宏时,我们会发现,选中任意工作表的任意单元格都能改变其填充色。对于以上操作,建议读者亲自测试并验证,以加深理解。
录制宏的另一种引用方式为相对引用。 相对引用 是指宏记录的并非操作单元格或区域的具体位置,而是单元格或区域的位置变化。在Excel的“开发工具”标签中,“录制宏/停止录制”按钮的下方就是“使用相对引用”按钮,如图2-9所示。
针对案例03,我们可以分别使用绝对引用和相对引用录制宏,看看得到的宏有何区别。
先使用绝对引用。首先,选中2020年的第一个周日,也就是“2020年1月5日”所在的A5单元格,然后开始录制宏,改变A5单元格的填充色,接着选中下一个周日,也就是“2020年1月12日”所在的A12单元格,停止录制。

图2-9 “使用相对引用”按钮
执行得到的宏,其效果为改变当前选中单元格的填充色,然后选中A12单元格。很明显,使用绝对引用录制的宏无法满足案例03的要求。
再使用相对引用。在功能区的“开发工具”标签中选中“使用相对引用”按钮(选中后文字变为深色),然后选中A5单元格,开始录制宏,改变A5单元格的填充色,选中A12单元格,停止录制。重新选中A5单元格并执行宏,A5单元格的填充色被改变且A12单元格被选中;再次执行宏,A12单元格的填充色被改变且A19单元格被选中;第三次执行宏,A19单元格的填充色被改变且A26单元格被选中……如图2-10所示。

图2-10 使用相对引用录制的宏可改变当前单元格的填充色并下移7个单元格
由此可知,本案例中使用相对引用录制的宏可以改变当前选中单元格的填充色,并将光标下移7个单元格。因此,只要选中A5单元格(2020年的第一个周日),并将该宏执行足够多次数,就能将2020年所有的周日标记出来。
但是,将所有周日都标记出来,需要将宏执行50次以上,工作量依然很大。为了提高工作效率,可将录制的宏代码嵌入For循环,以此来代替手动执行宏。打开Visual Basic编辑器,在模块中找到使用相对引用录制的宏代码,如图2-11所示。

图2-11 使用相对引用录制的宏代码
为了便于区分和修改,建议重新创建一个过程,可将其命名为“标记”或其他符合VBA规则的过程名,并将图2-11中“宏1”过程的主体部分复制到该过程中,如图2-12所示。

图2-12 创建一个新的过程,并将录制得到的代码复制至其中
现在“标记”过程的执行效果为:修改当前选中单元格的填充色,然后使鼠标光标下移7个单元格。该执行效果与录制得到的“宏1”相同。
因为2020年一共有52个周日,所以需要将“标记”过程的主体部分嵌入For循环执行52次,那么计数变量的取值范围应设为1~52。For循环的代码详见代码清单2-2。
代码清单2-2
For i = 1 To 52
……
Next
小贴士: 编写VBA代码时,可不区分大小写,编辑器会根据需要自动转换,如将代码中的for自动转换为For,将next自动转换为Next。
虽然默认情况下Visual Basic编辑器不要求在代码中事先定义变量,但是为了增加代码的可读性,也为了避免错误,编写代码时应养成定义变量的好习惯。 定义变量 是指在使用变量前先声明其数据类型,而未被定义的变量,其数据类型是不确定的,因此,在使用时编辑器无法为其提供足够多的信息支持。
根据使用环境可知,For循环中的计数变量i的类型为整数型,因此,可在过程中增加一行代码,将变量i的数据类型定义为整数型:
Dim i As Integer
2.2.2 案例代码
将代码清单2-1和代码清单2-2整合到一起,即可得到“标记”过程的完整代码,如代码清单2-3所示。
代码清单2-3
Sub 标记()
Dim i As Integer
For i = 1 To 52
With Selection.Interior
.Pattern = xlSolid
.PatternColorIndex = xlAutomatic
.Color = 65535
.TintAndShade = 0
.PatternTintAndShade = 0
End With
ActiveCell.Offset(7, 0).Range("A1").Select
Next
End Sub
代码清单2-3的“标记”过程在Visual Basic编辑器中的显示详见图2-13。

图2-13 “标记”过程代码
切换至Excel程序,选中工作表的A5单元格(即2020年1月5日),然后在“宏”对话框中选中“标记”宏,并单击“执行”按钮,如图2-14所示。

图2-14 执行“标记”宏
执行“标记”宏后,工作表中2020年所有周日对应的日期均会被标记,如图2-15所示。

图2-15 所有周日对应的日期均被标记
注意,在执行“标记”宏之前,必须先选中A5单元格,再执行宏。
2.2.3 案例小结
本案例“复习”了录制宏和For循环,重点介绍了绝对引用和相对引用,以及如何对录制的宏代码进行修改。
本案例的“标记”宏还遗留了一个小问题,如果在执行宏之前没有正确选择起始单元格(A5单元格),执行结果就会出现错误。这个问题的解决方法将在后续章节中介绍。