【问题标题】:VBA - Manipulate Specific Sheet Data With Macro - Not ActivesheetVBA - 使用宏操作特定工作表数据 - 不是 Activesheet
【发布时间】:2018-05-08 16:38:56
【问题描述】:

我的工作簿中有 10 张工作表 - 这些工作表是从各个工作簿中导入的 - 这些工作簿是从不同的监控工具中提取的

我需要对所有 10 个工作表应用过滤器,但是,并非所有工作表都采用相同的格式/结构。

对于 6 个工作表,列标题相同且顺序相同。

剩下的 4 张有不同的标题。例如:过滤器需要查找标题名称 Status - 这适用于具有相同结构的 6 个工作表,但是,其他 4 个工作表具有以下内容:

wsheet1:

用户状态 而不是 Status - 我需要将标题更改为 Status

wsheet2:

Current_Status 而不是 Status - 我需要将标题更改为 Status

下面是示例代码,它应该操纵 指定的工作表,以使其“看起来”与其他工作表相同,但是,我遇到了一些非常烦人的问题'不应用于指定的工作表,而是在执行宏时应用于“Activesheet”。

这是我的代码:

Sub arrangeSheets()

    Dim lastCol As Long, idCount As Long, nameCount As Long, headerRow As Long

    Dim worksh As Integer, WS_Count As Integer, i As Integer, count As Integer

    Dim rng As Range, cel As Range, rngData As Range

    Dim worksheetexists As Boolean

            worksh = Application.Sheets.count
            worksheetexists = False

            headerRow = 1       'row number with headers
            lastCol = Cells(headerRow, Columns.count).End(xlToLeft).Column 'last column in header row
            idCount = 1
            nameCount = 1


            ' Set WS_Count equal to the number of worksheets in the active
            ' workbook.
            WS_Count = ActiveWorkbook.Worksheets.count

            'If Application.Match finds no match it will throw an error so we need to skip them
            On Error Resume Next

            For x = 1 To worksh

                If Worksheets(x).Name = "wsheet1" Then
                    worksheetexists = True

                    Set rng = Sheets("wsheet1").Range(Cells(headerRow, 1), Cells(headerRow, lastCol)) 'header range

                    With Worksheets("wsheet1").Name

                        Rows(2).Delete
                        Rows(1).Delete
                        count = Application.Match("*USER STATUS*", Worksheets("wsheet1").Range("A1:AZ1"), 0)

                        If Not IsError(count) Then
                            For Each cel In rng                     'loop through each cell in header
                                If cel = "*USER STATUS*" Then       'check if header is "Unit ID"

                                    cel = "STATUS" & idCount        'rename "Unit ID" using idCount
                                    idCount = idCount + 1           'increment idCount

                                End If
                            Next cel
                        End If

                    End With

            Exit For

                End If

            Next x
            End Sub

【问题讨论】:

  • 您是说您只需将User Status 更改为Status on wsheet1` 并在wsheet2 上将Current_Status 更改为Status
  • 这一切都在同一个工作簿中运行吗?请注意,首先要排序的是不要只使用单元格或范围,而是使用它们附带的工作表名称,否则它将默认为 Activesheet
  • 我需要对 4 个工作表进行更多更改,但我需要有关如何“关注”正确工作表的帮助,然后我将处理我需要操作工作表的代码。@ ashleedawg
  • 感谢@QHarr 的回复,我还在学习,所以我会在这些方面对自己进行更多的教育。

标签: vba excel


【解决方案1】:
  • 考虑使用.,在With-End with 部分参考提到的工作表:

  • If cel Like "*USER STATUS*" 中的Like* 一起使用,因此对于12USER STATUS12 或类似的东西,将评估为True

  • count 变量应声明为变体,因此它本身可以保留“错误”。

这就是代码的样子:

With Worksheets("wsheet1")

    .Rows(2).Delete
    .Rows(1).Delete
    Count = Application.Match("*USER STATUS*", .Range("A1:AZ1"), 0)

    If Not IsError(Count) Then
        For Each cel In Rng                     'loop through each cell in header
            If cel Like "*USER STATUS*" Then    'check if header is "Unit ID"
                cel = "STATUS" & idCount        'rename "Unit ID" using idCount
                idCount = idCount + 1           'increment idCount    
            End If
        Next cel
    End If

End With

【讨论】:

  • 我用您在@Vityata 上面提供的示例修改了我的代码,但目前任何工作表上都没有发生任何事情。
  • 我还按照@QHarr 的建议将计数声明更改为变体。
【解决方案2】:

如果您想在工作簿中的所有工作表中使用相同的标题,您可以从第一个工作表中复制标题并将它们粘贴到每个工作表上。

如果您的列顺序在工作表中不同,这将不起作用,但从您给出的示例来看,它只是重命名列而不是重新排序?

Sub CorrectHeaders()

    Dim cpyRng As Range

    With ThisWorkbook
        If .Worksheets.count > 1 Then

            With .Worksheets(1)
                Set cpyRng = .Range(.Cells(1, 1), .Cells(1, .Columns.count).End(xlToLeft))
            End With

            .Sheets.FillAcrossSheets cpyRng

        End If
    End With

End Sub

如果列标题的顺序不同,但您只想将包含文本“状态”的任何单元格替换为“状态”,那么您可以使用Replace。您可能需要添加MatchCase:=True 的额外条件。

Sub Correct_Status()

    Dim wrkSht As Worksheet

    For Each wrkSht In ThisWorkbook.Worksheets
        wrkSht.Cells(1, 1).EntireRow.Replace What:="*Status*", Replacement:="Status", LookAt:=xlWhole
    Next wrkSht

End Sub

【讨论】:

  • 感谢您的回复和帮助@Darren。抱歉,在我的问题中,我忘了说我需要做一些更改,而不仅仅是重命名标题。否则,您的代码会完美运行,但在具有不同标题的四张纸上,它们也有不同数量的列,并且与其他 6 张纸的顺序不同。
  • 我添加了代码来替换 Status。不过,这不会让您知道单词的结尾。
  • 再次感谢您的回复。不幸的是,代码似乎没有做任何事情@Darren。我什至创建了一个只包含列标题的新工作簿并进行了测试,但什么也没发生。
  • 这很奇怪。我的测试工作簿有六张纸,其中包含各种单元格,其中包含文本“状态”:“Current_Status”、“用户状态”、“此状态错误”和“inconcievablestatus's”,并将每个单元格更改为“状态”。代码在包含要更改的文本的工作簿中 - ThisWorkbook 并且标题位于第 1 行?也许尝试将ThisWorkbook 更改为ActiveWorkbook
  • 啊!我们去吧!谢谢达伦的帮助:)
【解决方案3】:

我有其他解决方案也有助于解决此问题。代码如下:

Sub ManipulateSheets()

    Dim worksh As Integer

    Dim worksheetexists As Boolean

    worksh = Application.Sheets.count
    worksheetexists = False

    'If Application.Match finds no match it will throw an error so we need to skip them
    On Error Resume Next

    Worksheets("wSheet1").Activate

    With Worksheets("wSheet1")

        .Rows(2).Delete
        .Rows(1).Delete
    End With

    Worksheets("wSheet2").Activate

    With Worksheets("wSheet2")

        .Rows(2).Delete

    End With

End Sub

【讨论】:

    猜你喜欢
    • 2022-11-13
    • 1970-01-01
    • 1970-01-01
    • 2019-08-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-20
    • 1970-01-01
    相关资源
    最近更新 更多