【问题标题】:VBA code to call different macro depending on part of Worksheet nameVBA代码根据工作表名称的一部分调用不同的宏
【发布时间】:2017-11-25 13:22:50
【问题描述】:

我正在开发一个宏,它将循环浏览活动工作簿中的所有工作表,然后根据工作表名称中是否包含相关关键字之一来清除特定工作表的某个部分。在每种情况下,工作表名称都会不同,但我要清除的任何内容都将包含以下关键字之一。

我已经设置了一个单独的宏来清除每种情况下的单元格范围。如果工作表名称不包含任何关键字,我希望宏移动到下一个工作表。

我的最终目标是能够将其应用于许多不同的工作簿,因为我正在处理的项目是按区域划分的,每个区域都有一个单独的 Excel 文件。

我一直在尝试的代码如下。我运行代码时没有出现错误,代码似乎也没有运行,实际上什么也没发生!

任何指导或建议将不胜感激。

Sub Loop_Customer_Sheets()

    Dim ws As Integer
    Dim i As Integer

    ws = ActiveWorkbook.Worksheets.Count

    For i = 1 To ws
        If ActiveSheet.Name Like "*ABC*" Then
            Call ABCInfoClear
        ElseIf ActiveSheet.Name Like "*DEF*" Then
            Call DEFInfoClear
        ElseIf ActiveSheet.Name Like "*GHI*" Then
            Call GHIInfoClear
        Else:
        End If
    Next i
End Sub

【问题讨论】:

    标签: excel loops if-statement worksheet vba


    【解决方案1】:

    “什么都没有发生” - 用您的代码解决问题:

    您的问题是您正在循环通过 number 个工作表,但您只检查了 ActiveSheet,它永远不会改变!将您的代码替换为

    ws = ActiveWorkbook.Worksheets.Count
    For i = 1 To ws
        With ActiveWorkbook.WorkSheets(i)
            If .Name Like "*ABC*" Then
                ABCInfoClear
            ElseIf .Name Like "*DEF*" Then
                DEFInfoClear
            ElseIf ActiveSheet.Name Like "*GHI*" Then
                GHIInfoClear
            End If
        End With
    Next i
    

    注意:你不需要 Call 关键字,你可以像上面介绍的那样调用 subs。


    替代解决方案

    比拥有大量宏更好的选择可能是创建一个通用子类

    Sub ClearRangeInSheet(rangeAddress As String, sh As WorkSheet)
        Dim myRange As Range
        Set myRange = sh.Range(rangeAddress)
        myRange.ClearContents
        ' Any other cell clearing code e.g. for formatting here
    End Sub 
    

    然后在循环中调用

    Dim wsCount as Long
    wsCount = ActiveWorkbook.WorkSheets.Count
    For i = 1 to wsCount
        With ActiveWorkbook
            If .WorkSheets(i).Name Like "*ABC*" Then
                ' Always pass ".WorkSheets(i)", but change the range address as needed
                ClearRangeInSheet("A1:A20", .WorkSheets(i))
            ElseIf ' Other worksheet name conditions ...
    
            End If
        End With
    Next I
    

    按照 cmets 中的建议,您可以放弃索引工作表,而只循环访问工作表对象本身:

    Dim wksht as WorkSheet
    For Each wksht In ActiveWorkbook.WorkSheets
        If wksht.Name Like "*ABC*" Then
            ' Always pass wksht but change the range address as needed
            ClearRangeInSheet("A1:A20", wksht)
        ElseIf ' Other worksheet name conditions ...
    
        End If
    Next wksht
    

    【讨论】:

    • 也许使用For Each ws In ActiveWorkBook.Worksheets(将ws定义为工作表)而不是For...Next循环。
    • @Darren,绝对是一个选择,我只是想尽可能接近 OP 的布局以保持简单。我在编辑中包含了一个很好的建议示例。
    • 嗨 Wolfie,感谢一百万花时间给出如此深入的回答!我已经用您概述的代码替换了我的代码(我暂时避免添加您建议的快捷方式,但将来肯定会添加它们)。宏现在正在工作,但在同一张工作表上运行所有 InfoClear 宏,并且不会转换到下一张工作表。是否有可能发生这种情况的常见原因?我目前正在审查我在上面的示例中输入的内容,但到目前为止我没有看到任何差异。
    • 要回答这个问题,我必须查看您的 InfoClear 宏之一的示例,请将其编辑到您的问题中...您可能在每个宏中使用 ActiveSheet 或类似的的宏,您希望将相关工作表作为输入参数传递给这些子。
    • 你是正确的,经过审查,我记得我的清除宏只是我选择和清除相关单元格的记录,因此它们被锁定到活动表。我已将您的通用子合并到我的宏中,现在一切正常。再次感谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-13
    • 1970-01-01
    • 2014-04-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多