Excel 更改事件的VBA手动工作表计算

Excel 更改事件的VBA手动工作表计算,excel,vba,Excel,Vba,我是VBA的新手,正在寻找有关如何手动控制以下内容的更改事件的建议。 列“F”有一个返回“Fail”或“0”的Vlookup,当列F中的单个单元格变为0时,让每个单独的代码隐藏行,我发现下面的方法效果最好 Private Sub Worksheet_Change(ByVal Target As Range) Dim myRow As Long If Target.Column = 6 Then ' Loop through rows 5-160 For myRow = 5

我是VBA的新手,正在寻找有关如何手动控制以下内容的更改事件的建议。 列“F”有一个返回“Fail”或“0”的Vlookup,当列F中的单个单元格变为0时,让每个单独的代码隐藏行,我发现下面的方法效果最好

Private Sub Worksheet_Change(ByVal Target As Range)

Dim myRow As Long

If Target.Column = 6 Then
'       Loop through rows 5-160
    For myRow = 5 To 160
'           Hide row in entry in column F is "0"
        Rows(myRow).Hidden = (Cells(myRow, "F") = "0")
    Next myRow
End If

End Sub
我曾尝试在事件更改时使用下面的命令,但它会使程序崩溃并始终重新启动。如有任何建议,将不胜感激。谢谢

Private Sub Worksheet_Calculate()
   Worksheet_Change Range("F:F")
End Sub

这是我对你想要实现的目标的看法。如果F5:F160中的公式返回的值发生变化,则工作表_计算会捕获这些变化的值,而工作表_change只会处理这些变化的值

警告:当工作簿中存在易失性函数时,这种从公式中捕获更改值的方法不起作用。Volatile函数包括TODAY()、NOW()、OFFSET(…)等

选项显式
私有子工作表_更改(ByVal目标作为范围)
如果不相交(目标,范围(“F5:F160”))则为零
Application.EnableEvents=False
关于错误转到meh
调光范围
调试。打印“chg:&Intersect(目标,范围(“F5:F160”))。地址(0,0)
对于相交中的每个t(目标,范围(“F5:F160”))
't.EntireRow Hidden=CBool(LCase(t.Value2)=“失败”或t.Value2=0)
t、 EntireRow.Hidden=CBool(LCase(t.Value2)=“失败”)
下一个t
如果结束
无聊的:
Application.EnableEvents=True
端接头
专用子工作表_Calculate()
静态effs作为变量
变暗f为长,t为范围
如果我是空的,那么
effs=范围(“F1:F160”)。值2
对于f=5到160
如果IsError(effs(f,1)),则effs(f,1)=vbNullString
下一个f
其他的
对于f=5到160
如果不是IsError(单元格(f,“f”)),则
如果effs(f,1)单元格(f,“f”)。值2,则
如果不是,那么t什么都不是
集合t=并集(t,单元(f,“f”))
其他的
设置t=单元(f,“f”)
如果结束
effs(f,1)=单元格(f,“f”)。值2
如果结束
如果结束
下一个f
如果不是,那么t什么都不是
调试。打印“计算:&t.Address(0,0)
工作表\u更改t
如果结束
如果结束
端接头

这似乎在测试工作簿上运行良好。在您自己的情况下,可能需要额外的错误和循环控制。

是否有公式使用类似于小计或聚合的函数,这些函数依赖于隐藏/可见单元格?你有像offset、address、today和now这样的易失性函数吗?你最好回到工作表中的单个单元格和工作表中的静态数组。为什么
“0”
是一个看起来像数字而不是实数的字符串?除了vlookup之外,我没有任何其他公式可以改变单元格。“0”这只是一个备选答案——我也会将其保留为“空”,但它无论如何都有效。我只需要找出一个纠结,当F列中的一个单元格被更新时,事件会发生变化,因为它们会一次改变一个单元格,而不是一次改变所有单元格。@Jeeped感谢您的见解。我想我必须回到单个单元格-这是以前的设置方式,但我想看看是否有更简单的代码。它工作得非常完美!我对VBA还是一个新手,所以我永远也不会想出像你这样的答案。再次感谢您的帮助!见我最后的修改。
Option Explicit

Private Sub Worksheet_Change(ByVal Target As Range)

    If Not Intersect(Target, Range("F5:F160")) Is Nothing Then
        Application.EnableEvents = False
        On Error GoTo meh
        Dim t As Range
        Debug.Print "chg: " & Intersect(Target, Range("F5:F160")).Address(0, 0)

        For Each t In Intersect(Target, Range("F5:F160"))
            't.EntireRow Hidden = CBool(LCase(t.Value2) = "fail" or t.Value2=0)
            t.EntireRow.Hidden = CBool(LCase(t.Value2) = "fail")
        Next t
    End If

meh:
    Application.EnableEvents = True

End Sub

Private Sub Worksheet_Calculate()
    Static effs As Variant
    Dim f As Long, t As Range

    If IsEmpty(effs) Then
        effs = Range("F1:F160").Value2
        For f = 5 To 160
            If IsError(effs(f, 1)) Then effs(f, 1) = vbNullString
        Next f
    Else
        For f = 5 To 160
            If Not IsError(Cells(f, "F")) Then
                If effs(f, 1) <> Cells(f, "F").Value2 Then
                    If Not t Is Nothing Then
                        Set t = Union(t, Cells(f, "F"))
                    Else
                        Set t = Cells(f, "F")
                    End If
                    effs(f, 1) = Cells(f, "F").Value2
                End If
            End If
        Next f

        If Not t Is Nothing Then
            Debug.Print "calc: " & t.Address(0, 0)
            Worksheet_Change t
        End If
    End If
End Sub