VBA操作数据库

本文介绍了如何在Excel中使用VBA和Python进行SQL查询,包括数据库连接设置(如MicrosoftJet和ACEOLEDB),创建Recordset对象执行SQL操作,以及如何配置Schema.ini处理文本文件数据。还涵盖了分页控件和窗体应用实例。

相关背景

对于数据分析同学,一般SQL,EXCEL是必备技能,但对于VBA和Python可能有的同学不会;在处理本地数据上(诸如excel、txt|csv文本);

excel简易sql查询插件,可转:https://blog.youkuaiyun.com/me_to_007/article/details/130417173

相关配置

转载自蓝色幻想

'一、Connection对象
  '1 建立和数据库的连接
    '.Open
   ' Dim con As New Connection
   ' Set con = CreateObject("ADODB.Connection")    
   ' con.Open "provider=microsoft.jet.oledb.4.0;extended properties=excel 8.0;data source=" & ThisWorkbook.Path & "/Database/exceldata.xls"
   
	 ' 数据连接
	 ' con.Open "Provider=Microsoft.ace.Oledb.12.0;" _
	    & "Extended Properties=Excel 12.0;" _
	    & "Data Source=" & ThisWorkbook.FullName
    
      'Conn.Open:打开数据库的连接
      'provider=microsoft.jet.oledb.4.0 数据库引擎版本,该引擎主要用于excel2003;Provider=Microsoft.ace.Oledb.12.0;用于excel2007及以上版本
      'extended properties=excel 8.0 连接的是Excel8.0版本(excel2000以后的版本),Excel不是标准的数据库格式,所以要设置扩展属性
      'data source=" & ThisWorkbook.Path & "/数据库.xls" 数据库路径
      
   '************以下是连接其他数据库或文件的字符串表达式*********************************
        '1 Mysql数据库
            'strDriver = "Provider=SQLOLEDB;DataSource=" & Path & ";Initial Catolog=" & strDataName
        '2 TXT文件
            'strDriver = "Provider=Microsoft.Jet.OLEDB.4.0;Extended Properties='text;IMEX=1;HDR=NO;FMT=Delimited;';Data Source=" & Path
        '3 MSSQL数据库
            'strDriver = "Provider=MSDASQL;Driver={SQL Server};Server=" & Path & ";Database=" & strDataName
        '4 Oracle数据库
             'strDriver= "Provider=madaora;Data Source=MyOracleDB; User Id=UserID; Password=Password"

  '2 执行sql语句
    '.Execute SQL
    '增加新表格:.Execute "Create 表格名 字段和属性"
    '增加新记录:.Execute "Insert into 表名 (字段1, 字段2,... 字段n) VALUES(值1,值2,... 值n)"
    '删除记录:  .Execute "Delete from 表名 where 条件
    '修改旧记录:.Execute "Update 表名称 SET 列1 = 新值,列2=新值 WHERE 列名称 = 某值
    '筛选记录:   .Execute "Select 字段 from 表 where 条件
           
'二、Recordset对象
  '作用 打开记录集操作记录
    '1 打开游标(记录集)
       'rst.Open sql或command语句等,已打开的conn链接,
       ' Set rst = CreateObject("ADODB.Recordset")
    '2 添加新记录
       'AddNew 单个字段或数组,单个值或数组
       
       '或
       
'       rst.AddNew '添加新的记录
'       rst.Fields("姓名") = "伍天明" 'Fields("字段名")表示某列的记录
'       rst.Fields("年龄") = 28
'       rst.Fields("性别") = "男"
'       rst.Update '添加记录后要更新
    '3 修改记录
       'rst.Update 字段数组, 值或数组
    '4 删除记录
       'rst.delete
    '5 在记录中循环
       'BOF 在记录的最前面
       'EOF 在记录的结尾
       'GetRows(默认值-1,Start, 字段)'Start 0从当前记录开始,1从第一条记录,2从最后一条记录开始

一般操作步骤

在这里插入图片描述

if con.State=ADODB.ObjectStateEnum.adStateOpen then "连接成功" 可用来判断数据库链接是否成功

ActiveSheet.Range("A2").CopyFromRecordset rst 可以把返回的数据集写到活动工作表里

rst.Open query_sql, con, 1, 1执行sql查询

rst.recordcount是查询结果记录行数,可以用来判断SQL是否有返回记录行;

写入表头

With ActiveSheet
    cols = rs.Fields.Count
    For i = 0 To cols - 1
        .Cells(1, i + 1).Value = rs.Fields(i).Name  ' 写入表头
    Next
    .Cells(2, 1).CopyFromRecordset rs    ' 数据写入
End With

用来判断rst是否成功返回
if rst.State=ADODB.ObjectStateEnum.adStateOpen then msgbox "rst.open 成功返回"

关于数据库引擎与连接串

' provider=microsoft.jet.oledb.4.0 数据库引擎版本,该引擎主要用于excel2003,wps使用该引擎;
' Provider=Microsoft.ace.Oledb.12.0;用于excel2007及以上版本

关闭链接对象和记录集

Set con = Nothing
Set rs = Nothing

本地查询sql样例:

select t2.group,sum(t1.销售额) as sales 
from [Sheet1$] as t1 
inner join [分组$c4:d7] as t2 
on t1.姓名=t2.姓名 
where date_field<#2023/4/24# 
group by t2.group

如果是读取文本文件,诸如txt,csv,链接串后面的路径只需填写txt文本所在目录;,比如:F:\桌面\;同一个目录下的不同文本文件可以关联查询;

strDriver = "Provider=Microsoft.Jet.OLEDB.4.0;Extended Properties=""text;IMEX=1;HDR=Yes;FMT=Delimited(,)"";Data Source=F:\桌面\" 

其中:HDR=Yes表示文件包含表头;HDR=No表示文件不包含表头

文本分隔符不生效的问题

解决方法:在文本文件目录下配置schema.ini文件(同一目录);

参考来源:https://www.cnblogs.com/zyizyizyi/archive/2011/10/10/2497832.html

这里可以使用文本框控件让用户填写分隔符,然后使用代码在文本目录下生成该配置文件,再创建链接;

如未配置,如果是访问txt文本,delimited指定其他分隔符,不生效的,还是读成了英文逗号;

Schema.ini配置格式大概格式如下:把注释和不必要的属性删了,第一行未文件名,用中括号括起来;

[Contacts.txt] ///需要导入的文本文件名
ColNameHeader=True ///是否有数据头
Format=FixedLength ///字段固定长度
MaxScanRows=0 ///最多导入行
CharacterSet=OEM ///字符集
Col1="First Name" Char Width 10 ///第一列格式
Col2="Last Name" Char Width 9 ///第二列格式
Col3="HireDate" Date Width 8 ///第三列格式

Schema.ini用于提供文本数据中的记录规格信息。每个Schema.ini的条目用于指明表的5个特征之一:

文本文件名
文件名有方括号括起来,例如如果要对Sample.txt使用Schema,那么它的对应的Schema条目应该是[Sample.txt]

文件格式指令如下:
Format=Value,Value可以取下面的值之一:
TabDelimited 用Tab分隔
CSVDelimited 用逗号分隔
FixedLength 固定长度
Delimited(C) 指定字符,其中C可以为除了双引号(")外的任何字符,也可以为空

字段名、字段宽度和类型
格式为:Coln=字段名 数据类型 [width 宽度]
字段名可以是任意字符,如果字段名包含空格,请使用双引号括起来。

数据类型可以为:Bit,Byte,Short(Integer),Long,Currency,Single,Double(Float),DateTime(Date DateFormat),Text(Char),Memo(LongChar)
其中DateFormat是日期的格式字符串例如:Date YYYY-MM-DD

字符集
格式:CharacterSet=ANSI | OEM
格式只有两种:ANSI和OEM

竖杠分隔测试:

Sub sql_query()
Dim con, rs As Object
Dim query_sql, str As String
Dim i, cols As Long

' 创建对象
Set con = CreateObject("ADODB.Connection")
Set rs = CreateObject("ADODB.Recordset")


str = "Provider=Microsoft.ace.Oledb.12.0;Extended Properties=""text;HDR=Yes;FMT=Delimited(|)"";Data Source=C:\Users\yinrong\Desktop\"

    
' 数据连接
con.Open str

query_sql = "select * from [test.txt] where age>20"
' 执行sql语句
rs.Open query_sql, con, 1, 1

' 数据写入
Worksheets.Add    ' 新建工作表
With ActiveSheet
    cols = rs.Fields.Count
    For i = 0 To cols - 1
        .Cells(1, i + 1).Value = rs.Fields(i).Name  ' 写入表头
    Next
    .Cells(2, 1).CopyFromRecordset rs    ' 数据写入
End With

rs.Close
con.Close
Set con = Nothing

End Sub

schema.ini文件配置如下:不必要的属性配置删除(我这里抛出了异常)

[test.txt]
Format=Delimited(|)
CharacterSet=OEM

配置文件与文本在同一目录下
在这里插入图片描述

如果是配置多个文件的schema,直接在该文件标识即可;比如test.txt文件是以|分隔的;test1.txt以-分隔;配置文件如下:

[test.txt]
Format=Delimited(|)
CharacterSet=OEM

[test1.txt]
Format=Delimited(-)
CharacterSet=OEM

写sql时,txt文件名即表名,sql样例如下(文本文件名为:test.txt):
select * from [test.txt] where age>20

窗体控件相关

公司闲暇时间做了一版,大概样式(文件没法外发),执行结果分页,使用列表控件展示结果:

在这里插入图片描述

在插件自定义功能区设置按钮,点击按钮加载该窗体;

UserForm1.show(0)是非模态显示窗体,在展示窗体后可以同时操作工作簿;

UserForm1.show(1)显示窗体后,无法操作工作簿;

分页控件通过设置value属性,展示对应对应页面;UserForm1.MultiPage1.Value = 0表示显示第一个page页面;

其他就是一些控件属性设置,事件动作,异常逻辑等,整体上比较简单;

SQL相关函数

聚合函数基本同其他数据库一致,其他函数有些区别,有些SQL函数可能不适用;

在这里插入图片描述

1-1 利用DAO创建数据库和数据表 7 1-2 利用ADOX创建数据库和数据表: 8 1-3 利用SQL语句创建数据库和数据表 9 1-4 在已有的数据库中创建数据表(DAO) 10 1-5 在已有的数据库中创建数据表(ADOX) 12 1-6 在已有的数据库中创建数据表(SQL,Command对象) 13 1-7 在已有的数据库中创建数据表(SQL,Recordset对象) 13 1-8 利用Access对象创建数据库和数据表 14 1-8-1 不引用Access对象库而使用Access的有关对象、属性和方法 16 1-9 利用Access对象在已有的数据库中创建数据表 17 1-10 利用工作表数据创建数据表(ADOX) 18 1-11 利用工作表数据创建数据表(ADO+SQL) 21 1-12 利用工作表数据创建数据表(DAO) 23 1-13 利用已有的数据表创建新数据表(ADO) 25 1-14 利用已有的数据表创建新数据表(DAO) 27 1-15 利用已有的数据表创建新数据表(Access)(前绑定方法引用Access对象库) 28 2-1 检查数据表是否存在(ADO) 28 •实例2-2 检查数据表是否存在(ADOX) 32 •实例2-3 检查数据表是否存在(DAO) 33 •实例2-4 检查数据表是否存在(Access) 33 •实例2-5 获取数据库中所有表的名称和类型(ADO) 34 •实例2-6 获取数据库中所有表的名称和类型(ADOX) 35 •实例2-8 获取数据库中所有数据表名称(ADO) 36 •实例2-9 获取数据库中所有数据表名称(ADOX) 37 •实例2-10 获取数据库中所有数据表名称(DAO) 37 •实例2-11 获取数据库中所有数据表名称(Access) 38 •实例2-12 检查某字段是否存在(ADO) 39 •实例2-13 检查某字段是否存在(ADOX) 40 •实例2-14 检查某字段是否存在(DAO) 41 •实例2-15 检查某字段是否存在(Access) 41 •实例2-16 获取数据库中某数据表的所有字段信息(ADO) 42 •实例2-17 获取数据库中某数据表的所有字段信息(ADOX) 44 •实例2-18 获取数据库中某数据表的所有字段信息(DAO) 45 •实例2-19 获取数据库中某数据表的所有字段信息(Access) 47 •实例2-20 获取数据库的所有查询信息(ADOX) 48 •实例2-21 获取数据库的所有查询信息(DAO) 49 •实例2-22 获取数据库的模式信息(openschema) 50 •实例2-23 获取表的创建日期和最后更新日期(ADOX) 51 •实例2-24 获取表的创建日期和最后更新日期(DAO) 52 •实例3-1 将数据库记录数据全部导入到excel工作表(ADO,之一) 53 •实例3-2 将数据库记录数据全部导入到excel工作表(ADO,之二) 54 •实例3-3 将数据库记录数据全部导入到Excel工作表(ADO,之三) 55 •实例3-4 将数据库记录数据全部导入到Excel工作表(DAO,之一) 56 •实例3-5 将数据库记录数据全部导入到Excel工作表(DAO,之二) 57 •实例3-6 将数据库记录数据全部导入到Excel工作表(QueryTable集合) 58 •实例3-7 将数据库的某些字段的记录数据导入到Excel工作表(ADO) 59 •实例3-8 将数据库的某些字段记录数据导入到Excel工作表(DAO) 60 •实例3-9 查询前面的若干条记录(全部字段)(TOP) 61 •实例3-10 查询前面的若干条记录(部分字段)(TOP) 62 •实例3-11 查询不重复的字段记录(DISTINCT) 63 •实例3-12 利用Like运算符进行模糊查询 64 •实例3-13 查询某一区间内的记录(BETWEEN) 65 •实例3-14 查询存在于某个集合里面的记录(IN) 67 •实例3-15 将查询结果进行排序(ORDER BY) 68 •实例3-16 进行复杂条件的查询(WHERE) 69 •实例3-17 利用合计函数进行查询(查询最大值和最小值) 70 •实例3-18 利用合计函数进行查询(查询合计值和平均值) 71 •实例3-19 将一个查询结果作为查询条件进行查询 72 •实例3-20 将查询结果进行分组(GROUP BY) 73 •实例3-21 查询结果进行分组(HAVING) 74 •实例3-22 通过计算列进行查询 76 •实例3-23 使用IS NULL运算符进行查询 77 •实例3-24 使用COUNT函数进行查询 78 •实例3-25 使用FIRST函数与LAST函数查询第一条记录和最后一条记录的字段 78 •实例3-26 使用Parameters参数动态查询记录(DAO)指定单个参数 79 •实例3-27 使用parameters参数动态查询记录(DAO):指定多个参数 80 •实例3-28 使用parameters参数动态查询记录(ADO):指定单个参数 81 •实例3-29 使用Parameters参数动态查询记录(ADO):指定多个参数 83 •实例3-30 使用别名查询数据库 84 •实例3-31 将查询结果作为窗体控件的源数据 85 •实例3-32 通过窗体控件查询浏览数据库记录 88 •实例3-33 多表查询(WHERE连接) 98 •实例3-34 多表查询(内连接INNER JOINT) 99 •实例3-35 多表查询(左外连接LEFT OUTER JOINT) 101 •实例3-36 多表查询(右外连接 RIGHT OUTER JOINT) 102 •实例3-37 多表查询(子查询WHERE,ANY,SOME) 103 •实例3-38 多表查询(子查询EXISTS,NOT EXISTS) 105 •实例3-39 从两个数据表中查询出都存在的记录 106 •实例3-40 从两个数据表中查询出只存在于某个数据表的记录 108 •实例3-41 将查询结果生成一个数据表 108 •实例3-42 将查询结果保存为一个XML文件 109 •实例3-43 利用工作表实现记录的分页显示 110 •实例3-44 利用窗体实现记录的分页显示 113 •实例4-1 添加新记录(ADO+addnew) 116 •实例4-2 添加新记录(ADO+SQL) 117 •实例4-3 添加新记录(DAO+addnew) 118 •实例4-4 添加新记录(DAO+SQL) 118 •实例4-5 添加新记录(Access+SQL) 119 •实例4-6 修改更新特定记录(ADO+SQL) 120 •实例4-7 修改更新特定记录(DAO+SQL) 120 •实例4-8 修改更新特定记录(Access+SQL) 121 •实例4-9 修改更新全部记录(ADO+SQL) 121 •实例4-10 修改更新全部记录(DAO+SQL) 122 •实例4-11 修改更新全部记录(Access+SQL) 122 •实例4-12 删除特定记录(ADO+SQL) 123 •实例4-13 删除特定记录(DAO+SQL) 124 •实例4-14 删除特定记录(Acess+SQL) 124 •实例4-15 删除全部记录(ADO+SQL) 124 •实例4-16 删除全部记录(DAO+SQL) 125 •实例4-17 删除全部记录(Access+SQL) 125 •实例4-18 通过窗体编辑记录 126 •实例5-1 将整个工作表数据都保存为新的Access数据库(Access) 128 •实例5-2 将工作表的某些区域数据保存为新Access数据库(Access) 129 •实例5-3 将工作簿的所有工作表数据分别保存为不同的数据表(Access) 130 •实例5-4 将多个工作簿的某个工作表数据汇总为新Access数据库(Access) 131 •实例5-5将多个工作簿的某个工作表数据保存为不同的数据表(Access) 132 •实例5-6 将工作表数据保存到已有的Access数据库(循环方式)(ADO) 134 •实例5-7 将工作表数据保存到已有的Access数据库(循环方式)(DAO) 136 •实例5-8 将工作表数据保存到已有的Access数据库(数组方式)(ADO) 138 •实例5-9 将工作表数据保存到已有的Access数据库(数组方式)(DAO) 139 •实例5-10 将工作簿的所有工作表数据分别保存为不同的数据表(ADO) 141 •实例5-11 将工作簿的所有工作表数据分别保存为不同的数据表(DAO) 142 •实例6-1 打开数据库和数据表(Getobject函数) 144 •实例6-2 打开数据库和数据表(createobject函数) 145 •实例6-3 删除数据表(ADO) 145 •实例6-4 删除数据表(ADOX) 146 •实例6-5 删除数据表(DAO+DELETE) 147 •实例6-6 删除数据表(DAO+SQL) 147 •实例6-7 删除数据表(Access) 148 •实例6-8 为数据表增加字段(ADO) 148 •实例6-9 为数据表增加字段(ADOX) 149 •实例6-10 为数据表增加字段(DAO) 150 •实例6-11 为数据表增加字段(Access) 151 •实例6-12 删除字段(ADO) 152 •实例6-13 删除字段(ADOX) 153 •实例6-14 删除字段(DAO) 154 •实例6-15 删除字段(Access) 155 •实例6-16 改变字段的类型(ADO) 157 •实例6-17 改变字段的类型(DAO) 157 •实例6-18 改变字段的类型(Access) 158 •实例6-19 改变字段的长度(ADO) 158 •实例6-20 改变字段的长度(DAO) 159 •实例6-21 改变字段的长度(Access) 159 •实例6-22 重命名数据表(Access) 159 •实例6-23 复制数据表(Access) 160 •实例6-24 复制数据表(ADO) 161 •实例6-25 复制数据表(DAO) 162 •实例6-26 通过窗体维护数据库 162 •实例7-1 判断SQL Server数据库是否存在(ADO) 172 •实例7-2 检查数据表是否存在(ADOX) 173 •实例7-3 创建新的SQL Server数据库和数据表(ADO) 174 •实例7-4 在已有的SQL Servre数据库中创建数据表(ADO) 175 •实例7-5 从SQL Server数据库服务器中删除数据库(ADO) 176 •实例7-6 从SQL Server数据库中删除数据表(ADO) 177 •实例7-7 将SQL Server数据库中的数据导入到Excel工作表(ADO) 177 •实例7-8 将SQL Server数据库中的数据导入到Excel工作表(DAO) 178 •实例7-9 查询获取SQL Server数据库的数据(ADO) 180 •实例7-10 查询获取SQL Server数据库的数据(DAO) 181 •实例7-11 将工作表数据导入到SQL Server数据库(ADO) 182 •实例7-12 向SQL Server数据库中添加记录的一般方法 183 •实例7-13 将SQL Server数据库转换为Access数据库 184 •实例7-14 将access数据库转换为SQL Server数据库 185 •实例8-1 将FoxPro数据库全部数据导入到Excel工作表 187 •实例8-2 查询获取FoxPro数据库数据 188 •实例8-3 将excel工作表数据保存到FoxPro数据库 189 •实例8-4 判断FoxPro数据库的字段是否存在 190 •实例8-5 获取FoxPro数据库的字段信息 190 •实例9-1 从工作簿的某个工作表中查询获取数据(ADO) 192 •实例9-2 从工作簿的全部工作表中查询获取数据(ADO) 193 •实例9-3 利用DAO从工作表中查询数据 194 •实例9-4 查询其他工作簿的数据(ADO) 195 •实例9-6 利用ADO对工作表数据进行多重排序 196 •实例9-7 利用ADO按照字符的长度对数据进行排序 197 •实例9-8 比较两张表,将两个表中相同的行数据抓取出来 198 •实例9-9 比较两张表,将只存在于某个表中的行数据抓取出来 199 •实例9-10 删除工作表数据区域内的所有空行 200 •实例10-2 利用DAO导入文本文件的全部内容 202 •实例10-3 利用ADO导入文本文件的部分内容 203 •实例10-4 利用DAO导入文本文件的部分内容 204 •实例10-5 利用ADO获取文本文件的行数和列数 205 •实例10-6 利用ADO将超过65536行的文本文件数据导入到Excel工作表 206 •实例10-7 将工作表全部数据保存为文本文件(SaveAs) 208 •实例10-8 将工作表全部数据保存为文本文件(循环) 208 •实例10-9 将数据库数据导出为文本文件 209 •实例10-10 将文本文件保存为Access数据库(Access) 210 •实例10-11 将文本文件保存为Access数据库(ADO+ADOX) 211
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值