前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >VBA与数据库——合并表格

VBA与数据库——合并表格

作者头像
xyj
发布于 2021-09-10 06:23:15
发布于 2021-09-10 06:23:15
5K20
代码可运行
举报
文章被收录于专栏:VBA 学习VBA 学习
运行总次数:0
代码可运行

在Excel里,如果需要把多个工作表或者工作簿的数据合并到一起,用VBA来做一个程序还是比较容易的,在多个工作簿合并到一个工作簿多个工作表合并到一个工作表里有过介绍,代码不算很复杂。

如果能保证列的一致性,使用ADO合并也是可以的。

合并主要是要用到union all关键字,如果是合并一个工作簿的工作表,sql语句是比较好写的。如果是是多个工作簿数据源的时候,sql语句的用法:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[Excel 12.0;Database=" & Workbook.FullName & ";].[" & Sheet.Name & "$]

代码的核心就是构建出sql语句,首先遍历一个文件夹,获取到需要处理的Excel文件名称,然后按上面的语法构建sql语句,最后调用ado执行就可以了:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Sub UnionAll()
    Dim strsql As String
    
    strsql = UnionAllExcelSQL(ThisWorkbook.path & "\unionall", "Sheet1")
    
    If VBA.Len(strsql) = 0 Then Exit Sub
    
    Dim AdoConn As Object
    Set AdoConn = VBA.CreateObject("ADODB.Connection")
    
    '打开数据库
    AdoConn.Open "Provider =Microsoft.ACE.OLEDB.12.0;Data Source=" & ThisWorkbook.fullname & ";Extended Properties=""Excel 12.0;HDR=YES"";"
    
    Dim rst As Object
    Set rst = VBA.CreateObject("ADODB.Recordset")
    Set rst = AdoConn.Execute(strsql, , 1)
    '输出标题
    Dim i As Long
    For i = 0 To rst.Fields.Count - 1
        Range("A1").Offset(0, i).Value = rst.Fields(i).name
    Next
    '输出数据
    Range("A2").CopyFromRecordset rst

    rst.Close
    AdoConn.Close
    
    Set rst = Nothing
    Set AdoConn = Nothing
End Sub


Function UnionAllExcelSQL(path As String, shtname As String) As String
    Dim RetDirs() As String, RetFiles() As String
    
    If ScanDir(path, RetDirs, RetFiles) = -1 Then
        UnionAllExcelSQL = ""
        Exit Function
    End If
    
    Dim i As Long
    For i = 0 To UBound(RetFiles)
        '[Excel 12.0;Database=" & ThisWorkbook.FullName & ";].[" & ActiveSheet.Name & "$]
        RetFiles(i) = "select *, '" & GetFileName(RetFiles(i)) & "' as wkname from [Excel 12.0;Database=" & RetFiles(i) & ";].[" & shtname & "$]"
    Next
    
    UnionAllExcelSQL = VBA.Join(RetFiles, " union all ")
End Function

'获取文件名称
Function GetFileName(fullname As String) As String
    Dim i As Long
    
    i = VBA.InStrRev(fullname, "\")
    If i Then
        GetFileName = VBA.Mid$(fullname, i + 1)
    End If
End Function

Function ScanDir(str_dir As String, RetDirs() As String, RetFiles() As String) As Long
    Dim fso As Object
    Dim file As Object
    Dim folder As Object, SubDir As Object
    Dim k As Long
    
    On Error GoTo err_handle
    
    Set fso = CreateObject("Scripting.FileSystemObject")
    Set folder = fso.Getfolder(str_dir)
    
    If folder.Subfolders.Count Then
        ReDim Preserve RetDirs(folder.Subfolders.Count - 1) As String
        k = 0
        For Each SubDir In folder.Subfolders
            RetDirs(k) = SubDir.path
            k = k + 1
        Next
    End If
    
    If folder.Files.Count Then
        ReDim Preserve RetFiles(folder.Files.Count - 1) As String
        k = 0
        For Each file In folder.Files
            RetFiles(k) = file.path
            k = k + 1
        Next
    End If
    
    ScanDir = k
    
    Set file = Nothing
    Set folder = Nothing
    Set fso = Nothing
    Set SubDir = Nothing
    
    Exit Function
    
err_handle:
    ScanDir = -1
    MsgBox Err.Description
End Function

测试:

首先我创建了一个00.xlsx文件,写入了10000行、3列数据,然后复制了另外49个:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Sub CopyWk()
    Dim i As Long
    
    For i = 1 To 49
        VBA.FileCopy ThisWorkbook.path & "\unionall\00.xlsx", ThisWorkbook.path & "\unionall\" & VBA.Format(i, "00") & ".xlsx"
    Next
End Sub

在我电脑上进行了如下测试:

大于50个文件之后,提示:

我首先想到可能是sql语句太长了,于是把程序文件和测试文件夹unionall放到了E盘根目录,这样至少路径短了,sql语句也就短了,测试结果仍然是不能超过50个!

具体原因还不知道!如果有清楚的请指点一下。

另外在我电脑测试,普通的vba逐个打开工作簿,复制单元格内容的程序竟然比调用ado要快!这个倒是始料未及啊?

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-08-30,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 VBA 学习 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
2 条评论
热度
最新
字段格式怎么处理的?日期、时间、长数字等
字段格式怎么处理的?日期、时间、长数字等
11点赞举报
这个只是复制数据,不涉及处理数据,字段格式没什么影响
这个只是复制数据,不涉及处理数据,字段格式没什么影响
回复回复点赞举报
推荐阅读
编辑精选文章
换一批
VBA与数据库——排列组合(可重复)
在VBA实现排列组合(可重复)中使用普通的VBA编程方法,实现了排列组合(可重复),代码虽然不是很多,但作为初学者需要理解还是有一定难度的。
xyj
2021/10/20
1.2K0
创建MyVBA加载宏
MyVBA加载宏主要功能是设置为自动加载,作为打开其他宏文件的一个程序,做好后大概是这么一个东西:
xyj
2020/07/28
1.1K0
创建MyVBA加载宏
VBA与数据库——简化程序编写-查找
比较简单的一段代码,和汇总数据一样,这里只是按照一个条件进行查找,需要按照2个甚至多个条件来查找的时候,需要改动的代码有:
xyj
2021/07/20
9620
VBA与数据库——简化程序编写-汇总
我们在使用VBA处理Excel数据的时候,很多时候就是对数据进行分类汇总、查找等等。一般这种功能都是使用字典来实现,比如汇总数据功能。
xyj
2021/06/22
1.3K0
VBA与数据库——简化程序编写-汇总
VBA与数据库——简化程序编写-去重
代码和汇总、查找数据等一样,仅仅是修改了sql语句,相比使用字典,代码更加的简单,在需要更换去重字段条件的时候,也更加的方便。
xyj
2021/08/13
1.6K2
VBA与数据库——简化程序编写-排序
在Excel里对数据排序是非常简单的一个操作,只需要选中数据,点击菜单-数据-排序,然后选择相应的字段和排序方式即可。
xyj
2021/07/20
1.2K0
VBA与数据库——写个类操作ADO_操作数据库
操作数据库有增加、修改、删除、查询记录等,在前面的例子中,用的基本都是查询,这种是需要得到结果数据的,另外几种是修改数据库里的数据,很多时候是不需要返回数据的。
xyj
2021/11/12
1.2K0
VBA与数据库——合并表格并删除重复
在前面合并表格里提到,用union all关键字进行合并数据,union all只是简单的将所有的数据进行复制到一起,不做其他的处理。
xyj
2021/09/10
4.7K3
VBA与数据库——合并表格并删除重复
VBA与数据库——简化程序编写-一维表转二维表
在一维表转二维表里介绍了使用字典来转换表格的方法,可以看到使用字典的方法代码量还是有一点多的,有点复杂。
xyj
2021/07/20
8510
VBA与数据库——获取第一条查找记录
在简化程序编写-查找里,已经介绍过了查找数据的方法,里面演示的数据非常简单,数据源是没有重复的。
xyj
2021/10/08
1.9K0
VBA与数据库——获取第一条查找记录
VBA与数据库——Excel
一说到数据库,一般都会想到那些很专业的数据库,其实Excel本身也可以作为数据库来使用。
xyj
2021/04/26
2.7K0
VBA与数据库——Excel
VBA与数据库——简化程序编写-拼接表格
需要实现这个功能,在VBA里首先想到的应该还是字典,首先将表格2中的字段对应关系记录到字典,然后在表格1基础上增加一列,遍历表格1,利用字典将字段A对应的字段C读取出来即可。
xyj
2021/08/13
1.5K0
VBA与数据库——简化程序编写-筛选
要对Excel数据进行筛选,最容易想到的方法自然是Excel本身的数据-筛选功能,但是如果是要在VBA中对数据进行筛选,那么一般的做法是对数据进行循环遍历,把符合条件的数据提取出来,假如数据是这样的:
xyj
2021/07/20
1.1K0
ExcelVBA-ADO-SQL-001连接数据库
Excel 2003 Excel 2007 Excel 2010 Excel 2013
哆哆Excel
2022/10/25
2.1K0
ExcelVBA-ADO-SQL-001连接数据库
VBA汇总多个Excel文件数据
将某个文件夹下,所有Excel文件及子文件夹下的Excel文件内容,复制到一张汇总表。
xyj
2020/07/28
2.7K0
VBA汇总多个Excel文件数据
VBA-ADO-SQL-002单条件查询语句
输入“工号 姓名 性别 年龄 部门 工资 奖金”
哆哆Excel
2022/10/25
7110
VBA-ADO-SQL-002单条件查询语句
VBA创建多个数据源的数据透视表
比如要分析工资的数据,工资表是按月分了不同Sheet管理的,现在需要把12个月的数据放到一起创建1个数据透视表。
xyj
2020/07/28
3.5K0
VBA创建多个数据源的数据透视表
ExcelVBA-ADO-SQL-003多条件组合查询(模糊查询)
假如现在有一个提交表单,里面是N个查询的条件(工号、姓名、性别、年龄、部门、工资、奖金)用户可以只填写其中的几个条件来进行查询。(也可以不填写条件)
哆哆Excel
2022/10/25
2.8K0
ExcelVBA-ADO-SQL-003多条件组合查询(模糊查询)
VBA与数据库——写个类操作ADO_打开数据库
在前面介绍的一些操作数据库的代码中,可以看到,主要的操作逻辑基本上是打开数据库-操作-关闭数据库,很多时候改变的仅仅是操作,所以,把这些封装到一个类里面,以后调用自己写的类就会更方便。
xyj
2021/11/12
2.9K0
VBA与数据库——写个类操作ADO_打开数据库
VBA调用外部对象02:FileSystemObject——其他函数
fso.GetFileName这个功能在需要判断文件名称是否符合某个条件的时候用的还是比较多的,如果要自己去处理,用VBA Strings模块下的Left、Right、Mid函数等也是可以的。
xyj
2020/07/28
1.7K0
相关推荐
VBA与数据库——排列组合(可重复)
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档