为什么这个简单的macros(隐藏行)导致Excel变得无法响应?

作为最近交通科学项目的一部分,我收到了一张来自7094次车祸的数据表。 为了只过滤掉相关的数据 – 在这种情况下,涉及行人,死亡或重伤的事故 – 我尝试调整我在网上find的一个macros。

这是我第一次涉足VBA,虽然我有一些C和Java的本科经验(以防万一certificate有关)。 代码如下:

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无法响应。 我可以看到macros正在执行预定的function,但是我不能保存或重新获得对程序的控制权。

为此挣扎是浪费了很多时间,我有一个感觉,问题(和后来的修复)是非常非常简单的 – 希望。

任何意见将不胜感激。

除了添加ScreenUpdatingEnableEvent布尔值之外,还可以重构代码以仅执行一次隐藏/取消隐藏操作(在本例中为两次),而不是在每次循环迭代中执行,这会减慢速度。 你也可以closures计算(如果这影响的话)。

 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 

为了加速这个代码,你只需要添加Application.ScreenUpdating = False到开始和Application.ScreenUpdating = 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。 这实际上不应该是必要的,你的方式当然更容易阅读。