excel - VBA - 在某些列为空之后删除某些行
问题描述
我有一个 excel 表,如下所示:
Name task date1 date2 date3 date4
John t1 d1
Lucy t2
Mary t3 d2 d3
我想删除第三列之后的列(即 from date1
)为空的行(例如本例中的 Lucy)
我找到了下面的示例,我认为它很接近,但不确定如何通过选择第三列之后的空行而不是整行来修改它。
Sub DeleteAllEmptyRows()
Dim LastRowIndex As Integer
Dim RowIndex As Integer
Dim UsedRng As Range
Set UsedRng = ActiveSheet.UsedRange
LastRowIndex = UsedRng.Row - 1 + UsedRng.Rows.Count
Application.ScreenUpdating = False
For RowIndex = LastRowIndex To 1 Step -1
If Application.CountA(Rows(RowIndex)) = 0 Then 'Some logic to add here to choose range
Rows(RowIndex).Delete
End If
Next RowIndex
Application.ScreenUpdating = True
End Sub
请问有什么建议吗?谢谢。
解决方案
我认为您需要的只是首先计算使用范围中的最后一列,然后在循环内的 CountA 语句中使用它。
要计算最后一列,您可以在循环之前添加以下行:
Dim LastColIndex As Integer: LastColIndex = UsedRng.Column - 1 + UsedRng.Columns.Count
然后,该If
语句需要看起来像这样:
If WorksheetFunction.CountA(Range(Cells(RowIndex, 3), Cells(RowIndex, LastColIndex))) = 0 Then
这将检查从当前行的第 3 列开始的非空值。
合并后的代码将如下所示:
Sub DeleteAllEmptyRows()
Dim LastRowIndex As Integer
Dim RowIndex As Integer
Dim UsedRng As Range
Set UsedRng = ActiveSheet.UsedRange
LastRowIndex = UsedRng.Row - 1 + UsedRng.Rows.Count
Application.ScreenUpdating = False
Dim LastColIndex As Integer: LastColIndex = UsedRng.Column - 1 + UsedRng.Columns.Count
For RowIndex = LastRowIndex To 1 Step -1
If WorksheetFunction.CountA(Range(Cells(RowIndex, 3), Cells(RowIndex, LastColIndex))) = 0 Then
Rows(RowIndex).Delete
End If
Next RowIndex
Application.ScreenUpdating = True
End Sub
我还将For
循环更改为倒数到 2 而不是 1 以避免删除标题行的可能性,但我想这取决于你的口味:)
在幻像值的情况下...
有时,单元格的值是肉眼不可见的,但由 Excel 的COUNTA
函数计算,例如当一个单元格有一个或多个空格作为其值时。如果需要考虑这些情况,我们可以使用以下 VBA 函数单独检查每个单元格:
Function IsBlankRange(ByRef rng As Range) As Boolean
'For faster processing, read in the entire range into a memory variable
' instead of reading in each cell value from Excel
Dim arr As Variant: arr = rng.Value
'If the range contains a single value, check it and exit
If Not IsArray(arr) Then 'With single-value ranges, arr will not be an array
IsBlankRange = Trim(arr & "") = ""
Exit Function
End If
'If we are here, the range contains an array of values,
' so we must loop through the array
'Assume the range is not blank
IsBlankRange = False
Dim arrLb1 As Long: arrLb1 = LBound(arr, 1)
Dim arrUb1 As Long: arrUb1 = UBound(arr, 1)
Dim arrLb2 As Long: arrLb2 = LBound(arr, 2)
Dim arrUb2 As Long: arrUb2 = UBound(arr, 2)
Dim i As Long, j As Long
For i = arrLb1 To arrUb1
For j = arrLb2 To arrUb2
'Return false (the value assumed above) on the first non-blank value
If Trim(arr(i, j) & "") <> "" Then Exit Function
Next
Next
'If we are here, no non-blank value was encountered, so the range is blank
IsBlankRange = True
End Function
此功能可用于将If WorksheetFunction.CountA(...) = 0
线路更改为
If IsBlankRange(Range(Cells(RowIndex, 3), Cells(RowIndex, LastColIndex))) Then
简而言之,新程序如下所示:
Sub DeleteAllEmptyRows()
Dim LastRowIndex As Integer
Dim RowIndex As Integer
Dim UsedRng As Range
Set UsedRng = ActiveSheet.UsedRange
LastRowIndex = UsedRng.Row - 1 + UsedRng.Rows.Count
Application.ScreenUpdating = False
Dim LastColIndex As Integer: LastColIndex = UsedRng.Column - 1 + UsedRng.Columns.Count
For RowIndex = LastRowIndex To 1 Step -1
If IsBlankRange(Range(Cells(RowIndex, 3), Cells(RowIndex, LastColIndex))) Then
Rows(RowIndex).Delete
End If
Next RowIndex
Application.ScreenUpdating = True
End Sub
当然,IsBlankRange
也需要添加新功能(DeleteAllEmptyRows
可能在代码下方)。如果该函数永远不会在其他任何地方使用,则可以将该函数设为模块私有。
但是,如果你可以使用 CONCAT ...
IsBlankRange
如果您有 Excel 2019 并且可以使用新功能,则可以简化该功能CONCAT
,该功能可以应用于范围:
Function IsBlankRange(ByRef rng As Range) As Boolean
IsBlankRange = Trim(WorksheetFunction.Concat(rng) & "") = ""
End Function
{CONCAT
函数在https://www.excelfunctions.net/excel-concat-function.html有解释}
除了使用IsBlankRange
函数,CONCAT
也可以直接在循环If
内的语句中使用:For
If Trim(WorksheetFunction.Concat(Range(Cells(RowIndex, 3), Cells(RowIndex, LastColIndex))) & "") = "" Then
但是,我相信将范围评估留在单独的函数中可以更容易地根据所使用的 Excel 版本进行自定义,并且使If
语句更易于阅读。
推荐阅读
- django - 使用抽象用户扩展默认用户
- javascript - 从数据库到输入的日期时间格式 type='datetime' PHP
- angular - Angular 7:路由到另一个应用程序时如何构建脚本和样式
- spring - 如何在没有代码的情况下从“Spring Tool Suite”可执行文件中共享 Spring MVC 项目?
- javascript - Python/Flask/HTML - 在新窗口而不是主页中呈现 HTML
- java - 如何从多个输入 xml 构建 XML
- c++ - 使用 std::move 将 unique_ptr 移动到向量中
- amazon-web-services - 将域指向 Route 53
- python - VGG16 Tensorflow 实现在 cifar-10 上不学习
- mysql - 如何在 SQL 中将多行合并为一行?