连接三段代码 "Open Dialog Box" "Cut and Paste" 和 "Split Column Rename"

Joining three pieces of Code "Open Dialog Box" "Cut and Paste" and "Split Column Rename"

希望对你有所帮助。我有以下三段代码。这三者完全相互独立地工作。一切编译宏只是不会正确执行。

第一段代码 Sub Open_Workbook_Dialog() 打开一个对话框并允许用户 select 一个文件。

第二段代码 Public Sub Sample() 在列标题中搜索文本 'CountryCode',然后剪切该列并将其粘贴到 F 列中。

第三段代码 Public Sub Filter() 获取 F 列并将其拆分为新的工作表,并根据国家/地区重命名工作表。

所以本质上,宏应该做的是打开一个对话框获取文件,找到国家/地区列所在的位置,将其剪切并粘贴到 F 列,然后将此列拆分为新工作表并重命名。

就像我说的,所有代码独立运行都很好,但是当我把它们放在一起时。对话框打开我 select 我的文件然后我得到 Msgbox "Country not Found" 即使国家代码列在 范围内我认为 Set aCell = .Range("A1:X50")国家/地区代码在 W 列中。

单击 MsgBox "Country not Found" 后,Public Sub Filter() 执行并拆分并重命名了错误的列。查找似乎没有发生,因此剪切和粘贴没有发生。

我附上了图片以便更好地理解。

未找到国家/地区

被错误的F分裂

代码如下

Sub Open_Workbook_Dialog()

Dim my_FileName As Variant

    MsgBox "Pick your TOV file" '<--| txt box for prompt to pick a file

        my_FileName = Application.GetOpenFilename(FileFilter:="Excel Files,*.xl*;*.xm*") '<--| Opens the file window to allow selection

    If my_FileName <> False Then
    Workbooks.Open Filename:=my_FileName

Call Sample '<--|Calls the Filter Code and executes

Call Filter '<--|Calls the Filter Code and executes

End If


End Sub
Public Sub Sample()
    Dim ws As Worksheet
    Dim aCell As Range, Rng As Range
    Dim col As Long, lRow As Long
    Dim colName As String

    '~~> Change this to the relevant sheet
    Set ws = ThisWorkbook.Sheets("Sheet1")

    With ws
        Set aCell = .Range("A1:X50").Find(What:="CountryCode", LookIn:=xlValues, LookAt:=xlWhole, _
                    MatchCase:=False, SearchFormat:=False)
    '~~> If Found
    If Not aCell Is Nothing Then

    '~~> Cut the entire column
    aCell.EntireColumn.Cut

    '~~> Insert the column here
    Columns("F:F").Insert Shift:=xlToRight

    Else
    MsgBox "Country Not Found"

    End If
    End With
End Sub
Public Sub Filter()
    Dim rCountry As Range, helpCol As Range

    With Worksheets("Sheet1") '<--| refer to data worksheet
        With .UsedRange
            Set helpCol = .Resize(1, 1).Offset(, .Columns.Count) '<--| get a "helper" column just at the right of used range, it'll be used to store unique country names in
        End With

        With .Range("A1:Q" & .Cells(.Rows.Count, 1).End(xlUp).Row) '<--| refer to its columns "A:Q" from row 1 to last non empty row of column "A"
            .Columns(6).AdvancedFilter Action:=xlFilterCopy, CopyToRange:=helpCol, Unique:=True '<-- call AdvancedFilter on 6th column of the referenced range and store its unique values in "helper" column
            Set helpCol = Range(helpCol.Offset(1), helpCol.End(xlDown)) '<--| set range with unique names in (skip header row)
            For Each rCountry In helpCol '<--| iterate over unique country names range (skip header row)
                .AutoFilter 6, rCountry.Value2 '<--| filter data on country field (6th column) with current unique country name
                If Application.WorksheetFunction.Subtotal(103, .Cells.Resize(, 1)) > 1 Then '<--| if any cell other than header ones has been filtered...
                    Worksheets.Add Worksheets(Worksheets.Count) '<--... add new sheet
                    ActiveSheet.Name = rCountry.Value2  '<--... rename it
                    .SpecialCells(xlCellTypeVisible).Copy ActiveSheet.Range("A1") 'copy data for country under header
                End If
            Next
        End With
        .AutoFilterMode = False '<--| remove autofilter and show all rows back
    End With
    helpCol.Offset(-1).End(xlDown).Clear '<--| clear helper column (header included)
End Sub

问题是您不是在打开的工作簿中搜索 "CountryCode",而是在工作簿中搜索 运行 您的代码。所以基本上你有一个工作簿,你可以在其中启动你的宏代码并打开另一个你想要使用的工作簿(通过使用你的对话框)。但是在您的 Public Sub Sample() 中,您的问题是:

Set ws = ThisWorkbook.Sheets("Sheet1")

问题是您正在引用工作簿,您的宏代码是使用 ThisWorkbook 在其中编写和执行的。因为您不知道 Public Sub Sample() 中的文件名。我已经编辑了您的代码以使其按应有的方式工作:

Sub Open_Workbook_Dialog()

Dim my_FileName As Variant
Dim my_Workbook As Workbook

  MsgBox "Pick your TOV file" '<--| txt box for prompt to pick a file

  my_FileName = Application.GetOpenFilename(FileFilter:="Excel Files,*.xl*;*.xm*") '<--| Opens the file window to allow selection

  If my_FileName <> False Then
    Set my_Workbook = Workbooks.Open(Filename:=my_FileName)

    Call Sample(my_Workbook)'<--|Calls the Filter Code and executes

    Call Filter(my_Workbook) '<--|Calls the Filter Code and executes

  End If
End Sub

Public Sub Sample(my_Workbook as Workbook)
  Dim ws As Worksheet
  Dim aCell As Range, Rng As Range
  Dim col As Long, lRow As Long
  Dim colName As String

  '~~> Change this to the relevant sheet
  Set ws = my_Workbook.Sheets("Sheet1")

  With ws
    Set aCell = .Range("A1:X50").Find(What:="CountryCode", LookIn:=xlValues, LookAt:=xlWhole, _
                MatchCase:=False, SearchFormat:=False)
    '~~> If Found
    If Not aCell Is Nothing Then
      '~~> Cut the entire column

      aCell.EntireColumn.Cut

      '~~> Insert the column here

      Columns("F:F").Insert Shift:=xlToRight
    Else
      MsgBox "Country Not Found"
    End If
  End With
End Sub

Public Sub Filter(my_Workbook as Workbook)
  Dim rCountry As Range, helpCol As Range

  With my_Workbook.Worksheets("Sheet1") '<--| refer to data worksheet
    With .UsedRange
      Set helpCol = .Resize(1, 1).Offset(, .Columns.Count) '<--| get a "helper" column just at the right of used range, it'll be used to store unique country names in
    End With

    With .Range("A1:Q" & .Cells(.Rows.Count, 1).End(xlUp).Row) '<--| refer to its columns "A:Q" from row 1 to last non empty row of column "A"
      .Columns(6).AdvancedFilter Action:=xlFilterCopy, CopyToRange:=helpCol, Unique:=True '<-- call AdvancedFilter on 6th column of the referenced range and store its unique values in "helper" column
      Set helpCol = Range(helpCol.Offset(1), helpCol.End(xlDown)) '<--| set range with unique names in (skip header row)
      For Each rCountry In helpCol '<--| iterate over unique country names range (skip header row)
        .AutoFilter 6, rCountry.Value2 '<--| filter data on country field (6th column) with current unique country name
        If Application.WorksheetFunction.Subtotal(103, .Cells.Resize(, 1)) > 1 Then '<--| if any cell other than header ones has been filtered...
          Worksheets.Add Worksheets(Worksheets.Count) '<--... add new sheet
          ActiveSheet.Name = rCountry.Value2  '<--... rename it
          .SpecialCells(xlCellTypeVisible).Copy ActiveSheet.Range("A1") 'copy data for country under header
        End If
      Next
    End With
    .AutoFilterMode = False '<--| remove autofilter and show all rows back
  End With
  helpCol.Offset(-1).End(xlDown).Clear '<--| clear helper column (header included)
End Sub

您可能还想将带有 .Sheets("Sheet1")(或 .Worksheets("Sheet1"))的行更改为 .Sheets(1)(或 .Worksheets(1)),这样您就不会依赖于命名在打开的工作簿中。

在设置 aCell 变量时,在您的行中包含具有 CountryCodes 的列(在本例中为 W 列)。

很有可能是引用问题。

用简单的英语来说,这意味着您没有传递新打开的工作簿的引用,因此您的另一个 Subs 不知道您在说哪个!

我已经举了一个例子来告诉你在哪里进行更改:

Sub Open_Workbook_Dialog()
Dim my_FileName As Variant

'~~> Changes here
Dim MainWbk As Workbook
Dim OpenedWbk As Workbook
'~~> Changes here
Set MainWbk = ThisWorkbook

MsgBox "Pick your TOV file"
my_FileName = Application.GetOpenFilename(FileFilter:="Excel Files,*.xl*;*.xm*")

If my_FileName <> False Then
    '~~> Changes here
    Set OpenedWbk = Workbooks.Open(Filename:=my_FileName)
    '~~> Changes here
    Call Sample(OpenedWbk, MainWbk)
    ''~~> Same changes to do here
    'Call Filter
End If


End Sub

'~~> Changes here (arguments to pass the references of the workbooks)
Public Sub Sample(OpenedWbk As Workbook, MainWbk As Workbook)
    Dim ws As Worksheet
    Dim aCell As Range, Rng As Range
    Dim col As Long, lRow As Long
    Dim colName As String

    '~~> Changes here
    Set ws = OpenedWbk.Sheets("Sheet1")

    With ws
        Set aCell = .Range("A1:X50").Find(What:="CountryCode", _
                    LookIn:=xlValues, LookAt:=xlWhole, _
                    MatchCase:=False, SearchFormat:=False)
        If Not aCell Is Nothing Then
            aCell.EntireColumn.Cut
            '~~> Changes here
            MainWbk.Columns("F:F").Insert Shift:=xlToRight
        Else
            MsgBox "Country Not Found"
        End If
    End With
End Sub