ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

搜索
EH技术汇-专业的职场技能充电站 妙哉!函数段子手趣味讲函数 Excel服务器-会Excel,做管理系统 效率神器,一键搞定繁琐工作
HR薪酬管理数字化实战 Excel 2021函数公式学习大典 Excel数据透视表实战秘技 打造核心竞争力的职场宝典
让更多数据处理,一键完成 数据工作者的案头书 免费直播课集锦 ExcelHome出品 - VBA代码宝免费下载
用ChatGPT与VBA一键搞定Excel WPS表格从入门到精通 Excel VBA经典代码实践指南
查看: 3441|回复: 11

[求助] 多表汇总求提速

[复制链接]

TA的精华主题

TA的得分主题

发表于 2016-1-31 00:11 | 显示全部楼层 |阅读模式
多张工作表,格式为.xlsm,带宏的,每张表中有个名为数据库的工作表,位置为当前文件夹以及子文件夹,现用代码为SQL语句

Function fld(Path As String)
    Dim Fso As Object
    Dim f As Object
    Dim fd As Object
    Dim subf As Object
    Set Fso = CreateObject("scripting.FileSystemObject")
    Set fd = Fso.GetFolder(Path)
        For Each f In fd.Files
         l = l + 1
        ReDim Preserve arr(1 To l)
        arr(l) = f.Path
    Next
        For Each subf In fd.SubFolders
        fld (subf.Path)
    Next
End Function
Sub 汇总文件夹以及子文件夹()
t = Timer - t
Application.ScreenUpdating = False
On Error Resume Next
Dim mySQL As String
Dim mycnn
Dim f As String
Dim File() As String
Dim i, k, x
x = 1
i = 1: k = 1
ReDim File(1 To i)
File(1) = ActiveWorkbook.Path & "\"
Do Until i > k
    f = Dir(File(i), vbDirectory)
        Do Until f = ""
            If InStr(f, ".") = 0 Then
                k = k + 1
                ReDim Preserve File(1 To k)
                File(k) = File(i) & f & "\"
            End If
            f = Dir
        Loop
    i = i + 1
Loop
For i = 1 To k
    f = Dir(File(i) & "*.xlsm")
Do
        Set mycnn = CreateObject("adodb.connection")
        If f <> ThisWorkbook.Name Then
            mycnn.Open "Provider=Microsoft.Ace.OLEDB.12.0;Extended Properties=excel 12.0;Data Source=" & File(i) & f & ""
            mySQL = "select * from [数据库$]"
            Range("A65536").End(xlUp).Offset(1, 0).CopyFromRecordset mycnn.Execute(mySQL)
        End If
       Set mycnn = Nothing
       f = Dir
    Loop While Len(f) And f <> ThisWorkbook.Name
Next
Application.ScreenUpdating = True
MsgBox Timer - t
End Sub



速度还是不尽人意,在此请求老师支招感激不尽

求提速.7z

249.58 KB, 下载次数: 70

TA的精华主题

TA的得分主题

 楼主| 发表于 2016-1-31 00:14 | 显示全部楼层
不知道有没有更快的汇总办法

TA的精华主题

TA的得分主题

发表于 2016-1-31 00:36 | 显示全部楼层
提速一倍多一点,不是很理想:
  1. Sub Macro1()
  2. t = Timer
  3.     Dim Fso As Object, Folder As Object, arr$(), m&, i&, p$
  4.     Application.ScreenUpdating = False
  5.     Set Fso = CreateObject("Scripting.FileSystemObject")
  6.     Set Folder = Fso.GetFolder(ThisWorkbook.Path)
  7.     Call GetFiles(Folder, arr, m)
  8.     Set mycnn = CreateObject("adodb.connection")
  9.     mycnn.Open "Provider=Microsoft.Ace.OLEDB.12.0;Extended Properties=excel 12.0;Data Source=" & arr(1)
  10.     ActiveSheet.UsedRange.Offset(1).ClearContents
  11.     For i = 1 To m
  12.         mySQL = "select * from [Excel 12.0;Database=" & arr(i) & "].[数据库$]"
  13.         Range("A65536").End(xlUp).Offset(1, 0).CopyFromRecordset mycnn.Execute(mySQL)
  14.     Next
  15.     Application.ScreenUpdating = True
  16.     Set Folder = Nothing
  17.     Set Fso = Nothing
  18.     MsgBox Timer - t
  19. End Sub

  20. Sub GetFiles(ByVal Folder As Object, arr$(), m&)
  21.     Dim SubFolder As Object
  22.     Dim File As Object
  23.     If Folder.Path <> ThisWorkbook.Path Then
  24.         For Each File In Folder.Files
  25.             If File.Name Like "*.xls*" Then
  26.                 m = m + 1
  27.                 ReDim Preserve arr(1 To m)
  28.                 arr(m) = File
  29.             End If
  30.         Next
  31.     End If
  32.     For Each SubFolder In Folder.SubFolders
  33.         Call GetFiles(SubFolder, arr, m)
  34.     Next
  35. End Sub
复制代码

评分

2

查看全部评分

TA的精华主题

TA的得分主题

 楼主| 发表于 2016-1-31 07:25 来自手机 | 显示全部楼层

TA的精华主题

TA的得分主题

 楼主| 发表于 2016-1-31 07:27 来自手机 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
zhaogang1960 发表于 2016-1-31 00:36
提速一倍多一点,不是很理想:

字典是不是更快,求告知,或者有别的办法呢

TA的精华主题

TA的得分主题

发表于 2016-1-31 10:31 | 显示全部楼层
朝旭暮阳 发表于 2016-1-31 07:27
字典是不是更快,求告知,或者有别的办法呢

本题目仅合并数据,与字典无关,速度慢主要原因是待合并文件太多(492个),我认为没有比SQL法速度快的其他方法了,如果采用逐个打开复制数据,或写入数组,用时应该超过10分钟

TA的精华主题

TA的得分主题

发表于 2016-1-31 12:06 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
zhaogang1960 发表于 2016-1-31 10:31
本题目仅合并数据,与字典无关,速度慢主要原因是待合并文件太多(492个),我认为没有比SQL法速度快的其 ...

虽然比不上SQL,但是也不至于需要十分钟如此不堪吧。简单测试了下不到一分钟。
普通方法耗时主要是打开和关闭文件。

TA的精华主题

TA的得分主题

发表于 2016-1-31 12:25 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
crazy0qwer 发表于 2016-1-31 12:06
虽然比不上SQL,但是也不至于需要十分钟如此不堪吧。简单测试了下不到一分钟。
普通方法耗时主要是打开 ...

我估计的有点过,经测试下面程序运行259秒,我改写的SQL法为18秒:

Sub Macro1()
t = Timer
    Dim Fso As Object, Folder As Object, arr$(), m&, i&, sh As Worksheet
    Application.ScreenUpdating = False
    Set sh = ActiveSheet
    Set Fso = CreateObject("Scripting.FileSystemObject")
    Set Folder = Fso.GetFolder(ThisWorkbook.Path)
    Call GetFiles(Folder, arr, m)
    ActiveSheet.UsedRange.Offset(1).ClearContents
    For i = 1 To m
        With GetObject(arr(i))
            .Sheets("数据库").UsedRange.Offset(1).Copy sh.Range("A65536").End(xlUp).Offset(1)
            .Close 0
        End With
    Next
    Application.ScreenUpdating = True
    Set Folder = Nothing
    Set Fso = Nothing
    MsgBox Timer - t
End Sub

Sub GetFiles(ByVal Folder As Object, arr$(), m&)
    Dim SubFolder As Object
    Dim File As Object
    If Folder.Path <> ThisWorkbook.Path Then
        For Each File In Folder.Files
            If File.Name Like "*.xls*" Then
                m = m + 1
                ReDim Preserve arr(1 To m)
                arr(m) = File
            End If
        Next
    End If
    For Each SubFolder In Folder.SubFolders
        Call GetFiles(SubFolder, arr, m)
    Next
End Sub



你的打开、关闭算法速度快,请传上来分享一下

评分

1

查看全部评分

TA的精华主题

TA的得分主题

发表于 2016-1-31 12:48 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
zhaogang1960 发表于 2016-1-31 12:25
我估计的有点过,经测试下面程序运行259秒,我改写的SQL法为18秒:

Sub Macro1()

如果楼主的数据是CSV文件的话还有办法,XLSM 就没办法了,普通方法只能在excel打开。

我用您SQL方法时间是 6.8 S ,而我的代码时间是 56.9 将近十倍。
而用您8楼getobject 方法时间为 109.2 。

之前我也有测试过 getobject ,不过这样打开反而比关闭屏幕更新后的workbooks.open要慢得多,我想也许是这个方法需要匹配文件的类型,才能选择对应的程序来打开,最终也还是需要用excel来打开,所以速度慢很多。

附我的代码,比一般多做了一步:禁用宏的方式打开工作簿,避免因为工作簿中open过程的宏影响。

  1. Sub Macro1()
  2. t = Timer
  3.     Dim Fso As Object, Folder As Object, arr$(), m&, i&, p$
  4.     Application.ScreenUpdating = False
  5.     Application.DisplayAlerts = False
  6.     x = Application.AutomationSecurity
  7.     Application.AutomationSecurity = msoAutomationSecurityForceDisable
  8.    Set Fso = CreateObject("Scripting.FileSystemObject")
  9.     Set Folder = Fso.GetFolder(ThisWorkbook.Path)
  10.     Call GetFiles(Folder, arr, m)
  11.     Sheet2.UsedRange.Offset(1).ClearContents
  12.     n = 2
  13.     For i = 2 To m
  14.         With Workbooks.Open(arr(i), False)
  15.             .Sheets("数据库").Range("a1").CurrentRegion.Offset(1).Copy Sheet2.Range("A1048576").End(xlUp).Offset(1)
  16.             n = n + UBound(arr) - 1
  17.             .Close False
  18.         End With
  19.     Next
  20.     Application.ScreenUpdating = True
  21.     Application.AutomationSecurity = x
  22.     Set Folder = Nothing
  23.     Set Fso = Nothing
  24.     Debug.Print Timer - t
  25. End Sub
复制代码

TA的精华主题

TA的得分主题

发表于 2016-1-31 13:04 | 显示全部楼层
crazy0qwer 发表于 2016-1-31 12:48
如果楼主的数据是CSV文件的话还有办法,XLSM 就没办法了,普通方法只能在excel打开。

我用您SQL方法时 ...

谢谢。
看来我和楼主一样,电脑配置太差了,如果楼主的电脑中SQL方法也是6.8 S,应该很满意了,复制492个工作簿的数据工作量不小
您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

手机版|关于我们|联系我们|ExcelHome

GMT+8, 2025-1-9 15:38 , Processed in 0.029361 second(s), 15 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

沪公网安备 31011702000001号 沪ICP备11019229号-2

本论坛言论纯属发表者个人意见,任何违反国家相关法律的言论,本站将协助国家相关部门追究发言者责任!     本站特聘法律顾问:李志群律师

快速回复 返回顶部 返回列表