根据文件名将excel文件合并到新的excel文件中

根据文件名将excel文件合并到新的excel文件中,excel,vba,runtime-error,Excel,Vba,Runtime Error,我有一个包含500-600个excel文件的文件夹,这些文件来自我制作的一个脚本,文件名最终是这样的 101a12345.xlsx 101a67899.xlsx 102a12345.xlsx 102a78999.xlsx 文件名遵循Patren、101a、102a等。我要做的是将基于该Patrent的文件合并到一个excel文件中。因此,101a12345.xlsx和101a67899.xlsx应合并为101aMaster.xlsx。所有excel文件都是单页的 我在这里找到了一个我正在尝试实

我有一个包含500-600个excel文件的文件夹,这些文件来自我制作的一个脚本,文件名最终是这样的

101a12345.xlsx
101a67899.xlsx
102a12345.xlsx
102a78999.xlsx
文件名遵循Patren、101a、102a等。我要做的是将基于该Patrent的文件合并到一个excel文件中。因此,101a12345.xlsx和101a67899.xlsx应合并为101aMaster.xlsx。所有excel文件都是单页的

我在这里找到了一个我正在尝试实现的示例代码:

摘自上面的链接:

Sub test(sourceFolder As String, destinationFolder As String)
    Const TO_DELETE_SHEET_NAME As String = "toBeDeleted"
    '------------------------------------------------------------------
    Dim settingSheetsNumber As Integer
    Dim settingDisplayAlerts As Boolean
    Dim dict As Object
    Dim wkbSource As Excel.Workbook
    Dim wks As Excel.Worksheet
    Dim filepath As String
    Dim code As String * 4
    Dim wkbDestination As Excel.Workbook
    Dim varKey As Variant
    '------------------------------------------------------------------


    'Change [SheetsInNewWorkbook] setting of Excel.Application object to
    'create new workbooks with a single sheet only.
    With Excel.Application
        settingDisplayAlerts = .DisplayAlerts
        settingSheetsNumber = .SheetsInNewWorkbook
        .SheetsInNewWorkbook = 1
        .DisplayAlerts = False
    End With


    Set dict = VBA.CreateObject("Scripting.Dictionary")


    filepath = Dir(sourceFolder)

    'Loop through each Excel file in folder
    Do While filepath <> ""

        If VBA.Right$(filepath, 5) = ".xlsx" Then

            Set wkbSource = Excel.Workbooks.Open(sourceFolder & filepath)
            Set wks = wkbSource.Worksheets(1)
            code = VBA.Left$(wkbSource.Name, 4)


            'If this code doesn't exist in the dictionary yet, add it.
            If Not dict.exists(code) Then
                Set wkbDestination = Excel.Workbooks.Add
                wkbDestination.Worksheets(1).Name = TO_DELETE_SHEET_NAME
                Call dict.Add(code, wkbDestination)
            Else
                Set wkbDestination = dict.Item(code)
            End If

            Call wks.Copy(Before:=wkbDestination.Worksheets(1))
            wkbDestination.Worksheets(1).Name = VBA.Mid$(filepath, 6)

            Call wkbSource.Close(False)

        End If

        filepath = Dir

    Loop


    'Save newly created files.
    For Each varKey In dict.keys
        Set wkbDestination = dict.Item(varKey)

        'Remove empty sheet.
        Set wks = Nothing
        On Error Resume Next
        Set wks = wkbDestination.Worksheets(TO_DELETE_SHEET_NAME)
        On Error GoTo 0

        If Not wks Is Nothing Then wks.Delete


        Call wkbDestination.SaveAs(Filename:=destinationFolder & varKey & ".xlsx")


    Next varKey


    'Restore Excel.Application settings.
    With Excel.Application
        .DisplayAlerts = settingDisplayAlerts
        .SheetsInNewWorkbook = settingSheetsNumber
    End With


End Sub
子测试(sourceFolder作为字符串,destinationFolder作为字符串)
要删除的常数\u工作表\u名称为String=“toBeDeleted”
'------------------------------------------------------------------
尺寸设置表编号为整数
Dim设置将警报显示为布尔值
作为对象的Dim dict
将wkbSource设置为Excel.工作簿
Dim以Excel格式工作。工作表
将文件路径设置为字符串
Dim代码为字符串*4
将wkbDestination设置为Excel.工作簿
Dim varKey作为变体
'------------------------------------------------------------------
'将Excel.Application对象的[SheetwWorkbook]设置更改为
'仅使用单个工作表创建新工作簿。
使用Excel.Application
设置DisplayAlerts=.DisplayAlerts
设置SheetsNumber=.SheetsWorkbook
.wWorkbook=1
.DisplayAlerts=False
以
Set dict=VBA.CreateObject(“Scripting.Dictionary”)
filepath=Dir(sourceFolder)
'循环浏览文件夹中的每个Excel文件
在文件路径“”时执行此操作
如果VBA.Right$(文件路径,5)=“.xlsx”,则
设置wkbSource=Excel.Workbooks.Open(sourceFolder&filepath)
设置wks=wkbSource.Worksheets(1)
代码=VBA.Left$(wkbSource.Name,4)
'如果字典中还不存在此代码,请添加它。
如果不存在dict.exists(代码),则
设置wkbDestination=Excel.Workbooks.Add
wkbDestination.Worksheets(1).Name=删除工作表
调用dict.Add(代码,wkbDestination)
其他的
Set wkbDestination=dict.Item(代码)
如果结束
调用wks.Copy(之前:=wkbDestination.Worksheets(1))
wkbDestination.Worksheets(1).Name=VBA.Mid$(文件路径,6)
调用wkbSource.Close(False)
如果结束
filepath=Dir
环
'保存新创建的文件。
对于dict.keys中的每个varKey
Set wkbDestination=dict.Item(varKey)
'删除空表。
设为零
出错时继续下一步
设置wks=wkbDestination.Worksheets(删除工作表名)
错误转到0
如果不是wks,则为wks。删除
调用wkbDestination.SaveAs(文件名:=destinationFolder&varKey&“.xlsx”)
下一个瓦基
'还原Excel。应用程序设置。
使用Excel.Application
.DisplayAlerts=设置DisplayAlerts
.sheetsineworkbook=设置sheetsnumber
以
端接头
然而,这段代码打开了所有工作簿,在大约60-70个打开的excel文件中,我收到一个错误:运行时错误“1004”-对象“工作簿”的方法“打开”失败

有没有办法让这段代码正常工作


Excel版本是pro plus 2016。

未经测试,但这里有一种方法可以避免同时打开多个文件:

子测试(sourceFolder作为字符串,destinationFolder作为字符串)
Dim dict作为对象,代码作为字符串
将文件作为集合、f、k、wb作为工作簿新建、wb作为工作簿
Set dict=VBA.CreateObject(“Scripting.Dictionary”)
'确保尾随“\”
EnsureSlash源文件夹
确保刷新目标文件夹
'获取源文件夹中所有xlsx文件的集合
设置colFiles=allFiles(sourceFolder,*.xlsx)
如果colFiles.Count=0,则退出子“无文件”
'根据文件名的前四个字符将文件分组
对于colfile中的每个f
代码=左(f.Name,4)
如果不存在dict.exists(代码),则设置dict(代码)=新集合“是否需要新组?”?
dict(code).Add f'将文件添加到此代码集合中
下一个f
"环游群雄,
对于dict中的每个k
设置colFiles=dict(k)'此代码的文件
设置wbNew=工作簿。添加(模板:=XLWBATWORKEM)“一张工作表
对于colfile中的每个f
使用工作簿。打开(f.Path)
.工作表(1).复制时间:=wbNew.Sheets(wbNew.Sheets.Count)
wbNew.Sheets(wbNew.Sheets.Count).Name=Replace(f.Name、.xlsx、“”)
.关闭错误
以
下一个f
Application.DisplayAlerts=False
wbNew.Sheets(1).删除“删除空工作表”
Application.DisplayAlerts=True
wbNew.SaveAs destinationFolder&k&“.xlsx”
新的,结束
下一个k
端接头
'返回`sourceFolder`中与`pattern'匹配的所有文件`
'作为文件对象的集合
函数allFiles(sourceFolder作为字符串,pattern作为字符串)作为集合
Dim col作为新系列,f
对于CreateObject(“scripting.filesystemobject”).getfolder(sourceFolder).Files中的每个f
如果f.名称与图案相似,则列添加f
下一个f
设置allFiles=col
端函数
'实用程序-检查以反斜杠结尾的路径
'如果需要跨平台,请使用Application.PathSeparator
子EnsureSlash(ByRef f作为字符串)
如果右(f,1)“\”则f=f&“\”
端接头
合并工作簿
  • 它将以唯一的前四个字符开始打开每个文件中的第一个,并将下一个打开的每个文件的第一个工作表复制到第一个打开的文件,最后将其保存为新文件
  • 不需要只有两个文件(以相同的四个字符开头),而且只能有一个
  • 调整常量部分中的值
选项显式
子工作簿()
有限公司
Sub listNames()
    Dim nm As Name
    For Each nm In ActiveWorkbook.Names
        Debug.Print nm.Name
    Next nm
End Sub
Sub deleteNames()
    Dim nm As Name
    For Each nm In ActiveWorkbook.Names
        nm.Delete
    Next nm
End Sub