循环浏览多个工作表并删除给定范围内的每一个空列



我想循环浏览多个工作表,并删除给定范围内的每一个空列。

我得到

错误2023和运行时错误13

在if语句上。

Sub Delete_all_empty_columns_test2()
Dim Areas(12) As Range, Idx As Integer, C As Range
Set Areas(0) = Ark2.Range("C6:W6")
Set Areas(1) = Ark4.Range("D11:X11")
Set Areas(2) = Ark3.Range("D11:X11")
Set Areas(3) = Ark3.Range("AC11:AW11")
Set Areas(4) = Sheet1.Range("C6:W6")
Set Areas(5) = Ark12.Range("C6:W6")
Set Areas(6) = Ark11.Range("C6:W6")
Set Areas(7) = Ark11.Range("AA6:AU6")
Set Areas(8) = Ark14.Range("D11:X11")
Set Areas(9) = Ark8.Range("D11:X11")
Set Areas(10) = Ark9.Range("D11:X11")
Set Areas(11) = Ark10.Range("D11:X11")
Set Areas(12) = Sheet2.Range("E13:X13")
For Idx = 0 To 12
For Each C In Areas(12).Cells
If C.Value = "0" Or C.Value = "" Or C.Value = "N/A" Then
C.EntireColumn.Delete
End If
Next C
Next Idx
End Sub

尽管您可以轻松地在所有工作表(或工作表(中循环,但循环的简单性被每个工作表上要执行的任务之间的复杂性差异所击败。在设计代码时,您应该识别重复的任务。在这种情况下,它是删除空白列。

在实际编写代码时,您需要从核心向外工作。在这种情况下,核心是测试。If C.Value = "0"无法工作,因为范围的值是一个数组。下一个任务是循环浏览列。你不能使用For。。。每个列都是因为您需要先删除最后一列,因为当删除其中一些列时,列的位置会发生变化。

这是由上述逻辑产生的代码。

Sub DeleteEmptyColumns(ByVal RngAddress As String, _
Ws As Worksheet)
Dim C       As Long             ' loop counter: columns

With Ws.Range(RngAddress)
For C = (.Column + .Columns.Count - 1) To .Column Step -1
With .Worksheet
If WorksheetFunction.CountA(.Columns(C)) = 1 Then
.Columns(C).EntireColumn.Delete
End If
End With
Next C
End With
End Sub

使用两个参数调用sub,即要检查的列范围的地址和找到它的工作表。在下一步中,您需要一个过程来调用sub。这个过程的性质来自子例程的要求。给你。

Sub DeleteEmptyColumns_Main()
DeleteEmptyColumns "C6:W6", Ark2
DeleteEmptyColumns "D11:X11", Ark4

'    Set Areas(2) = Ark3.Range("D11:X11")
'    Set Areas(3) = Ark3.Range("AC11:AW11")
'    Set Areas(4) = Sheet1.Range("C6:W6")
'    Set Areas(5) = Ark12.Range("C6:W6")
'    Set Areas(6) = Ark11.Range("C6:W6")
'    Set Areas(7) = Ark11.Range("AA6:AU6")
'    Set Areas(8) = Ark14.Range("D11:X11")
'    Set Areas(9) = Ark8.Range("D11:X11")
'    Set Areas(10) = Ark9.Range("D11:X11")
'    Set Areas(11) = Ark10.Range("D11:X11")

DeleteEmptyColumns "E13:X13", Worksheets("Sheet2")
End Sub

我没有完成打字任务,但这很容易。注意,你甚至可以将一列作为RngAddresss参数传递,但它必须像";C: C";。工作表可以使用CodeNames(就像您的代码一样(或选项卡名称来指定,需要像上面最后一项所示的Worksheets("MyTab")这样的语法——只是为了显示。最好坚持一种方法。CodeNames的[dis-]优点在于,当用户更改选项卡名称时,它们不会更改。

可以说,调用执行子例程的任务可以通过Main中的循环来简化,但这是另一个线程的另一个问题。我怀疑这种努力是否值得,因为重复的数量是有限的。

因此,唯一需要做的就是考虑子程序的范围。由于它不会从除Main之外的任何位置调用,因此应该与Main放在同一模块中,因此它的作用域不必是Public(这是默认值(,因此应该标记为Private

最新更新