VBA代码删除不正确的行
我有一段代码,如果一行在D列到L列中有空单元格,它将删除该行。VBA代码删除不正确的行,vba,excel,Vba,Excel,我有一段代码,如果一行在D列到L列中有空单元格,它将删除该行。 出于某种原因,它还删除了位于C8的我的标题单元格。 有人知道为什么吗?如何修复它 Sub RemoveEmptyRows() Dim ws As Worksheet For Each ws In Sheets ws.Activate Dim n As Long Dim nlast As Long Dim rw As Range Set rw = ActiveWorkbook.ActiveSheet.U
出于某种原因,它还删除了位于C8的我的标题单元格。
有人知道为什么吗?如何修复它
Sub RemoveEmptyRows()
Dim ws As Worksheet
For Each ws In Sheets
ws.Activate
Dim n As Long
Dim nlast As Long
Dim rw As Range
Set rw = ActiveWorkbook.ActiveSheet.UsedRange.Rows
nlast = rw.count
For n = nlast To 1 Step -1
If (rw.Cells(n, 4).Value = "" And rw.Cells(n, 5).Value = "" And rw.Cells(n, 6).Value = "" And rw.Cells(n, 7).Value = "" And rw.Cells(n, 8).Value = "" And rw.Cells(n, 9).Value = "" And rw.Cells(n, 10).Value = "" And rw.Cells(n, 11).Value = "") Then
rw.Rows(n).Delete
End If
Next n
Next ws
End Sub
问题在于,您使用的是
UsedRange
的行和列索引,假设它们与工作表的索引相匹配。事实并非如此。正如您在评论中向@YowE3K指出的,您有一些完全空的列
解决方案非常简单-只需使用ws.Cells
而不是rw.Cells
。我还将循环中的所有内容都放入带有
块的中,以使其更快、更可读。您还可以通过将长If
语句转换为Select Case
梯形图来缩短该语句:
Sub RemoveEmptyRows()
Dim ws As Worksheet
For Each ws In ThisWorkbook.Sheets
With ws
Dim n As Long
Dim nlast As Long
nlast = .UsedRange.Rows(.UsedRange.Rows.Count).Row
For n = nlast To 9 Step -1
Select Case False
Case .Cells(n, 4).Value = vbNullString
Case .Cells(n, 5).Value = vbNullString
Case .Cells(n, 6).Value = vbNullString
Case .Cells(n, 7).Value = vbNullString
Case .Cells(n, 8).Value = vbNullString
Case .Cells(n, 9).Value = vbNullString
Case .Cells(n, 10).Value = vbNullString
Case .Cells(n, 11).Value = vbNullString
Case Else
.Rows(n).Delete
End Select
Next n
End With
Next ws
End Sub
请注意,还有更可靠的方法可以找到工作表的最后一行。问题在于,您使用的是UsedRange
的行和列索引,假设它们与工作表的索引匹配。事实并非如此。正如您在评论中向@YowE3K指出的,您有一些完全空的列
解决方案非常简单-只需使用ws.Cells
而不是rw.Cells
。我还将循环中的所有内容都放入带有
块的中,以使其更快、更可读。您还可以通过将长If
语句转换为Select Case
梯形图来缩短该语句:
Sub RemoveEmptyRows()
Dim ws As Worksheet
For Each ws In ThisWorkbook.Sheets
With ws
Dim n As Long
Dim nlast As Long
nlast = .UsedRange.Rows(.UsedRange.Rows.Count).Row
For n = nlast To 9 Step -1
Select Case False
Case .Cells(n, 4).Value = vbNullString
Case .Cells(n, 5).Value = vbNullString
Case .Cells(n, 6).Value = vbNullString
Case .Cells(n, 7).Value = vbNullString
Case .Cells(n, 8).Value = vbNullString
Case .Cells(n, 9).Value = vbNullString
Case .Cells(n, 10).Value = vbNullString
Case .Cells(n, 11).Value = vbNullString
Case Else
.Rows(n).Delete
End Select
Next n
End With
Next ws
End Sub
请注意,还有更可靠的方法可以找到工作表的最后一行。以下是您的代码,稍作修改
Sub RemoveEmptyRows()
Dim ws As Worksheet
Dim n As Long
Dim nlast As Long
Dim rw As Range
For Each ws In Worksheets 'changed. In case there are Chart Sheets.
'deleted ws.activate. AVOID THAT AS PLAGUE
Set rw = ws.UsedRange.Rows
With rw
nlast = .Count
For n = nlast To 2 Step -1 'Note the 2, to skip title row. As was pointed in comments.
If (.Cells(n, 4).Value2 = "" And .Cells(n, 5).Value2 = "" And .Cells(n, 6).Value2 = "" And .Cells(n, 7).Value2 = "" And .Cells(n, 8).Value2 = "" And .Cells(n, 9).Value2 = "" And .Cells(n, 10).Value2 = "" And .Cells(n, 11).Value2 = "") Then
.Rows(n).Delete
End If
Next n
End With 'rw
Next ws
End Sub
这是你的代码稍微修改一下
Sub RemoveEmptyRows()
Dim ws As Worksheet
Dim n As Long
Dim nlast As Long
Dim rw As Range
For Each ws In Worksheets 'changed. In case there are Chart Sheets.
'deleted ws.activate. AVOID THAT AS PLAGUE
Set rw = ws.UsedRange.Rows
With rw
nlast = .Count
For n = nlast To 2 Step -1 'Note the 2, to skip title row. As was pointed in comments.
If (.Cells(n, 4).Value2 = "" And .Cells(n, 5).Value2 = "" And .Cells(n, 6).Value2 = "" And .Cells(n, 7).Value2 = "" And .Cells(n, 8).Value2 = "" And .Cells(n, 9).Value2 = "" And .Cells(n, 10).Value2 = "" And .Cells(n, 11).Value2 = "") Then
.Rows(n).Delete
End If
Next n
End With 'rw
Next ws
End Sub
您的标题在C8中,然后在第1行之前不要删除:
替换
For n = nlast To 1 Step -1
借
您的标题在C8中,然后在第1行之前不要删除:
替换
For n = nlast To 1 Step -1
借
您可以尝试以下(未测试)代码:
您可以尝试以下(未测试)代码:
如果顶部有空行,UsedRange
的行索引不一定与工作表的行索引匹配。嗯,代码有点乱。例如,在循环中定义变量让我感到恶心。但实际上它删除了从第4(D)列到第11(K)列中没有任何内容的每一整行。因此,如果D8:K8中的单元格为空,第8行将被删除。尝试用F8单步遍历代码。我认为@Comintern的注释可能是原因,但您总是使用行作为从UsedRange
开始的偏移量-实际上,您没有从UsedRange
开始偏移的是列。我敢打赌,a、B或C列中都有一个完全空的列,因此rw。单元格(n,4)
不是指D列(等)您是否只需要将For loop更新为For n=nlast到第2步-1
,因为页眉正在UsedRange
中计数?您的UsedRange
的示例是什么?如果顶部有空行,UsedRange
的行索引不一定与工作表的行索引匹配。嗯,代码有点乱。例如,在循环中定义变量让我感到恶心。但实际上它删除了从第4(D)列到第11(K)列中没有任何内容的每一整行。因此,如果D8:K8中的单元格为空,第8行将被删除。尝试用F8单步遍历代码。我认为@Comintern的注释可能是原因,但您总是使用行作为从UsedRange
开始的偏移量-实际上,您没有从UsedRange
开始偏移的是列。我敢打赌,a、B或C列中都有一个完全空的列,因此rw。单元格(n,4)
不是指D列(等)您是否只需要将For loop更新为For n=nlast至2 step-1
,因为标头正在UsedRange
中计数?您的UsedRange
示例是什么?@MTBthePRO-Yup。已修复。对于n=nlast至9步骤-1
@MTBthePRO-Yup。已修复。对于n=nlast至9步骤-1