如何将多个工作表移动和复制到单个工作簿中。

huangapple go评论53阅读模式
英文:

How to move and copy multiple sheets into a single workbooks

问题

我正在尝试使用VBA将一组工作表复制到新工作簿中。但是,一组中的工作表数量可以根据某个条件而变化。

例如:35100001-1、35100001-2、35100001-3是一个工作簿中的工作表名称。

现在我想要复制工作表,其工作表名称与这些相同的字符,并将它们放入一个新的Excel工作簿中,所以在这里我希望有一个包含这些工作表的新Excel工作簿:

35100001工作簿

  • 35100001-1 35100001-2 35100001-3工作表

35100002工作簿

  • 35100002-1 35100002-2 35100002-3工作表

35100003工作簿

  • 35100003-1 35100003-2 35100003-3 35100003-4工作表

35100004工作簿

  • 35100004-1 35100004-2工作表

我正在尝试使用VBA将一组工作表复制到新工作簿中。但是,一组中的工作表数量可以根据某个条件而变化。

感谢帮助,我真的很感激。

英文:

I'm trying to copy and groups of sheets to a new workbook using VBA.
But the number of sheets in a group can change depending on a criterion.

For example: 35100001-1, 35100001-2, 35100001-3 are sheet names in one workbook.

Now I want to copy sheets with sheet name having the character same these into a single workbook , so here I want a new excel workbook containing these sheets:

35100001 workbook

  • 35100001-1 35100001-2 35100001-3 worksheets

35100002 workbook

  • 35100002-1 35100002-2 35100002-3 worksheets

35100003 workbook

  • 35100003-1 35100003-2 35100003-3 35100003-4 worksheets

35100004 workbook

  • 35100004-1 35100004-2 worksheets

I'm trying to copy and groups of sheets to a new workbook using VBA.
But the number of sheets in a group can change depending on a criterion.

thanks for the help, i really appreciate it.

答案1

得分: 1

以下是您要翻译的代码部分:

Sub ExportSheets()
    
    ' Define constants.
    
    Const DELIMITER As String = "-"
    
    ' Reference the workbook.
    
    Dim wb As Workbook: Set wb = ThisWorkbook ' workbook containing this code
    
    ' In each 'key' of a dictionary, return a unique workbook name while
    ' adding each associated sheet name to a 'key' of another dictionary held
    ' in the associated 'item' of the initial dictionary.
    
    Dim dict As Object: Set dict = CreateObject("Scripting.Dictionary")
    dict.CompareMode = vbTextCompare
    
    Dim sh As Object, DelPos As Long, wbName As String, shName As String
    
    For Each sh In wb.Sheets
        ' Prevent 'mayhem' if the only sheet of a group is hidden or very hidden
        ' i.e. very hidden sheets will never get copied but either won't
        ' raise an error if at least one of the sheets is visible.
        ' To simplify, exclude both.
        If sh.Visible = xlSheetVisible Then
            shName = sh.Name
            DelPos = InStr(shName, DELIMITER)
            ' Prevent error if the sheet name starts with the delimiter.
            If DelPos > 1 Then
                wbName = Left(shName, DelPos - 1)
                If Not dict.Exists(wbName) Then
                    Set dict(wbName) = CreateObject("Scripting.Dictionary")
                End If
                dict(wbName)(shName) = Empty
            End If
        End If
    Next sh
    
    If dict.Count = 0 Then
        MsgBox "No sheets found.", vbCritical
        Exit Sub
    End If
    
    ' Define the path: use the same path as the workbook (modify as required).
    
    Dim wbPath As String: wbPath = wb.Path
    
    ' Using the 'keys' (the workbook names) and the 'items'
    ' (the 1D arrays of sheet names ('keys')), export each group of sheets
    ' to a new workbook, then save and close the workbook.
    
    Application.ScreenUpdating = False
    
    Dim Key, FilePath As String
    
    For Each Key In dict.Keys
        wb.Sheets(dict(Key).Keys).Copy ' return the sheets in a new workbook
        With Workbooks(Workbooks.Count) ' reference this new workbook
            ' The following is all you need to save as a '.xlsx' file
            ' i.e. you don't need to specify the file extension.
            FilePath = wbPath & Application.PathSeparator & Key
            Application.DisplayAlerts = False ' overwrite without confirmation
                .SaveAs FilePath
            Application.DisplayAlerts = True
            .Close SaveChanges:=False
        End With
    Next Key
    
    Application.ScreenUpdating = True
    
    ' Inform.
    
    MsgBox "Sheets exported.", vbInformation
    
End Sub

请注意,这是代码的翻译部分。如果您需要更多帮助或其他内容的翻译,请随时告诉我。

英文:

Export Groups of Sheets to New Workbooks

如何将多个工作表移动和复制到单个工作簿中。

<!-- language: lang-vb -->

Sub ExportSheets()
&#39; Define constants.
Const DELIMITER As String = &quot;-&quot;
&#39; Reference the workbook.
Dim wb As Workbook: Set wb = ThisWorkbook &#39; workbook containing this code
&#39; In each &#39;key&#39; of a dictionary, return a unique workbook name while
&#39; adding each associated sheet name to a &#39;key&#39; of another dictionary held
&#39; in the associated &#39;item&#39; of the initial dictionary.
Dim dict As Object: Set dict = CreateObject(&quot;Scripting.Dictionary&quot;)
dict.CompareMode = vbTextCompare
Dim sh As Object, DelPos As Long, wbName As String, shName As String
For Each sh In wb.Sheets
&#39; Prevent &#39;mayhem&#39; if the only sheet of a group is hidden or very hidden
&#39; i.e. very hidden sheets will never get copied but either won&#39;t
&#39; raise an error if at least one of the sheets is visible.
&#39; To simplify, exlude both.
If sh.Visible = xlSheetVisible Then
shName = sh.Name
DelPos = InStr(shName, DELIMITER)
&#39; Prevent error if the sheet name starts with the delimiter.
If DelPos &gt; 1 Then
wbName = Left(shName, DelPos - 1)
If Not dict.Exists(wbName) Then
Set dict(wbName) = CreateObject(&quot;Scripting.Dictionary&quot;)
End If
dict(wbName)(shName) = Empty
End If
End If
Next sh
If dict.Count = 0 Then
MsgBox &quot;No sheets found.&quot;, vbCritical
Exit Sub
End If
&#39; Define the path: use the same path as the workbook (modify as required).
Dim wbPath As String: wbPath = wb.Path
&#39; Using the &#39;keys&#39; (the workbook names) and the &#39;items&#39;
&#39; (the 1D arrays of sheet names (&#39;keys&#39;)), export each group of sheets
&#39; to a new workbook, then save and close the workbook.
Application.ScreenUpdating = False
Dim Key, FilePath As String
For Each Key In dict.Keys
wb.Sheets(dict(Key).Keys).Copy &#39; return the sheets in a new workbook
With Workbooks(Workbooks.Count) &#39; reference this new workbook
&#39; The following is all you need to save as a &#39;.xlsx&#39; file
&#39; i.e. you don&#39;t need to specify the file extension.
FilePath = wbPath &amp; Application.PathSeparator &amp; Key
Application.DisplayAlerts = False &#39; overwrite without confirmation
.SaveAs FilePath
Application.DisplayAlerts = True
.Close SaveChanges:=False
End With
Next Key
Application.ScreenUpdating = True
&#39; Inform.
MsgBox &quot;Sheets exported.&quot;, vbInformation
End Sub

答案2

得分: 0

这里是一个完整的示例代码。
原则:

  1. 计算我需要的所有工作簿的名称
  2. 创建这些工作簿
  3. 逐个遍历工作簿中的每个工作表并复制到其新位置
  4. 保存并关闭所有打开的工作簿
Option Explicit
Sub demo()
Dim ws As Worksheet, colSheets As Collection, wbName As String
Set colSheets = New Collection
'首先计算要创建的其他工作簿的名称
For Each ws In ThisWorkbook.Sheets
wbName = Left(ws.Name, InStr(ws.Name, "-") - 1)
On Error Resume Next '强制循环忽略重复的键
colSheets.Add wbName, wbName
On Error GoTo 0 '重置错误处理
Next
'现在创建这些工作簿 - 并保存在与当前工作簿相同的文件夹中
Dim x As Variant, wb As Workbook
For Each x In colSheets
Set wb = Workbooks.Add(1) '强制工作簿只有1个工作表
'关闭警告,以防这是重新运行
Application.DisplayAlerts = False
wb.SaveAs Filename:=ThisWorkbook.Path & "\" & x
Application.DisplayAlerts = True
Next
'现在只需将每个工作表复制到其相关的新位置
For Each ws In ThisWorkbook.Sheets
wbName = Left(ws.Name, InStr(ws.Name, "-") - 1) & ".xlsx"
ws.Copy After:=Workbooks(wbName).Sheets(Workbooks(wbName).Sheets.Count)
Next
'整理新工作簿
For Each x In colSheets
Set wb = Workbooks(x & ".xlsx")
Application.DisplayAlerts = False
wb.Sheets("Sheet1").Delete
Application.DisplayAlerts = True
wb.Close SaveChanges:=True
Next
End Sub

还有很多改进的空间 - 例如错误处理、跳过任何已知不想复制的工作表等等。

英文:

Here is a complete worked example.
Principle:

  1. Work out the names of all the workbooks I will need

  2. Create those workbooks

  3. Step through every sheet in the workbook and copy to its new home

  4. Save and close all the open workbooks

    Option Explicit

    Sub demo()

     Dim ws As Worksheet, colSheets As Collection, wbName As String
    Set colSheets = New Collection
    &#39;First work out the names of other workbooks to create
    For Each ws In ThisWorkbook.Sheets
    wbName = Left(ws.Name, InStr(ws.Name, &quot;-&quot;) - 1)
    On Error Resume Next &#39;force the loop to ignore duplicate keys
    colSheets.Add wbName, wbName
    On Error GoTo 0 &#39;reset error handling
    Next
    &#39;Now go create those workbooks - and save in same folder as current workbook
    Dim x As Variant, wb As Workbook
    For Each x In colSheets
    Set wb = Workbooks.Add(1) &#39;forces the workbook to only have 1 sheet
    &#39;Turn off warnings in case this is a re-run
    Application.DisplayAlerts = False
    wb.SaveAs Filename:=ThisWorkbook.Path &amp; &quot;\&quot; &amp; x
    Application.DisplayAlerts = True
    Next
    &#39;Now just copy each sheet to it&#39;s relevant new home
    For Each ws In ThisWorkbook.Sheets
    wbName = Left(ws.Name, InStr(ws.Name, &quot;-&quot;) - 1) &amp; &quot;.xlsx&quot;
    ws.Copy After:=Workbooks(wbName).Sheets(Workbooks(wbName).Sheets.Count)
    Next
    &#39;Tidy up the new workbooks
    For Each x In colSheets
    Set wb = Workbooks(x &amp; &quot;.xlsx&quot;)
    Application.DisplayAlerts = False
    wb.Sheets(&quot;Sheet1&quot;).Delete
    Application.DisplayAlerts = True
    wb.Close SaveChanges:=True
    Next
    

    End Sub

Plenty of room for improvement - e.g. error handling, skip any known sheets that you don't want to copy etc., etc.

答案3

得分: 0

由于您没有提供更多详细信息,无论您是要完全自动执行过程,还是要手动运行宏以查找特定工作表名称,或者您如何输入要查找的所需工作表名称,我简化了代码。提供的代码是一个可工作的示例。请根据您的具体需求进行调整。

方法CopySheets要求您提供您要查找的基本工作表名称(例如35100001等),并维护复制工作表的整个过程。
它调用方法GetSheetsArray,该方法在当前工作簿中搜索符合您的条件的工作表名称,并将它们作为“Variant数组”返回。
最后,它创建一个新工作簿,将所有相关工作表复制到其中,并将该工作簿保存在与当前工作簿相同的文件夹中。工作簿的名称始终与您要查找的工作表名称相同(例如35100001等)。

Public Sub CopySheets()
'要求提供您要查找的基本工作表名称(例如35100001等)
Dim BaseSheetName As String
BaseSheetName = InputBox(Prompt:="基本工作表名称")
'包含符合您条件的工作表名称的数组。
Dim SheetsArray As Variant
SheetsArray = GetSheetsArray(BaseSheetName)  
Dim wbNew As Workbook
Set wbNew = Application.Workbooks.Add
'选择并复制工作表。
With ThisWorkbook
.Worksheets(SheetsArray).Select
.Activate
ActiveWindow.SelectedSheets.Copy After:=wbNew.Worksheets(1)
End With
'删除新创建的工作簿中的默认工作表。如果有3个默认工作表,请循环删除它们。
Application.DisplayAlerts = False
wbNew.Worksheets(1).Delete
Application.DisplayAlerts = True
'将新工作簿保存在与此工作簿相同的目录中,并为其命名
'您要查找的名称。根据您的首选项调整保存路径。
wbNew.SaveAs Filename:=ThisWorkbook.Path & "\" & BaseSheetName, _
FileFormat:=XlFileFormat.xlOpenXMLWorkbook
wbNew.Close
End Sub

以下函数中的输出数组实际上并不是必需的,可以直接使用GetSheetsArray。但我更喜欢这种方式,因为如果将来函数名称更改,只需在函数末尾修改它一次,这样可以简化程序员的工作。

Private Function GetSheetsArray(ByVal LookupName As String) As Variant
'输出数组的基本初始化。
Dim Output As Variant
ReDim Output(1)
Dim i As Long: i = 0
'将所有相关工作表名称存储在数组中。
Dim ws As Worksheet
For Each ws In ThisWorkbook.Worksheets
If InStr(1, ws.Name, LookupName, vbTextCompare) > 0 Then
ReDim Preserve Output(i)
Output(i) = ws.Name
i = i + 1
End If
Next ws
GetSheetsArray = Output
Erase Output
End Function

如果您想在与当前工作簿不同的工作簿中搜索符合您条件的工作表名称,可以通过将工作簿的引用作为输入参数添加到GetSheetsArray函数中来轻松修改该函数。

Private Function GetSheetsArray(ByVal LookupName As String, _
ByVal wb As Workbook) As Variant

然后在函数体内,您必须将ThisWorkbook替换为wb。

  For Each ws In wb.Worksheets
'...
Next ws
英文:

Since you didn't provide more details whether you want to have the process fully automatic or you want to run the macro manually for particular sheet names or how you put in the desired sheet name you are looking for, I made it quite simple. Provided code is a working sample. Kindly adjust it by your specific needs.

Method CopySheets asks you for base sheet name you are looking for (35100001, etc.) and maintains the whole process of copying worksheets.
It calls the method GetSheetsArray which searches for sheet names which met your criteria in current workbook and return them as Variant array.
Finally it creates new workbook where it will copy all relevant worksheets and saves the workbook in the same folder as current workbook. Name of the workbook is always identical with the sheet name you were looking for (35100001, etc.) .

Public Sub CopySheets()
&#39;Ask for the base sheet name you are looking for (35100001, etc.)
Dim BaseSheetName As String
BaseSheetName = InputBox(Prompt:=&quot;Base sheet name&quot;)
&#39;Array containing sheet names which fit your criteria.
Dim SheetsArray As Variant
SheetsArray = GetSheetsArray(BaseSheetName)  
Dim wbNew As Workbook
Set wbNew = Application.Workbooks.Add
&#39;Select and copy sheets.
With ThisWorkbook
.Worksheets(SheetsArray).Select
.Activate
ActiveWindow.SelectedSheets.Copy After:=wbNew.Worksheets(1)
End With
&#39;Delete the default sheet in newly created workbook. In case you have 3 default sheets, delete them in cycle.
Application.DisplayAlerts = False
wbNew.Worksheets(1).Delete
Application.DisplayAlerts = True
&#39;Save new workbook in same directory as this workbook and give it a name
&#39;you were looking for. Adjust the saving path by your preferences.
wbNew.SaveAs Filename:=ThisWorkbook.Path &amp; &quot;\&quot; &amp; BaseSheetName, _
FileFormat:=XlFileFormat.xlOpenXMLWorkbook
wbNew.Close
End Sub

The Output array in following function is not really necessary and GetSheetsArray can be used directly. But I prefer to use it this way because if function name changes in the future, it needs to be modified only at one place, at the end of the function. It makes programmer's life easier.

Private Function GetSheetsArray(ByVal LookupName As String) As Variant
&#39;Basic initialization of output array.
Dim Output As Variant
ReDim Output(1)
Dim i As Long: i = 0
&#39;Store all relevant sheet names in array.
Dim ws As Worksheet
For Each ws In ThisWorkbook.Worksheets
If InStr(1, ws.Name, LookupName, vbTextCompare) &gt; 0 Then
ReDim Preserve Output(i)
Output(i) = ws.Name
i = i + 1
End If
Next ws
GetSheetsArray = Output
Erase Output
End Function

If you want to search for worksheet names which met your criteria in workbook other then current workbok, you can easily modify the GetSheetsArray function by adding the reference to a workbook as an input parameter.

Private Function GetSheetsArray(ByVal LookupName As String, _
ByVal wb As Workbook) As Variant

Then within the function body you have to replace ThisWorkbook by wb.

  For Each ws In wb.Worksheets
&#39;...
Next ws

huangapple
  • 本文由 发表于 2023年6月13日 10:18:28
  • 转载请务必保留本文链接:https://go.coder-hub.com/76461334.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定