【问题标题】:Loop through Worksheets with similar name structure in VBA在 VBA 中循环使用具有相似名称结构的工作表
【发布时间】:2015-05-08 14:35:44
【问题描述】:

我的 Excel 文件具有以下工作表结构:

A1A2A3A4B1B2B3C1C2C3C5@p>@987654332

所以你可以看到 4 次 A、3 次 B、5 次 C 等等(没有均匀分布)

我想做的是遍历工作表组并应用一些代码。在这种情况下,组内的代码必须相同,但组之间的代码必须不同,因此我不能简单地同时遍历所有工作表。

我知道如何在 VBA 中获取工作表的名称。我的第一个想法是首先“切断”组名右侧的数字(最后一个字符),然后识别结果的唯一组。然后我想为每个组循环,例如第一个循环将从 A1 开始并在 A4 停止。但是我如何告诉 VBA 识别名称中的上边界不是恒定的(在示例中是 A4,然后是 B3,然后是 C5 等)?

也许这也不是最有效的方法。如果有任何意义,我什至可以将所有工作表重命名为不同的系统,但无论如何都必须应用编码。任何想法都受到高度赞赏。

简而言之,我想做什么:

1) 按名称(上例中的 A、B、C)识别唯一的 Worksheeps 组

2) 对于每个组,循环遍历所有相关工作表并应用一些代码

谢谢。

【问题讨论】:

  • 只需编写一个返回布尔值的小方法并检查工作表是否存在,如果存在则返回 true 并执行您的工作,如果不存在则您到达范围的末尾并移动到下一组。

标签: excel vba loops


【解决方案1】:

为了识别唯一组,您可以执行一个循环来查看工作表名称,如果它有“A”,则执行 X、“B”、执行 Y 等。

Dim ws as Worksheet

For each ws in Activebook.Sheets
    If ws.name like "A*" Then
       ** Code for "A" worksheets
    Else If ws.name like "B" Then
       ** code for "B*" worksheets
    Else If [...]
    End if

Next ws

然后您可以为每种工作表类型创建其他宏并在上述代码中调用它。即:

Private Sub A_Things()
  msgbox("This is a sheet 'A' type")
  [...whatever other code you want]
End Sub

Private Sub B_Things()
 msgbox("This is a sheet 'B' type")
 [...whatever other code you want]
End Sub

Sub checkSheets()

    Dim ws as Worksheet

    For each ws in Activebook.Sheets
        If ws.name like "A*" Then
           Call A_Things
        Else If ws.name like "B" Then
           Call B_Things
        Else If [...]
        End if
    Next ws
End Sub

编辑:对于只想在某些工作表上执行此操作或设置一些上限的部分...如果您确切知道要在哪些工作表上运行代码,则可以将它们放入数组中,然后仅在该数组中的工作表上运行代码。

类似(伪代码):

Dim nameArray() as Variant
ReDim nameArray(4) 'Note, this can hold 5 values, so if you have X sheets, ReDim this to X-1 sheets

nameArray = Array("A1","A2","A4","B1","B3")

for i = 0 to UBound(nameArray())
  'this will loop through Sheet A1, then A2, then A4, etc. and run the code below
    If nameArray(i) = "A1" Then
         [run A1 code]
    ElseIf [...]
    End If
Next i

【讨论】:

  • 这个解决方案也不错。如果可以,我会同时接受。
【解决方案2】:

另一种方式.. 如果你的名字只是 A - Z

Sub DoStuff()
Dim i As Integer
Dim counter As Integer
'loop through A to Z
For i = 65 To 90
    counter = 1
   'loop until we no longer have a valid sheet
    Do While isWorksheet(Chr(i) + CStr(counter)) = True
        'do work by calling the correct method
        Run (setSubName(Chr(i)))
        counter = counter + 1
    Loop
Next i
End Sub

'check to see if the worksheet exists
Function isWorksheet(name As String) As Boolean
On Error GoTo wsError
Err.Clear
'just try and access the name
Sheets(name).name

wsError:
    If Err.Number = 0 Then
        isWorksheet = True
    Else
        isWorksheet = False
    End If
End Function


'set the sub routine name to call
Function setSubName(value As String) As String
    setSubName = Switch(value = "A", "Sub_A_Name", value = "B", "Sub_B_Name", _
    value = "C", "Sub_C_Name", value = "D", "Sub_D_Name")
End Function


Sub Sub_A_Name()
    'do work for group A
End Sub

【讨论】:

  • 非常好的解决方案,我喜欢在循环中使用Chr,特别是因为它可以轻松地从 A 循环到 Z。
  • 编辑:不幸的是,当我运行您的代码时,我收到错误 438,问题似乎出在 Sheets(name).name 行。 Err.Number 始终设置为 438,isWorksheet 始终设置为 false(我注意到在调试模式下)。这种行为的原因是什么?
  • 传入的名称是什么,它是有效的工作表名称吗?该代码确实可以按照我的测试工作,因此问题出在您传入的工作表名称上。
  • 哦,好吧,我猜我错了。我现在可以使用它了,谢谢。
【解决方案3】:

我建议使用Dictionary 来定义组和每组中的工作表数。

这是一个想法:

Sub LoopThroughGroupsOfSheets()
'Needs reference to MS Scripting Runtime
Dim dic As Dictionary
Dim i As Integer, k As Integer
Dim wshName As String

'define Sheets for loop and count of them
Set dic = New Dictionary
dic.Add "A", 4
dic.Add "B", 3
dic.Add "C", 5

For k = 0 To dic.Count - 1
    For i = 1 To dic.Items(k)
        DoSomething  dic.Keys(k) & i
    Next
Next

End Sub

Sub DoSomething(wshName As String)

    Debug.Print wshName

End Sub

结果:

SheetName: A1
SheetName: A2
SheetName: A3
SheetName: A4
SheetName: B1
SheetName: B2
SheetName: B3
SheetName: C1
SheetName: C2
SheetName: C3
SheetName: C4
SheetName: C5

【讨论】:

  • 这似乎是一个非常好的解决方案,尽管必须手动计算Set dic = New Dictionary 行下方的工作表数
  • 谢谢。据我所知,工作表(组)的集合是定义的,所以......干杯,Maciej
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-04-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多