通过宏选项卡与按钮调用VBA宏出现图表位置差异问题
问题原因与解决方案
核心原因
你的代码里Range(ThisColumn & j)没有明确指定所属工作表,当通过按钮调用宏时,活动工作表不一定是"Current DMB Template",此时Range会默认引用当前活动工作表的单元格,导致读取的Left和Top是活动表中对应单元格的位置(而非主工作表修改后的行列位置)。而从开发工具/VBA编辑器调用时,你大概率是在主工作表界面操作,活动表正好是目标表,所以位置计算正确。
修复步骤
只需在所有引用主工作表单元格的Range前加上工作表对象main,确保始终读取目标表的单元格位置:
修改KPI子过程中创建图表对象的那一行:
Set embeddedchart = main.ChartObjects.Add(Left:=main.Range(ThisColumn & j).Left, Width:=170, Top:=main.Range(ThisColumn & j).Top, Height:=100)
完整修改后的KPI子过程
Sub KPI() Dim wb As Workbook Dim main As Worksheet Dim KPI As Worksheet Dim embeddedchart As ChartObject Set wb = ThisWorkbook Set main = wb.Sheets("Current DMB Template") Set KPI = wb.Sheets("KPI") Dim TotalGraphsD As Byte 'will store how many graphs in D Dim TotalGraphsG As Byte ' will store how many graphs in G Dim i As Long, j As Long Dim ThisColumn As String For i = 1 To 11 Step 3 ThisColumn = IIf(KPI.Range("E" & (i + 1)).Value = "No", "G", "D") 'which column will be the graph j = 9 + (7 * IIf(ThisColumn = "G", TotalGraphsG, TotalGraphsD)) ' 添加main.前缀,确保引用主工作表的单元格位置 Set embeddedchart = main.ChartObjects.Add(Left:=main.Range(ThisColumn & j).Left, Width:=170, Top:=main.Range(ThisColumn & j).Top, Height:=100) With embeddedchart.Chart .SetSourceData Source:=KPI.Range("B" & i & ":C" & (i + 1)) .ChartWizard , xlColumn, , xlColumns, , , True 'plot by cols .SeriesCollection(1).XValues = "=" & KPI.Range("A" & (i + 1)).Address(True, True, xlA1, True, True) 'title End With If ThisColumn = "G" Then TotalGraphsG = TotalGraphsG + 1 Else TotalGraphsD = TotalGraphsD + 1 Next i End Sub
额外建议
养成明确指定工作表对象的习惯,避免依赖ActiveSheet或默认活动表,这是VBA中常见的避坑技巧,能彻底解决这类环境依赖问题。
内容的提问来源于stack exchange,提问作者Kris_Toor
相关产品推荐
相关产品推荐

