我已经构建了此代码,并且工作正常。但是,我希望必须有一种更优雅的方法来将范围“ c”嵌入到Evaluate函数中,而不是如何使用“ r”来确定行号并将其构建到引用中。
(我正在学习)。 (非常精简的)xlsm的副本可在此处获取:https://www.dropbox.com/s/e6pcugqs4zizfgn/2018-11-28%20-%20Hide%20table%20rows.xlsm?dl=0
Sub HideTableRows()
Application.ScreenUpdating = False
Dim c As Range
Dim r As Integer
For Each c In Range("ForecastTable[[Group]:[Item]]").Rows
r = c.Row
If Application.Evaluate("=COUNTA(B" & r & ":D" & r & ") = 0") = True Then
c.EntireRow.Hidden = True
Else: c.EntireRow.Hidden = False
End If
Next c
Application.ScreenUpdating = True
End Sub
答案 0 :(得分:2)
没有特定的问题/问题,但这是我建议的代码改进。
Hidden
过程。这样,您就不必重复执行只需要完成一次的操作。在循环和处理数据时,这始终是最佳实践。 在确定范围后对工作表进行更改。 ScreenUpdating
。 Evaluate
函数很好,但是isEmpty
可能是最好的选择。可能有一些更快的方法,也许检查多个if语句,但是在数千行中花了不到一秒的时间(可能不值得研究)。rows
。您可以连续使用一个单元格,然后检查下两个单元格,请参见Offset
的使用以生成该范围。与使用硬编码的列(“ A” /“ B” ... etc“)相比,这也带来了更大的动态性Long
相比,推荐使用Integer
,但是它很小,我仅提及because I posted about it here.。从技术上讲,您甚至不需要上述更改即可。代码如下:
Sub HideTableRows()
Dim c As Range, hIdeRNG As Range, WS As Worksheet
'based on OP xlsm file.
Set WS = Sheet4
'used range outside of used range to avoid an if-statement on every row
Set hIdeRNG = WS.Cells(Rows.Count, 1)
'loops through range of single cells for faster speed
For Each c In Range("ForecastTable[Group]").Cells
If IsEmpty(Range(c, c.Offset(0, 2))) = 0 Then
'only need a single member in the row.
Set hIdeRNG = Union(hIdeRNG, c)
End If
Next c
'Hides rows only if found more than 1 cell in loop
If hIdeRNG.Cells.Count > 1 Then
Intersect(WS.UsedRange, hIdeRNG).EntireRow.Hidden = True
End If
End Sub
最终思想:如果您正在寻找非VBA解决方案,那么Excel可能会在2019年初发布一些重要增强功能,这些功能可能会对此类情况有用。 Click here for more info from MS.
答案 1 :(得分:1)
稍微翻转一下逻辑,为什么不只过滤这三列的空白,然后一次隐藏所有可见的过滤后的空白行呢?
类似这样的东西:
Sub DoTheHide()
Dim myTable As ListObject
Set myTable = Sheet4.ListObjects("ForecastTable")
With myTable.Range
.AutoFilter Field:=1, Criteria1:="="
.AutoFilter Field:=2, Criteria1:="="
.AutoFilter Field:=3, Criteria1:="="
End With
Dim rowsToHide As Range
On Error Resume Next
Set rowsToHide = myTable.DataBodyRange.SpecialCells(xlCellTypeVisible)
On Error GoTo 0
myTable.AutoFilter.ShowAllData
If Not rowsToHide Is Nothing Then
rowsToHide.EntireRow.Hidden = True
End If
End Sub
答案 2 :(得分:1)
由于使用c来对行进行迭代,并且每行包含有问题的3个单元,所以("=COUNTA(B" & r & ":D" & r & ") = 0")
等效于("=COUNTA(" & c.Address & ") = 0")
。但是直接使用WorksheetFunction是更好的方法。
应注意,Range("[Table]") will return the proper result as long as the table is in the ActiveWorkbook. It would be better to use
ThisWorkbook.Worksheets(“ Sheet1”)。Range(“ [Table]”)`。
Sub HideTableRows()
Application.ScreenUpdating = False
Dim row As Range, target As Range
With Range("ForecastTable[[Group]:[Item]]")
.EntireRow.Hidden = False
For Each row In .rows
If Application.WorksheetFunction.CountA(row) = 0 Then
If target Is Nothing Then
Set target = row
Else
Set target = Union(target, row)
End If
End If
Next
End With
If Not target Is Nothing Then target.EntireRow.Hidden = True
Application.ScreenUpdating = True
End Sub