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

Excel VBA自动公式更新V2:修改后代码失效求助

问题:Workbook_SheetChange代码修改后完全失效

此前可正常运行的代码:

Private Sub Workbook_SheetChange(ByVal sh As Object, ByVal Target As Range)
    
    Const FIRST_CELL_ADDRESS As String = "A2"
    Dim FeuilleExclue() As Variant: FeuilleExclue = _
        Array("HISTO", "VUE FINALE ANALYTIQUE", "BFT RENDEMENT 2030 CLIMAT")
    
    If IsNumeric(Application.Match(sh.Name, FeuilleExclue, 0)) Then Exit Sub
    
    Dim trg As Range:
    With sh.Range(FIRST_CELL_ADDRESS)
        Set trg = .Resize(sh.Rows.Count - .Row + 1)
    End With
    
    Dim irg As Range: Set irg = Intersect(trg, Target)
    If irg Is Nothing Then Exit Sub
    
    Application.EnableEvents = False
    
    ' This simplification is possible because you cannot paste a non-contiguous
    ' range unless you use VBA, and when you don't plan on clearing values.
    ' If you plan clearing values, loop trough the cells of `irg`,
    ' e.g., 'For Each cell In irg.Cells: With cell.EntireRow',
    ' and add an `If` statement in-between leaving the rest as is.
    With irg.EntireRow
        .Columns("H").FormulaR1C1 = "=IF(RC5<>"""",RC5/RC3 - 1,"""")"
        .Columns("I").FormulaR1C1 = _
            "=IFERROR(IF(AND(RC8<>"""",RC13<>""""),RC8-RC13,""""),"""")"
        .Columns("J").FormulaR1C1 = "=IF(RC9<>"""",ABS(RC9),"""")"
        .Columns("K").FormulaR1C1 = "=IF(R[+1]C7<>"""",R[+1]C7,"""")"
        .Columns("L").FormulaR1C1 = "=IF(R[+1]C7<>"""",RC11-RC7,"""")"
        .Columns("M").FormulaR1C1 = _
            "=IF(RC11<>"""",VLOOKUP(RC11,C15:C17,3,FALSE),"""")"
    End With
     
    Application.EnableEvents = True

End Sub

尝试新增P列触发公式更新功能后,代码完全失效(原A列功能也无法运行),修改后的代码:

Private Sub Workbook_SheetChange(ByVal sh As Object, ByVal Target As Range)
    
    Const FIRST_CELL_ADDRESS_A As String = "A4"
    Const FIRST_CELL_ADDRESS_P As String = "P4"
    Dim FeuilleExclue() As Variant: FeuilleExclue = _
        Array("HISTO", "VUE FINALE ANALYTIQUE", "BFT RENDEMENT 2030 CLIMAT")
    
    If IsNumeric(Application.Match(sh.Name, FeuilleExclue, 0)) Then Exit Sub
    
    Dim trgA As Range:
    With sh.Range(FIRST_CELL_ADDRESS_A)
        Set trgA = .Resize(sh.Rows.Count - .Row + 1)
    End With
    
    Dim trgP As Range:
    With sh.Range(FIRST_CELL_ADDRESS_P)
        Set trgP = .Resize(sh.Rows.Count - .Row + 1)
    End With
    
    Dim irgA As Range: Set irgA = Intersect(trgA, Target)
    Dim irgP As Range: Set irgP = Intersect(trgP, Target)
    
    If irgA And irgP Is Nothing Then Exit Sub
    
    Application.EnableEvents = False
    
    ' This simplification is possible because you cannot paste a non-contiguous
    ' range unless you use VBA, and when you don't plan on clearing values.
    ' If you plan clearing values, loop trough the cells of `irg`,
    ' e.g., 'For Each cell In irg.Cells: With cell.EntireRow',
    ' and add an `If` statement in-between leaving the rest as is.
    If Not irgA Is Nothing Then
        With irgA.EntireRow
            .Columns("H").FormulaR1C1 = "=IF(RC5<>"""",RC5/RC3 - 1,"""")"
            .Columns("I").FormulaR1C1 = _
                "=IFERROR(IF(AND(RC8<>"""",RC13<>""""),RC8-RC13,""""),"""")"
            .Columns("J").FormulaR1C1 = "=IF(RC9<>"""",ABS(RC9),"""")"
            .Columns("K").FormulaR1C1 = "=IF(R[+1]C7<>"""",R[+1]C7,"""")"
            .Columns("L").FormulaR1C1 = "=IF(R[+1]C7<>"""",RC11-RC7,"""")"
            .Columns("M").FormulaR1C1 = _
                "=IF(RC11<>"""",VLOOKUP(RC11,C15:C17,3,FALSE),"""")"
        End With
    End If
    
    If Not irgP Is Nothing Then
        With irgP.EntireRow
            .Columns("Q").FormulaR1C1 = "=IF(RC16 <>"""",RC16 / R[-1]C16 -1, """")"
        End With
    End If
            
    Application.EnableEvents = True
    
End Sub

问题原因与修正方案

核心错误

修改后的代码中,判断两个Range是否都为空的语法错误:

If irgA And irgP Is Nothing Then Exit Sub

在VBA中,判断对象是否为Nothing必须使用Is Nothing,不能直接用对象名作为布尔值。这行错误语法会直接触发运行时错误,导致整个Workbook_SheetChange事件失效。

正确写法应为:

If (irgA Is Nothing) And (irgP Is Nothing) Then Exit Sub

修正后的完整代码

Private Sub Workbook_SheetChange(ByVal sh As Object, ByVal Target As Range)
    
    Const FIRST_CELL_ADDRESS_A As String = "A4"
    Const FIRST_CELL_ADDRESS_P As String = "P4"
    Dim FeuilleExclue() As Variant: FeuilleExclue = _
        Array("HISTO", "VUE FINALE ANALYTIQUE", "BFT RENDEMENT 2030 CLIMAT")
    
    If IsNumeric(Application.Match(sh.Name, FeuilleExclue, 0)) Then Exit Sub
    
    Dim trgA As Range:
    With sh.Range(FIRST_CELL_ADDRESS_A)
        Set trgA = .Resize(sh.Rows.Count - .Row + 1)
    End With
    
    Dim trgP As Range:
    With sh.Range(FIRST_CELL_ADDRESS_P)
        Set trgP = .Resize(sh.Rows.Count - .Row + 1)
    End With
    
    Dim irgA As Range: Set irgA = Intersect(trgA, Target)
    Dim irgP As Range: Set irgP = Intersect(trgP, Target)
    
    ' 修正判断逻辑:只有当A列和P列的触发区域都为空时才退出
    If (irgA Is Nothing) And (irgP Is Nothing) Then Exit Sub
    
    Application.EnableEvents = False
    
    If Not irgA Is Nothing Then
        With irgA.EntireRow
            .Columns("H").FormulaR1C1 = "=IF(RC5<>"""",RC5/RC3 - 1,"""")"
            .Columns("I").FormulaR1C1 = _
                "=IFERROR(IF(AND(RC8<>"""",RC13<>""""),RC8-RC13,""""),"""")"
            .Columns("J").FormulaR1C1 = "=IF(RC9<>"""",ABS(RC9),"""")"
            .Columns("K").FormulaR1C1 = "=IF(R[+1]C7<>"""",R[+1]C7,"""")"
            .Columns("L").FormulaR1C1 = "=IF(R[+1]C7<>"""",RC11-RC7,"""")"
            .Columns("M").FormulaR1C1 = _
                "=IF(RC11<>"""",VLOOKUP(RC11,C15:C17,3,FALSE),"""")"
        End With
    End If
    
    If Not irgP Is Nothing Then
        With irgP.EntireRow
            ' 优化公式:避免第4行引用上方空行出错
            .Columns("Q").FormulaR1C1 = "=IF(AND(RC16<>"""",R[-1]C16<>"""",ROW()>4),RC16/R[-1]C16-1,"""")"
        End With
    End If
            
    Application.EnableEvents = True
    
End Sub

额外优化说明

针对P列的公式,增加了ROW()>4的判断,避免第4行(触发起始行)向上引用第3行时出现错误,你可以根据实际表格结构调整这个判断条件。


内容的提问来源于stack exchange,提问作者user29982961

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 19:17:05