Vba 为什么这个简单的宏(隐藏行)会导致Excel没有响应?

Vba 为什么这个简单的宏(隐藏行)会导致Excel没有响应?,vba,excel,Vba,Excel,作为最近交通科学项目的一部分,我收到了一份包含7094起车祸数据的表格。为了只过滤出相关数据——在本例中,涉及行人、死亡或重伤的车祸——我尝试调整我在网上找到的宏 这是我第一次涉猎VBA,尽管我在大学时有一些C和Java方面的经验(以防万一,这被证明是相关的)。代码如下: Sub HideRows() BeginRow = 2 EndRow = 7095 ChkCol = 10 For RowCnt = BeginRow To EndRow If Cells(RowCnt, ChkCo

作为最近交通科学项目的一部分,我收到了一份包含7094起车祸数据的表格。为了只过滤出相关数据——在本例中,涉及行人、死亡或重伤的车祸——我尝试调整我在网上找到的宏

这是我第一次涉猎VBA,尽管我在大学时有一些C和Java方面的经验(以防万一,这被证明是相关的)。代码如下:

Sub HideRows()
BeginRow = 2
EndRow = 7095
ChkCol = 10

For RowCnt = BeginRow To EndRow
    If Cells(RowCnt, ChkCol).Value > 0 Or Cells(RowCnt, ChkCol + 1).Value > 0 Or Cells(RowCnt, ChkCol + 2).Value > 0 Then
        Rows(RowCnt).EntireRow.Hidden = False
    Else
        Rows(RowCnt).EntireRow.Hidden = True
    End If
        Next RowCnt
End Sub
问题是它会导致Excel变得无响应。我可以看到宏正在执行预期的功能,但最终无法保存或恢复对程序的控制

与此抗争是浪费很多时间,我感觉问题(以及随后的修复)非常非常简单——希望如此


如果您有任何建议,我们将不胜感激。

要加快此代码的速度,您只需将
Application.ScreenUpdate=False
添加到开头,并在结尾添加
Application.ScreenUpdate=True

Sub HideRows()
BeginRow = 2
EndRow = 7095
ChkCol = 10

Application.ScreenUpdating = False
For RowCnt = BeginRow To EndRow
    If Cells(RowCnt, ChkCol).Value > 0 Or Cells(RowCnt, ChkCol + 1).Value > 0 Or Cells(RowCnt, ChkCol + 2).Value > 0 Then
        Rows(RowCnt).EntireRow.Hidden = False
    Else
        Rows(RowCnt).EntireRow.Hidden = True
    End If
Next RowCnt
Application.ScreenUpdating = True
End Sub
现在,您可能还有一些事件或条件格式,它们在每次更新工作表时都会触发。如果是这样,还应在循环开始时包括
Application.EnableEvents=False
,并在循环结束时重新启用它们

如果您真的愿意,您可以简单地说:

If Cells(RowCnt, ChkCol).Value Or Cells(RowCnt, ChkCol + 1).Value Or Cells(RowCnt, ChkCol + 2).Value 0 Then

因为在VBA中0=False。但是,这确实不必要,而且您的方式当然更容易阅读。

除了添加
屏幕更新
启用事件
布尔值外,您还可以重构代码,只执行一个隐藏/取消隐藏操作(在本例中为两个),而不是在每次循环迭代中执行该操作,这会让事情变慢。此外,您还可以关闭计算(以防影响某些内容)


我已经相应地更新了代码,运行它,我现在正在等待-希望-看到它结束。你知道这个操作最长需要多长时间吗?只是手动中断循环。在这一点上,它似乎一直工作到第1599行。将手动更新RowCnt并重新运行。这看起来很有趣。目前,宏已经运行了它的过程,并给出了预期的结果-它只是花了这么长时间!但我肯定会用它重新分析我的数据,并更仔细地研究代码,以便更好地理解。正如你们可能已经收集到的,我是VBA新手。@AshtonMoran-有时只是学习某些技巧来提高性能。有很多“正确”的答案,这些“正确”的答案带来了性能方面的利弊。
Option Explicit

    Sub HideRows()

        Dim BeginRow As Integer, EndRow As Integer, ChkCol As Integer

        BeginRow = 2
        EndRow = 7095
        ChkCol = 10

        With Application
            .ScreenUpdating = False
            .EnableEvents = False
            .Calculation = xlCalculationManual
        End With

        Application.Calculation xl

        Dim rHide As Range
        Dim rShow As Range


        For RowCnt = BeginRow To EndRow

            If Cells(RowCnt, ChkCol).Value > 0 Or Cells(RowCnt, ChkCol + 1).Value > 0 Or Cells(RowCnt, ChkCol + 2).Value > 0 Then

                If Not rHide Is Nothing Then
                    Set rHide = Cells(1, RowCnt)
                Else
                    Set rHide = Union(rHide, Cells(1, RowCnt))
                End If

            Else

                If Not rShow Is Nothing Then
                    Set rShow = Cells(1, RowCnt)
                Else
                    Set rShow = rShow(rHide, Cells(1, RowCnt))
                End If

            End If

        Next RowCnt

        'show / hide appropriate ranges
        rHide.EntireRow.Visible = False
        rShow.EntireRow.Visible = True

        With Application
            .ScreenUpdating = True
            .EnableEvents = True
            .Calculation = xlCalculationAutomatic
        End With

    End Sub