【Excel VBA编程】组合图表个性化设计:簇状柱形图+折线图
- 2026-11-08 05:44:15
总是听到或看到有人问,编程好学吗?如何入门?多久能学会?它能做些什么?怎么写代码呀?执行过程中出问题了谁能帮帮我...如果你也有类似的问题那就赶快关注我的公众号,一起学起来吧!
手动制作图表,尤其是处理大量数据或需要定期更新的周报、月报时,过程极其耗时。由于需要反复调整图表格式、核对数据准确性,一个报表可能就要花上1小时甚至更久。经常与图表打交道的小伙伴一定会感同身受
而使用VBA可以将这些重复性劳动打包成一个宏,实现一键汇总数据、一键生成图表。而更核心的价值是用一次性的代码投入,换取持续性的应用
接下来,就通过一则案例来详细说明:如何通过VBA自动创建组合图形
1 实现需求
如下图所示,是一张指标完成情况表格及详细格式

为了对比目标和实际数据,B列及C列数据需要使用簇状柱形图 E列的完成率使用折线图表示,并且完成率大于等于100%的节点要用绿色圆点表示,反之使用红色圆点 折线图显示在图表的上半部分,簇状柱形图显示在图表的下半部分,并形成“上下分区布局”的视觉效果

2 代码及说明
2.1 操作步骤
打开你的.xlsm文档
按下 Alt + F11 快捷键,打开VBA编辑器
选择 “插入” -> “模块”,将文中全部代码复制粘贴到新模块中 回到Excel工作表界面,顺次选择【开发工具】【插入】【表单控件】,添加1个按钮并指定宏名“GenerateReportAndChart”,以此关联代码
以上操作完成后,即可点击工作表上的按钮来一键生成组合图表了
2.2 代码实现
使用VBA代码设计图表的建议:先创建后调整。以本期案例需求为例,详细说明如何“先创建后调整”
创建图形:使用所有数据(指标、实际、目标、完成率)创建一个标准的簇状柱形图
转换图形:将“完成率”数据系列单独更改为折线图 (xlLine) 并将其AxisGroup属性设置为xlSecondary(次坐标轴)。这样就创建了双Y轴图表,折线图使用右侧的Y轴,而柱状图使用左侧的Y轴,如下图所示,(代码中隐藏了双Y轴,因此生成的图表看不到)

“上下分区布局”的视觉模拟:通过将折线图对应的次坐标轴刻度范围调整来实现。这样,折线将在图表绘图区的上半部分绘制,而簇状图使用主坐标轴(通常从0开始),占据下半部分,从而在视觉上形成上下分区
图表美化:为图表添加数据标签,并根据“完成率”数据动态将折线图中的圆点设置为红色或绿色,使图表信息更直观、易于理解
参考代码如下,可以根据需要在此基础上剪裁或是其他个性化设计
Sub GenerateReportAndChart()' 声明变量Dim ws As WorksheetDim lastRow As Long, i As LongDim chartObj As ChartObjectDim cht As ChartDim sngTop As Single, sngLeft As SingleDim rngData As Range, rngChartData As RangeDim completionRate As DoubleDim targetSeries As seriesOn Error GoTo ErrorHandler'设置工作表对象:当前活动工作表操作Set ws = ActiveSheetApplication.ScreenUpdating = False' 获取数据范围最后一行(假设数据从第2行开始,第1行为标题)lastRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).RowIf lastRow < 2 ThenMsgBox "没有找到有效数据!", vbExclamationExit SubEnd If' 计算差额(D列)和完成率(E列)For i = 2 To lastRowIf IsNumeric(ws.Cells(i, "C").Value) And IsNumeric(ws.Cells(i, "B").Value) Thenws.Cells(i, "D").Value = ws.Cells(i, "B").Value - ws.Cells(i, "C").ValueElsews.Cells(i, "D").Value = "数据错误"End IfIf IsNumeric(ws.Cells(i, "C").Value) And IsNumeric(ws.Cells(i, "B").Value) ThenIf ws.Cells(i, "B").Value <> 0 Thenws.Cells(i, "E").Value = ws.Cells(i, "C").Value / ws.Cells(i, "B").ValueElsews.Cells(i, "E").Value = "目标为零"End IfElsews.Cells(i, "E").Value = "数据错误"End IfNext i' 将E列(完成率)格式化为百分比ws.Range("E2:E" & lastRow).NumberFormat = "0.00%"' 图表需要展示:指标(A列)、实际(C列)、目标(B列)、完成率(E列)Set rngChartData = ws.Range("A1:A" & lastRow & ",B1:C" & lastRow & ",E1:E" & lastRow)' 定义图表位置放置在D7单元格右侧)sngLeft = ws.Range("D7").LeftsngTop = ws.Range("D7").Top' 创建图表对象Set chartObj = ws.ChartObjects.Add(Left:=sngLeft, Top:=sngTop, Width:=400, Height:=230)Set cht = chartObj.ChartWith cht'设置图表基本属性.SetSourceData Source:=rngChartData.chartType = xlColumnClustered ' 初始簇状柱形类型.HasTitle = True.ChartTitle.Text = "指标完成情况分析图"With .SeriesCollection(3).chartType = xlLine.AxisGroup = xlSecondary.MarkerStyle = xlMarkerStyleCircle.MarkerSize = 7End With' 设置坐标轴标题.Axes(xlCategory, xlPrimary).HasTitle = True.Axes(xlCategory, xlPrimary).AxisTitle.Text = ws.Range("A1").Value ' 指标名称' 设置图例位置.HasLegend = True.Legend.Position = xlLegendPositionBottom'调整主坐标轴With .Axes(xlValue, xlPrimary).MaximumScale = 1000.Format.Line.Visible = msoFalse.TickLabels.Font.ColorIndex = xlColorIndexNoneEnd With'调整次坐标轴With .Axes(xlValue, xlSecondary).MaximumScale = 1.5.MinimumScale = -1.Format.Line.Visible = msoFalse.TickLabels.Font.ColorIndex = xlColorIndexNoneEnd With' 添加数据标签.SeriesCollection(1).HasDataLabels = True.SeriesCollection(2).HasDataLabels = True.SeriesCollection(3).HasDataLabels = True.Axes(xlValue).MajorGridlines.Delete '删除网格线End WithSet targetSeries = cht.SeriesCollection("完成率") ' 通过名称获取系列For i = 1 To targetSeries.Points.CountIf targetSeries.Values(i) >= 1 Then ' 判断完成率是否≥100%With targetSeries.Points(i).Format.Fill.ForeColor.RGB = RGB(0, 176, 80) ' 绿色.Visible = msoTrueEnd WithElseWith targetSeries.Points(i).Format.Fill.ForeColor.RGB = RGB(255, 0, 0) ' 红色.Visible = msoTrueEnd WithEnd IfNext iApplication.ScreenUpdating = TrueMsgBox "数据计算与图表生成完成!", vbInformationExit SubErrorHandler:Application.ScreenUpdating = TrueMsgBox "运行过程中出现错误:" & Err.Description, vbCriticalEnd Sub
3 结尾
好了,今天的编程知识到此结束了,又到每日分享冷知识的时间了,今天介绍一种编程方式——打孔卡编程
打孔卡编程是计算机发展早期(20世纪50至70年代)一种主流的程序输入方式,它将程序指令和数据通过物理打孔的方式编码在纸卡片上,再由计算机读取执行。在当时,它作为主流的程序输入媒介,见证了从机器码到高级语言的过渡,对计算机的普及和应用产生了深远影响
本公众号一直在不间断地分享免费的编程案例和实用技巧。无论您是用来提升自动化办公效率还是想提升自我,请关注我的公众号,解锁更多的编程知识