Excel VBA技术问询:跨表排序数据后生成柱状图遇运行时错误91
解决VBA排序时运行时错误91及柱状图排序问题
嘿,我来帮你搞定这个头疼的问题——运行时错误91通常是因为你代码里的对象变量没被正确初始化,比如引用了某个工作表或单元格范围,但没明确指定它属于哪个工作簿/工作表,或者目标数据范围根本不存在,导致对象变成了Nothing。
错误原因拆解
简单说就是:你代码里用了某个对象(比如工作表、数据范围),但没给它“赋值”,VBA找不到它,就抛出了错误91。比如你直接写Range("A1:B10").Sort,但当前激活的工作表不是你要的,这就会出问题。
修正后的完整代码示例
假设你的联赛排名数据在名为"联赛排名"的工作表里,A列是球队名,B列是积分,表头在第1行,要在"主工作表"生成降序排序后的柱状图。以下代码解决了初始化问题,并且保证排序和图表生成正常运行:
Sub 生成排序后的联赛柱状图() Dim 源数据工作表 As Worksheet Dim 主表 As Worksheet Dim 目标数据范围 As Range Dim 新图表 As ChartObject ' 明确指定工作表,绝对不要依赖ActiveSheet! Set 源数据工作表 = ThisWorkbook.Worksheets("联赛排名") Set 主表 = ThisWorkbook.Worksheets("主工作表") ' 错误捕获,方便排查问题 On Error GoTo 错误处理 ' 自动获取整个数据区域(包含表头),不用手动写固定范围 Set 目标数据范围 = 源数据工作表.Range("A1").CurrentRegion ' 执行降序排序:按B列(积分)从高到低排 With 源数据工作表.Sort .SortFields.Clear ' 先清空之前的排序规则 .SortFields.Add _ Key:=目标数据范围.Columns(2), _ SortOn:=xlSortOnValues, _ Order:=xlDescending .SetRange 目标数据范围 ' 指定排序的整个区域 .Header = xlYes ' 告诉VBA第一行是表头,不要排序表头 .MatchCase = False .Orientation = xlTopToBottom .Apply ' 执行排序 End With ' 在主工作表生成柱状图 Set 新图表 = 主表.ChartObjects.Add(Left:=100, Width:=500, Top:=100, Height:=300) With 新图表.Chart .SetSourceData Source:=目标数据范围 .ChartType = xlColumnClustered ' 簇状柱状图,你可以改成其他类型 .HasTitle = True .ChartTitle.Text = "联赛积分排名(降序)" ' 设置坐标轴标题 .Axes(xlCategory).HasTitle = True .Axes(xlCategory).AxisTitle.Text = "球队名称" .Axes(xlValue).HasTitle = True .Axes(xlValue).AxisTitle.Text = "积分" End With Exit Sub 错误处理: MsgBox "出错啦:错误代码 " & Err.Number & " - " & Err.Description, vbExclamation End Sub
关键优化点(避免再踩坑)
- 明确对象引用:用
ThisWorkbook.Worksheets("工作表名")直接指定工作表,别用ActiveSheet——万一用户手动切了工作表,代码就乱了。 - 动态获取数据范围:
CurrentRegion会自动识别从A1开始的连续数据区域,不管数据行数怎么变都没问题,不用手动改A2:B20这种固定范围。 - 错误捕获机制:添加
On Error GoTo,出错时会弹出提示,告诉你具体错在哪,方便调试。 - 排序参数核对:确认
Header参数是xlYes还是xlNo——如果你的数据没有表头,就改成xlNo,不然表头会被一起排序。
针对你现有代码的调试建议
如果你不想用新代码,只想改自己的,重点查这几点:
- 所有用到的工作表、范围对象,是不是都用
Set语句初始化了?比如Set 某工作表 = ThisWorkbook.Worksheets("xxx")。 - 排序的
SetRange是不是指定了正确的范围?有没有可能范围是空的? - 运行报错时,点击“调试”,看黄色高亮的是哪一行——那行就是对象未初始化的地方。
内容的提问来源于stack exchange,提问作者Nicole




