每个工作表循环的 Excel VBA

Posted

技术标签:

【中文标题】每个工作表循环的 Excel VBA【英文标题】:Excel VBA For Each Worksheet Loop 【发布时间】:2014-03-22 00:10:54 【问题描述】:

我正在编写代码以基本上浏览我的工作簿中的每个工作表,然后更新列宽。下面是我写的代码;我没有收到任何错误,但它实际上也没有做任何事情。非常感谢任何帮助!

 Option Explicit
 Dim ws As Worksheet, a As Range

Sub forEachWs()

For Each ws In ActiveWorkbook.Worksheets
Call resizingColumns
Next

End Sub

Sub resizingColumns()
Range("A:A").ColumnWidth = 20.14
Range("B:B").ColumnWidth = 9.71
Range("C:C").ColumnWidth = 35.86
Range("D:D").ColumnWidth = 30.57
Range("E:E").ColumnWidth = 23.57
Range("F:F").ColumnWidth = 21.43
Range("G:G").ColumnWidth = 18.43
Range("H:H").ColumnWidth = 23.86
Range("i:I").ColumnWidth = 27.43
Range("J:J").ColumnWidth = 36.71
Range("K:K").ColumnWidth = 30.29
Range("L:L").ColumnWidth = 31.14
Range("M:M").ColumnWidth = 31
Range("N:N").ColumnWidth = 41.14
Range("O:O").ColumnWidth = 33.86
End Sub

【问题讨论】:

现在这是根据假设运行的,可能是错误的,但如果您正在尝试这样做,您可以使用 ws.Columns("A:O").AutoFit 代替您的子系统。 【参考方案1】:

尝试稍微修改您的代码:

Sub forEachWs()
    Dim ws As Worksheet
    For Each ws In ActiveWorkbook.Worksheets
        Call resizingColumns(ws)
    Next
End Sub

Sub resizingColumns(ws As Worksheet)
    With ws
        .Range("A:A").ColumnWidth = 20.14
        .Range("B:B").ColumnWidth = 9.71
        .Range("C:C").ColumnWidth = 35.86
        .Range("D:D").ColumnWidth = 30.57
        .Range("E:E").ColumnWidth = 23.57
        .Range("F:F").ColumnWidth = 21.43
        .Range("G:G").ColumnWidth = 18.43
        .Range("H:H").ColumnWidth = 23.86
        .Range("i:I").ColumnWidth = 27.43
        .Range("J:J").ColumnWidth = 36.71
        .Range("K:K").ColumnWidth = 30.29
        .Range("L:L").ColumnWidth = 31.14
        .Range("M:M").ColumnWidth = 31
        .Range("N:N").ColumnWidth = 41.14
        .Range("O:O").ColumnWidth = 33.86
    End With
End Sub

注意,resizingColumns 例程采用参数 - Ranges 所属的工作表。

基本上,当您使用Range("O:O") - 代码操作范围为ActiveSheet 时,这就是您应该使用With ws 语句然后使用.Range("O:O") 的原因。

并且没有必要使用全局变量(除非你在其他地方使用它们)

【讨论】:

【参考方案2】:

试试这个更简洁的代码:

Sub LoopOverEachColumn()
    Dim WS As Worksheet
    For Each WS In ThisWorkbook.Worksheets
        ResizeColumns WS
    Next WS
End Sub

Private Sub ResizeColumns(WS As Worksheet)
    Dim StrSize As String
    Dim ColIter As Long
    StrSize = "20.14;9.71;35.86;30.57;23.57;21.43;18.43;23.86;27.43;36.71;30.29;31.14;31;41.14;33.86"
    For ColIter = 1 To 15
        WS.Columns(ColIter).ColumnWidth = Split(StrSize, ";")(ColIter - 1)
    Next ColIter
End Sub

如果您想要更多列,只需将1 to 15 更改为1 to X,其中X 是您想要的列的列索引,并将您想要的列大小附加到StrSize

例如,如果您希望P:P 的宽度为25,只需将;25 添加到StrSize 并将ColIter... 更改为ColIter = 1 to 16

希望这会有所帮助。

【讨论】:

另一种方法是使用Array(20.14,9.71,..)代替string+split:) 更短的代码,但会使用更多的内存并且会稍微慢一些。更短并不意味着更好。 是的,这就是我拒绝那个“声明”的原因,哈哈。但是,除非用户想要对几十个工作表和数百个列执行此操作,否则我认为更新此操作要容易得多(至少如果您知道列索引并且不会被 StrSize 混淆,harhar)。就我而言,它在相对瞬间完成了 3 张。 :)【参考方案3】:

您需要将工作表标识符放在您的范围语句中,如下所示...

 Option Explicit
 Dim ws As Worksheet, a As Range

Sub forEachWs()

For Each ws In ActiveWorkbook.Worksheets
Call resizingColumns
Next

End Sub

Sub resizingColumns()
ws.Range("A:A").ColumnWidth = 20.14
ws.Range("B:B").ColumnWidth = 9.71
ws.Range("C:C").ColumnWidth = 35.86
ws.Range("D:D").ColumnWidth = 30.57
ws.Range("E:E").ColumnWidth = 23.57
ws.Range("F:F").ColumnWidth = 21.43
ws.Range("G:G").ColumnWidth = 18.43
ws.Range("H:H").ColumnWidth = 23.86
ws.Range("i:I").ColumnWidth = 27.43
ws.Range("J:J").ColumnWidth = 36.71
ws.Range("K:K").ColumnWidth = 30.29
ws.Range("L:L").ColumnWidth = 31.14
ws.Range("M:M").ColumnWidth = 31
ws.Range("N:N").ColumnWidth = 41.14
ws.Range("O:O").ColumnWidth = 33.86
End Sub

【讨论】:

@simoco 发布了我的答案的更简洁版本。我应该删除我的吗?【参考方案4】:

而不是添加“ws”。在每个范围之前,如上所述,您可以添加 “ws.activate” 在调用之前代替。

这将使您进入要处理的工作表。

【讨论】:

我建议不要这样做,因为它容易出错。为每个范围或命令显式定义工作表可确保使用适当的工作表来执行。使用激活时,用户可以在执行期间手动选择另一个工作表,并且您的代码会关闭。此外,您最好将其添加为评论而不是答案,因为它确实不能回答手头的问题。

以上是关于每个工作表循环的 Excel VBA的主要内容,如果未能解决你的问题,请参考以下文章

包含不同类型 VBA Excel 的组的每个下一个循环中的类型不匹配

Excel VBA:For循环扫描一组工作表

每个工作表的 VBA 循环

使用 VBA 循环遍历工作表中的每个打印页面

用VBA程式设计如何遍历EXCEL每一个工作表

工作表循环用户定义的功能故障