VBA Runtime Error 91问题咨询:原正常代码突发运行时报错
分析Runtime Error 91的原因与修复方案
我来帮你拆解这个突然出现的Runtime Error 91——这其实是VBA里最常见的“对象引用未设置”错误,说白了就是你代码里某个用Set声明的对象变量(比如snRow或者TmRow)没找到目标内容,变成了Nothing,之后你去访问它的属性(比如.Row或.Column)就触发了报错。咱们一步步解决:
1. 直接触发报错的原因:TmRow未找到匹配项
你标注的错误行是.Cells(ETRow, TmRow.Column),这里的TmRow是通过Find方法在Sheets("Summary").Range("C9:F9")里查找TMName得到的。如果这个范围内没有和TMName完全匹配的内容,Find方法就会返回Nothing,此时访问TmRow.Column就会直接抛出Error 91。
修复方案:每次Find后都判断对象是否存在
在使用TmRow之前,一定要先检查它是不是Nothing:
With Sheets("Summary") .Cells(4, r.Column - 1) = Sheets(x).Cells(snRow.Row, r.Column).Value Set TmRow = .Range("C9:F9").Find(TMName, LookIn:=xlValues, LookAt:=xlWhole) ' 新增判断:确保找到TmRow再执行后续操作 If Not TmRow Is Nothing Then .Cells(ETRow, TmRow.Column) = Left(r.Value, InStr(1, r.Value, "ET", vbTextCompare) - 1) ETRow = ETRow + 1 Else ' 可选:加个提示,方便排查问题 MsgBox "在Summary表的C9:F9范围未找到TMName: " & TMName End If End With
2. 潜在风险:snRow也可能为Nothing
你用Set snRow = .Range("C:C").Find("Total Staff", ...)查找“Total Staff”,如果当前遍历的工作表C列没有这个内容,snRow就会变成Nothing,后续访问snRow.Row同样会报错。所以也要补上判断:
With Sheets(x) TMName = Left(.Name, 6) Set snRow = .Range("C:C").Find("Total Staff", LookIn:=xlValues, LookAt:=xlWhole) ' 新增判断:没找到Total Staff就跳过这个工作表 If snRow Is Nothing Then MsgBox "工作表" & .Name & "的C列未找到'Total Staff',已跳过该表" GoTo NextSheet ' 跳转到循环末尾,处理下一个工作表 End If ' 后续的rng遍历逻辑... End With ' 循环末尾的标签 NextSheet:
3. 致命逻辑错误:重复的条件判断
你代码里有个明显的笔误:第一个If判断的是InStr(1, r.Value, "LT") > 0,然后处理ETRow;第二个ElseIf居然还是同样的条件!这导致第二个分支永远不会执行,逻辑完全混乱——这大概率是你把第一个条件的"LT"写成了"ET"的笔误。
修复后的条件判断:
' 第一个分支处理ET内容 If InStr(1, r.Value, "ET") > 0 Then With Sheets("Summary") .Cells(4, r.Column - 1) = Sheets(x).Cells(snRow.Row, r.Column).Value Set TmRow = .Range("C9:F9").Find(TMName, LookIn:=xlValues, LookAt:=xlWhole) If Not TmRow Is Nothing Then .Cells(ETRow, TmRow.Column) = Left(r.Value, InStr(1, r.Value, "ET", vbTextCompare) - 1) ETRow = ETRow + 1 End If End With ' 第二个分支处理LT内容 ElseIf InStr(1, r.Value, "LT") > 0 Then With Sheets("Summary") .Cells(5, r.Column - 1) = Sheets(x).Cells(snRow.Row, r.Column).Value Set TmRow = .Range("I9:L9").Find(TMName, LookIn:=xlValues, LookAt:=xlWhole) If Not TmRow Is Nothing Then .Cells(LTRow, TmRow.Column) = Left(r.Value, InStr(1, r.Value, "LT", vbTextCompare) - 1) LTRow = LTRow + 1 End If End With End If
4. 额外优化建议
- 避免重复调用
Sheets(Sheets(x).Name),既然已经用With Sheets(x)了,直接用.Cells(...)访问当前工作表的单元格即可,更高效也不容易出错。 - 检查
TMName = Left(Sheets(x).Name, 6)的逻辑:确保所有非Summary工作表的名称长度都≥6,否则会得到不完整的名称,导致Find匹配失败。
内容的提问来源于stack exchange,提问作者Php Newbie
相关产品推荐
相关产品推荐

