Excel·VBA使用ADO合并工作簿

之前文章《Excel·VBA合并工作簿(7,合并子文件夹同名工作簿中同名工作表,纵向汇总数据)》处理合并工作簿问题,代码运行速度比较慢

《Excel·VBA使用ADO读取工作簿工作表数据》读取数据非常快,那么是否可以使用ADO合并工作簿?

ADO合并子文件夹同名工作簿中同名工作表,纵向汇总数据

注意:合并生成结果表格不带格式,公式都读取为值,仅适用表头行1行,仅测试xlsx格式文件合并

vbnet 复制代码
Sub ADO合并子文件夹同名工作簿中同名工作表_纵向汇总数据2()
    '不打卡工作簿方法;最终合并文件以工作簿名命名,适用工作表格式相同;合并文件A列显示原子文件夹名
    Dim dict As Object, fso As Object, old_name As Boolean, write_wb As Workbook, s$, s1$, ss$
    Dim file_path$, save_path$, delimiter$, fd, i&, r&, f, ff, p, pp
    Dim cnn As Object, rs As Object, ex As Object, sqlstr$, fp$, ws, wss
'--------------------参数填写:
    file_path = "E:\测试\拆分表\合并工作簿7\"  'file_path待合并的子文件夹所在文件夹
    save_path = file_path + "合并表\"   '合并后的表格保存路径
    old_name = True    '写入原子文件夹名,是/否
    Application.ScreenUpdating = False  '关闭屏幕更新,加快程序运行
    Application.DisplayAlerts = False   '不显示警告信息
    Set dict = CreateObject("scripting.dictionary"): delimiter = Chr(28)
    Set fso = CreateObject("Scripting.FileSystemObject"): tm = Timer
    If fso.FolderExists(save_path) Then Debug.Print "保存文件夹已存在,会导致错误,请删除": Exit Sub
    For Each f In fso.GetFolder(file_path).SubFolders  '获取所有子文件夹名
        s = s & delimiter & f.Name
    Next
    fd = Split(Mid(s, 2), delimiter)
    If Not fso.FolderExists(save_path) Then fso.CreateFolder (save_path)  '创建文件夹
    Set cnn = CreateObject("ADODB.Connection"): Set rs = CreateObject("ADODB.Recordset")
    For Each p In fd
        For Each f In fso.GetFolder(file_path & p).Files  '空文件夹不影响
            If f.Name Like "*.xlsx" And Not dict.Exists(f.Name) Then
                s = f.Name: Set dict(s) = CreateObject("scripting.dictionary")
                Set write_wb = Workbooks.Add  '新建工作簿,合并文件
                For Each pp In fd  '遍历所有子文件夹同名工作簿
                    For Each ff In fso.GetFolder(file_path & pp).Files
                        If ff.Name = s Then
                            fp = file_path & pp & "\" & s  '文件名含路径
                            cnn.Open "Provider=Microsoft.Ace.OLEDB.12.0;Extended properties='Excel 12.0 Xml;Hdr=yes;IMEX=1';data source=" & fp
                            Set rs = cnn.OpenSchema(20): ss = ""
                            Do Until rs.EOF  '获取所有工作表名称
                                If rs.Fields("TABLE_TYPE") = "TABLE" Then
                                    s1 = Replace(rs("TABLE_NAME").Value, "'", "")
                                    If Right(s1, 1) = "$" Then s1 = Left(s1, Len(s1) - 1): ss = ss & delimiter & s1
                                End If
                                rs.MoveNext
                            Loop
                            rs.Close: wss = Split(Mid(ss, 2), delimiter)  '工作表名称数组
                            For Each ws In wss  '遍历工作表获取数据,并写入
                                sqlstr = "SELECT * FROM [" & ws & "$]"
                                Set ex = cnn.Execute(sqlstr)
                                If Not dict(s).Exists(ws) Then  '工作表不存在
                                    dict(s)(ws) = "": i = 0: ReDim trr(1 To ex.Fields.Count)
                                    For Each x In ex.Fields  '表头
                                        i = i + 1: trr(i) = x.Name
                                    Next
                                    write_wb.Worksheets.Add(after:=Sheets(Sheets.Count)).Name = ws  '最后添加新sheet,并命名
                                    With write_wb.Worksheets(ws)
                                        .[b1].Resize(1, UBound(trr)) = trr
                                        .[b2].CopyFromRecordset ex
                                        .[a1] = "子文件夹": .[a2].Resize(.[b1].End(xlDown).row - 1, 1) = pp
                                    End With
                                Else
                                    With write_wb.Worksheets(ws)
                                        r = .UsedRange.Rows.Count + 1
                                        .Cells(r, 2).CopyFromRecordset ex
                                        .Cells(r, 1).Resize(.[b1].End(xlDown).row - r + 1, 1) = pp
                                    End With
                                End If
                            Next
                            cnn.Close
                        End If
                    Next
                Next
                write_wb.Worksheets(1).Delete  'excel新建wb第1个ws为空表
                If Not old_name Then  '无需写入原子文件夹名
                    For Each sht In write_wb.Worksheets
                        sht.Columns("a:a").Delete
                    Next
                End If
                write_wb.SaveAs filename:=save_path & s
                write_wb.Close (False)
            End If
        Next
    Next
    Set rs = Nothing: Set cnn = Nothing
    Application.ScreenUpdating = True: Application.DisplayAlerts = True
    Debug.Print "文件夹合并完成,用时:" & Format(Timer - tm, "0.00")
End Sub

举例,并与"合并工作簿7"对比

合并与 "合并工作簿7" 举例中同样的数据


共有12个文件夹60个工作簿180个工作表,合并后


运行速度对比

代码版本 合并工作簿7.1 合并工作簿7.2 ADO合并工作簿
耗时秒数 40-60 22.5-29 5.77-6.76

相比 合并工作簿7.2 使用ADO代码行数更少,同时运行速度提升了数倍

相关推荐
星雨流星天的笔记本2 小时前
0.0用excel拆分数据
excel
想你依然心痛12 小时前
用MySQL玩转数据可视化:从SQL查询到动态图表的完整实战
sql·mysql·信息可视化
蓝创工坊Blue Foundry13 小时前
PaddleOCR 本地部署教程:小模型 OCR 如何完成字段提取到 Excel
pdf·自动化·ocr·excel·paddlepaddle·paddle
向夏威夷 梦断明暄14 小时前
基于Tez引擎的 Hive SQL 性能优化
hive·sql·性能优化
wujian831115 小时前
怎么用AI做excel表格 AI导出鸭来救场
人工智能·ai·excel·豆包·deepseek·ai导出鸭
用户2986985301415 小时前
React 前端处理 Excel 工作表复制的技术实践
javascript·react.js·excel
跟着珅聪学java1 天前
MERGE INTO开发教程
sql
这个DBA有点耶1 天前
交易型数据库是什么?OLTP核心能力与2026选型指南
数据库·数据仓库·sql·database·数据库架构·olap·dba
蓝创工坊Blue Foundry1 天前
个人藏书太多怎么整理?用 OCR 字段提取汇总成电子书目
pdf·ocr·excel·文心一言·paddlepaddle·paddle
提笔了无痕1 天前
MySQL SQL 从 EXPLAIN 到索引优化,搞懂 SQL 为什么慢
android·sql·mysql