You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 04:05:55