2.4 编辑宏
使用“宏录制器”创建的宏最终也将生成VBA语句,具有一定VBA或VB编程知识的用户可对这些代码进行修改。
2.4.1 分析宏代码
在Excel中录制的宏都是以VBA代码表示的,所有的宏都是以关键词“Sub”开始,以关键词“End Sub”结束的。其结构如下:
Sub 宏名称() ' 说明 VBA语句1 VBA语句2 …… End Sub
在关键词“Sub”之后的是宏的名称,宏名称后是一对小括号()。在“Sub”和“End Sub”之间是每次执行宏时的VBA语句,其中以半角单引号‘或’开头的是注释内容,VBA将忽略该语句。例如,本章前面录制的宏“设置表头格式”的代码如下:
Sub 设置表头格式() ' ' 设置表头格式 Macro ' ' 快捷键: Ctrl+h ' With Selection.Font .Name = "黑体" .Size = 16 .Strikethrough = False .Superscript = False .Subscript = False .OutlineFont = False .Shadow = False .Underline = xlUnderlineStyleNone .ThemeColor = xlThemeColorLight1 .TintAndShade = 0 .ThemeFont = xlThemeFontNone End With Selection.Font.Bold = True End Sub
从上面的代码可以看出,几乎每行代码中都包括句点,用来连接VBA语言中不同的要素。通常按从右向左的方向来阅读这些代码,例如下面的语句:
Selection.Font.Bold = True
该语句将所选单元格的字体设置为粗体。在宏代码中,有一段特别的代码块,这个代码块以“With”开始,以“End With”结束,这将加快宏代码的执行速度。有关“With…End With”详细用法的知识将在第11章中介绍。
2.4.2 清理宏代码
从上面的宏代码可以看出,按要求只需要设置所选单元格区域的字体、字号,并设置为粗体即可,但Excel录制宏时记录了其他有关字体设置的状态如删除线、阴影和下画线等。例如,以下的代码片断中加下画线的部分就是多余的代码:
With Selection.Font .Name = "黑体" .Size = 16 .Strikethrough = False .Superscript = False .Subscript = False .OutlineFont = False .Shadow = False .Underline = xlUnderlineStyleNone .ThemeColor = xlThemeColorLight1 .TintAndShade = 0 .ThemeFont = xlThemeFontNone End With
在使用宏录制器创建宏时,Excel总会生成这些多余的指令。删除这些多余的代码即可整理为以下形式:
With Selection.Font .Name = "黑体" .Size = 16 End With
经过整理的代码,不但简洁了不少,而且可以提高代码的执行速度。
另外,对于以下代码:
Selection.Font.Bold = True
也可将其添加到“With…End With”结构之中,变为以下形式:
With Selection.Font .Name = "黑体" .Size = 16 .Bold = True End With
经过清理后,“设置表头格式”宏的代码如下:
Sub 设置表头格式() ' ' 设置表头格式 Macro ' ' 快捷键: Ctrl+h ' With Selection.Font .Name = "黑体" .Size = 16 .Bold = True End With End Sub
该代码非常简洁,只保留了需要设置效果的三个语句。执行宏得到的效果与前面录制宏产生的一长串代码是一致的。
技巧:VBA的语言要素非常多,在本书后面将陆续介绍。作为初学者,通过录制宏,然后再对录制的宏代码进行编辑、优化,是学习VBA的一个高效方法。
2.4.3 编辑宏的步骤
录制宏后,可能会发现还需要宏再执行一个计划外的任务。如果用户已经熟悉VBA语言,可以非常容易地向宏代码中添加新的VBA语句,为宏增加新的功能。
有些情况下,可能还需要将两个宏所完成的功能合并到一起,执行一次命令就可将两个宏的功能完成。这时,可复制一个宏中需要的代码,然后将其粘贴到另一个宏代码的正确位置即可。例如,在前面的例子中只设置了表头的字体。下面再录制一个宏,设置表头的边框线,然后将两个宏合并。具体操作步骤如下。
步骤1 打开前面制作的实例文件。
步骤2 选中表头部分的单元格区域(其实选择任意单元格区域都行)。
步骤3 单击状态栏左侧的“录制宏”按钮,在打开的“录制新宏”对话框中,设置宏名为“设置边框线”,如图2-27所示。
图2-27 录制新宏
步骤4 在“录制新宏”对话框中单击“确定”按钮,开始录制宏。
步骤5 在“开始”功能区的“字体”组中,单击“边框”按钮打开边框下拉列表,选择“所有框线”,如图2-28所示。
图2-28 设置边框线
步骤6 单击状态栏左侧的“停止录制”按钮,结束宏的录制。
步骤7 按“Alt+F11”组合键进入VBE环境,可以看到新录制的“设置边框线”宏代码如下:
Sub 设置边框线() ' ' 设置边框线 宏 ' Selection.Borders(xlDiagonalDown).LineStyle = xlNone Selection.Borders(xlDiagonalUp).LineStyle = xlNone With Selection.Borders(xlEdgeLeft) .LineStyle = xlContinuous .ColorIndex = 0 .TintAndShade = 0 .Weight = xlThin End With With Selection.Borders(xlEdgeTop) .LineStyle = xlContinuous .ColorIndex = 0 .TintAndShade = 0 .Weight = xlThin End With With Selection.Borders(xlEdgeBottom) .LineStyle = xlContinuous .ColorIndex = 0 .TintAndShade = 0 .Weight = xlThin End With With Selection.Borders(xlEdgeRight) .LineStyle = xlContinuous .ColorIndex = 0 .TintAndShade = 0 .Weight = xlThin End With With Selection.Borders(xlInsideVertical) .LineStyle = xlContinuous .ColorIndex = 0 .TintAndShade = 0 .Weight = xlThin End With With Selection.Borders(xlInsideHorizontal) .LineStyle = xlContinuous .ColorIndex = 0 .TintAndShade = 0 .Weight = xlThin End With End Sub
注意:重新打开Excel工作表录制宏时,VBA将生成一个新的模块。本例的宏代码放在“模块2”中。
步骤8 将新录制的宏代码进行清理,得到如下代码:
Sub 设置边框线() ' ' 设置边框线 宏 ' ' Selection.Borders(xlDiagonalDown).LineStyle = xlNone Selection.Borders(xlDiagonalUp).LineStyle = xlNone With Selection .Borders(xlEdgeLeft).LineStyle = xlContinuous .Borders(xlEdgeTop).LineStyle = xlContinuous .Borders(xlEdgeBottom).LineStyle = xlContinuous .Borders(xlEdgeRight).LineStyle = xlContinuous End With End Sub
步骤9 类似地,将前面录制的“宏1”也进行清理,并将宏名改为“设置表头格式”,然后将上面整理的设置表格线的代码也复制到设置表头格式代码的下面,其代码如下所示:
Sub 设置表头格式() ' ' 设置表头格式 Macro ' ' 快捷键: Ctrl+h ' With Selection.Font .Name = "黑体" .Size = 16 . Bold = True End With Selection.Borders(xlDiagonalDown).LineStyle = xlNone Selection.Borders(xlDiagonalUp).LineStyle = xlNone With Selection .Borders(xlEdgeLeft).LineStyle = xlContinuous .Borders(xlEdgeTop).LineStyle = xlContinuous .Borders(xlEdgeBottom).LineStyle = xlContinuous .Borders(xlEdgeRight).LineStyle = xlContinuous End With End Sub
至此完成了两个宏代码的清理、合并工作,两个宏的功能被合并到一起了。