VBA也是交互式图表实现的重要方法之一,借助VBA不但可以很方便地处理使用定义名称、筛选、数据透视表无法完成的图表制作困扰,同时还可实现某些特殊效果的交互图表。
交互辅助
图14.4-1 的交互式图表没有使用任何我们已经熟知的触发器,触发采用鼠标点选数据区域的方式进行,在该案例中数据以列的方式被绘制到图表中,实际的触发过程利用工作表的Worksheet_SelectionChange事件驱动Excel强制重算来完成。
图14.4-1 使用VBA工作表事件驱动的即点即显交互图表
这个图表的制作过程使用到了条件格式、定义名称和VBA,此处的条件格式是为了高亮显示用户鼠标选取的列,并未参与图表的数据交互。以下是详细制作方法:
1.选中原始数据区的C5:F16单元格区域,设置条件格式如图14.4-2所示。
图14.4-2 单元格数据区域
2.分别定义“ChartData”、“Item”两个定义名称,公式详见图14.4-1案例左下方。
3.选中原始数据区的B4:C16单元格区域,制作柱形图,并美化为图14.4-1案例右上角图表样式。
4.修改图表柱形系列的SERIES公式为图14.4-1案例右下方箭头所指样式。
5.按下键盘Alt+F11组合键启动VBE界面,在对应工作表宏代码编辑区,键入以下VBA代码段:
程序代码:14.4-1 工作表事件驱动公式重算
动态可视
汉斯·罗斯林(Hans Rosling)在著名的TED大会演讲人口和世界各国经济时,展示了一个非常有趣且强大的图表:运动图(Motion Chart),图14.4-3即是该类型图表的一个演绎案例。这个交互式图表展示了1959年至2006年间全球平均气温与二氧化碳含量、太阳黑子数3者间的关系,使用了12个复选框和1个滚动条工作表控件来分层展示数据,复选框控制显示月份,滚动条驱动图表显示当前年度。
图14.4-3 使用VBA驱动的运动图(Motion Chart)[数据来源:NASA.gov美国国家航空和航天管理局网站]
这个案例的制作过程,VBA只是响应自动展示的播放按钮,除此之外并未参与图表的其他交互过程,其他交互过程完全依赖定义名称和工作表控件的配合。以下是详细制作方法:
1.额外增加“月”和“年”两个辅助列,相应的函数公式见图14.4-4箭头所指。
图14.4-4 图14.4-3案例实现第一步数据整理
2.参照如图14.4-3图表右侧样式,依次添加12个复选框工作表控件,并分别指定其对应单元格链接为R5~R16的单个单元格。
3.添加如图14.4-3所示的滚动条工作表控件,设置如图14.4-5所示的对话框参数。
图14.4-5 图14.4-3案例滚动条设置
4.依次添加如下方所示的36个定义名称:
5.生成气泡图,添加12个图表系列,依次按顺序将自第5行数据的“月”数据指定给系列的名称;定义名称Xdata指定给系列的X值数据,定义名称Ydata指定给系列的Y值数据,定义名称Ydata指定给系列的气泡大小,定义名称的序号与系列序号一个个对应。美化为图14.4-3的图表样式,图表的SERIES公式类似于:
6.在单元格K27输入公式:,通过“=”与图表标题相关联,并美化为图14.4-3的图表右上角所示样式。
7.添加按钮工作表控件,并同下方的工作表VBA代码相关联。
程序代码:14.4-2 CommandButton1_Click播放按钮单击事件
注:该VBA程序中并未使用类似Application.Wait(Now+TimeValue(“0:00:01”))的代码,是因为使用Sleep函数更加流畅和自然。
这个案例的实现过程其实不算复杂,但36个定义名称的编辑和设定,以及图表赋值的过程,操作步骤虽然简单却没有效率。以下是针对这3个作业的VBA宏代码段,供读者参考:
程序代码:14.4-3 NameWrite 36个定义名称编写
程序代码:14.4-4 NameSet 36个定义名称设定
程序代码:14.4-5 ChartSeries图表系列与定义名称关联
动态区间
图14.4-6的案例常见于互联网中,尤其是股票数据的展示中常见,但遗憾的是在Excel中要直接实现这样的效果需要使用两个滚动条来实现,要达到同等效果需要相对复杂的VBA编程,且演示的效果非常不友好。为此笔者编写了一个区间滑块控件来实现该效果,同时最低限度地使用VBA编程来实现同样的效果。
图14.4-6 范围区域滚动条制作的股票图
该控件在使用前需进行RegSvr32注册,注册后即可在工作表中调用该窗体控件。需注意:该控件不支持打印和打印预览,否则控件将不可使用,需关闭后重新打开;Windows 7中注册需要使用管理员权限,注册后可能无法直接通过Excel的控件工具箱来调用;某些没有及时打上补丁的Excel 2007/2010版本不支持,在Excel 2003工作表中可直接使用,所有版本都可以打开运行对应版本的本节案例工作簿。以下是结合该控件的案例制作说明:
1.分别定义以下6个定义名称:
2.设置图14.4-6右侧S4~S9单元格的样式。
3.在窗体控件的[其他控件]中查找控件,并绘制到单元格中。Windows 7下若注册后,若找不到该控件,可在设计模式下复制粘贴本案例中的控件对象到你需要的工作簿中。在Excel2010中若出现:运行时错误’1004’,可鼠标点击[确定]后,以Excel2007和2010的新格式保存该文档,退出,再次打开,控件就被绘制到工作表中了。
4.选中该控件,在VBE工作表宏代码编辑区编写如下代码:
程序代码:14.4-5 ctlRangeSlider1_Scroll区间滑块的滑动事件
5.选中原始数据,制作股票图,并美化为案例图14.4-6的图表样式。
6.依次修改图表系列的SERIES公式如下:
7.选中图表,并设置图表图表区背景为无,然后选中I4:P5单元格区域,合并单元格并设置公式为:
注:该案例和其他交互式图表相同,坐标轴均使用固定刻度设定。
学习思考
不同版本的Excel ,视是否有及时更新补丁和Windows作业系统影响,在这个案例中的交互体验完全不同,有些版本来得顺滑,有些则会出现卡顿和闪屏。
图表事件
图14.4-7案例模仿自《经济学人》杂志网站,这个案例中使用到了热力数据地图,窗体控件为切换按钮,且利用了图表事件来参与交互式体验,使单击图表系列变为触发图表数据变化的触发器。
图14.4-7 模仿《经济学人》杂志网站制作的交互热力数据地图
由于图14.4-7案例右侧的条形图使用了排序模式,实现过程使用到了辅助数据区来进行数据的排序作业。以下是详细的制作说明:
1.将图表和原始数据所在工作表分离,原始数据放置到Chart Data工作表中,包括了GDP、人均GDP、人口、出口4个大类,依次对应地图上方的4个切换按钮,每个大类又有3个小项,分别和图表系列相关,如图14.4-8所示。
图14.4-8 图14.4-7案例的原始数据[数据来源自:《经济学人》杂志网站和网络]
2.参考案例11.4-1的实现过程,制作XY散点数据地图,地图数据放置在Map Data工作表中。
3.在图表右侧的AD4:AI38单元格区域中分别设置如图14.4-9所示的辅助数据列来进行对原始数据区数据的排序,各列单元格详细公式设置如图14.4-9箭头所指。
图14.4-9 图14.4-7案例的辅助数据区域设定
4.选中辅助数据AF4:AE38,在地图右侧制作条形图表,并美化图表为图14.4-7案例右侧的条形图样式。
5.定义“Chart2Data”、“MapXData”、“MapYData”3个的定义名称,公式依次如下:
6.选中条形图,添加新图表系列“辅助”,并修改图表系列的SERIES公式如下:
7.选中XY散点地图,添加新图表系列“辅助”,并修改图表系列的SERIES公式如下:
8.设置XY散点地图图表区和绘图区为透明样式,合并C6:I7单元格区域,并设置公式为:
9.分别合并C18:F18、C19:F19、C20:F20、C21:F21单元格区域,然后设置C18:F21单元格区域,如图14.4-7案例左下方红色方框的样式,并依次设置公式为:
10.分别设置AB5:AB9单元格区域的样式如图14.4-7案例最右侧单元格所示,在XY散点地图上方依次添加4个窗体切换按钮,并在设计模式下,依次修改Caption属性为“国民生产总值”、“人均国民生产总值”、“人口”、“出口”。最后在VBE的Test1工作表宏代码编辑区编写如下代码:
程序代码:14.4-6 Worksheet_Activate工作表激活事件
程序代码:14.4-7 ToggleButton1_Click 第1个切换按钮被按下
程序代码:14.4-8 ToggleButton2_Click 第2个切换按钮被按下
程序代码:14.4-9 ToggleButton3_Click 第3个切换按钮被按下
程序代码:14.4-10 ToggleButton4_Click 第4个切换按钮被按下
程序代码:14.4-11 XYChartUpdate 按钮切换时XY散点地图热力颜色更新
11.在VBE界面,新建一个类模块“Class1”,编写如下代码:
程序代码:14.4-12 Class1类模块代码
12.在VBE界面,新建一个模块“模块1”,编写如下代码:
程序代码:14.4-13 模块1的ClassClose 释放图表事件的关联
程序代码:14.4-14 模块1的ClassOpen 建立图表事件的关联
13.在VBE界面的ThisWorkBook工作簿打开和关闭事件中,编写如下代码:
程序代码:14.4-15 Workbook_BeforeClose 工作簿关闭事件
程序代码:14.4-16 Workbook_Open 工作簿打开事件
当Excel图表绘制在图表工作簿中时,可在VBE的图表工作表中直接调用编写Excel图表事件代码,若是图表嵌入在Excel的非图表工作表中,则必须以类模块的方法来调用这些事件,图14.4-7的实现就是使用类模块的一个案例。而这类事件在日常图表制作中使用相对较少,只有在较为复杂的交互式图表中才有可能使用到。以下是Excel支持的图表事件列表,如表14.4-10所示。
表14.4-10 Excel支持的图表事件
注:笔者确认SeriesChange事件在Excel 2007/2010中亦不适用,但在Excel 2007/2010的帮助文档中并未列出该事件不被支持。
小技巧
关于图表名称
涉及VBA编程的图表,一个好的建议是使用英文字母来命名。毕竟Excel底层基于英文,使用英文的兼容性强过汉字。修改图表的名称请使用选择对象按钮,然后鼠标选取图表,在公式编辑栏前的输入框中修改。
14.4-2文件夹下包含了笔者开发的RangeSlider.ocx控件,在使用该控件前请单击“注册RangeSlider.bat”批处理文件注册,卸载请使用“卸载RangeSlider.bat”批处理文件,Windows 7需管理员权限。本章案例目录的Next.ico和Pause.ico图标对应图14.4-3案例的播放按钮,其案例文档为14.4-1。