运用SQL输出EXCEL报表 - EXCEL VBA(26)
SQL是Structured Query Language的缩写,中文译为“结构化查询语言”。SQL 是一种计算机语言,用来检索、存储和修改关系型数据库中存储的数据。SQL虽然是一种被ANSI标准化的语言,但是它有很多不同的实现版本。
SQL是关系型数据库的标准语言,所有的关系型数据库管理系统(RDBMS),比如 MySQL、Oracle、SQL Server、MS Access、Sybase、Informix、Postgres 等,都将SQL作为其标准处理语言。
将EXCEL做为数据库,运用强大的SQL语言来操作EXCEL表格,无疑会极大提高数据处理的效率和灵活性。SQL的内容非常丰富、用途广泛,是各种数据库程序员的必备技能。对于习惯于用EXCEL处理数据的用户来说,只需要了解SQL的SELECT语句即可。本文只介绍运用SQL检索EXCEL记录,并生成报表。至于日常工作中创建数据记录、删除数据、修改数据等数据清理工作均可在EXCEL表格中完成。
1、EXCEL数据表
学生数据EXCEL样例文档下载地址: https://pan.baidu.com/s/1dgMPt16OaahyVj9vJBfmAQ?pwd=ff53。
I、sheet1数据表
- 学生注册数据表:
- 字段属性:
【学号】ID唯一识别码,11位文本字符;
【姓名】文本字段;
【性别】逻辑字段,表中为男、女,也可以为0、1或M、F;
【省份】文本字段;
【学院】文本字段;
【专业】文本字段;
【生日】日期字段。
II、sheet2数据表
- 学生成绩数据表:
- 字段属性:
【学号】关联字段,和sheet1学号ID码关联.EXCEL关联报表需要适当的关联指标字段;
【数学】、【英语】和【政治】数值型字段,成绩在0-100之间。
III、数据预处理
为了SQL检索的准确性,需要运用EXCEL函数对原始数据进行数据预处理,包括,
- 【姓名】文本字段需要去除所有空格,
- 【学号】、【性别】、【省份】、【学院】和【专业】文本字段需要用根据码表录入(参见EXCEL数据码表和ID设计);
- 【生日】为了和SQL检索匹配,可以用TEXT函数格式化生日字段为“月/日/年”格式,即【=TEXT(字段值, "mm/dd/yyyy")】;
- 【数学】、【英语】和【政治】数值型成绩字段,应检测字段值是否为整数数值、值域是否在0-100之间。
2、使用ADODB.Connection对象连接本地Excel文档
在模块1编写connTest代码如下:
Sub connTest()
Dim conn As Object
Dim rs As Object
Dim strSQL As String
Dim filePath As String
' 设置本地Excel文档的文件路径
filePath = "D:\excelTest\strdentSQL.xlsx"
' 创建ADO连接对象
Set conn = CreateObject("ADODB.Connection")
' 设置连接字符串
conn.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & filePath & ";Extended Properties=""Excel 12.0;HDR=YES"""
' 打开连接
conn.Open
' 读取数据
strSQL = "SELECT * FROM [Sheet1$]"
Set rs = conn.Execute(strSQL)
'显示EXCEL表格字段数量
MsgBox rs.Fields.Count
' 关闭连接
conn.Close
' 释放对象
Set rs = Nothing
Set conn = Nothing
End Sub
- 地址代码:第7行代码【filePath = "D:\excelTest\strdentSQL.xlsx"】可根据自己电脑设置连接地址,EXCEL文档扩展名为“.xlsx”或“.xls”;
- 连接代码:第11行代码(核心代码),【conn.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & filePath & ";Extended Properties=""Excel 12.0;HDR=YES"""】。EXCEL版本不同,连接代码略有不同。本文使用EXCEL2010版本,所有SQL SELECT语句运行通过。连接代码中“HDR=YES”表示输出数据集不包含表头;
- SQL SELECT语句:第15行代码,【strSQL = "SELECT * FROM [Sheet1$]"】检索Sheet1所有数据,是最基本的SQL SELECT语句;
- 显示字段(EXCEL数据列)数量:第18行代码,【MsgBox rs.Fields.Count】显示出EXCEL数据量数量,说明ADODB.Connection对象连接本地Excel成功。
3、常用SQL SELECT检索语句
不同版本SQL语言用于不同数据库时,语法有所区别。SQL SELECT检索语句在操作EXCEL表格时,有些功能无法使用。
下面列出在EXCEL2010中运行通过的常用SQL SELECT检索语句:
'输出全部数据
1、"SELECT * FROM [Sheet1$]"
-------------------------------
'输出全部数据并按学号单列排序(升序),关键字ORDER BY
"SELECT * FROM [Sheet1$] ORDER BY 学号"
-------------------------------
'输出全部数据并按学号单列排序(降序),关键字DESC
2、"SELECT * FROM [Sheet1$] ORDER BY 学号 DESC"
-------------------------------
'统计不重复学号总数,关键字DISTINCT
3、"SELECT DISTINCT 学号 FROM [Sheet1$]"
-------------------------------
'输出全部数据并按学院和省份多列列排序(升序)
4、"SELECT * FROM [Sheet1$] ORDER BY 学院, 省份"
-------------------------------
'输出部分字段全部数据
5、"SELECT 学号, 姓名, 性别 FROM [Sheet1$]"
-------------------------------
'Like通配符"_"表示一个字符、"%"表示多个字符。检索名字为两个汉字、姓王的男生
6、"SELECT * FROM [Sheet1$] WHERE 姓名 Like '王_' AND 性别='男'"
-------------------------------
'检索名字为姓王或姓李的男生,关键字Like '[王李]%'
7、"SELECT * FROM [Sheet1$] WHERE 姓名 Like '[王李]%' AND 性别='男'"
-------------------------------
'检索名字为姓王或姓李的前10名男生,关键字TOP 10
8、"SELECT TOP 10 * FROM [Sheet1$] WHERE 姓名 Like '[王李]%' AND 性别='男'"
-------------------------------
'检索黑龙江、吉林、辽宁三省学生,关键字IN('黑龙江','吉林','辽宁')"
9、"SELECT * FROM [Sheet1$] WHERE 省份 IN('黑龙江','吉林','辽宁') AND 性别='男'"
-------------------------------
'检索1990出生的学生。生日字段数据处理使用YEAR、Month和DAY函数
10、SELECT * FROM [Sheet1$] WHERE YEAR(生日)=1990"
-------------------------------
'检索生日为11月13日的学生
11、"SELECT * FROM [Sheet1$] WHERE Month(生日)=11 AND DAY(生日)=13"
-------------------------------
'检索数学成绩在90-100之间的学生(FROM [Sheet1$])
12、"SELECT * FROM [Sheet2$] WHERE 数学 BETWEEN 90 AND 100"
-------------------------------
'统计数据总数
13、"SELECT COUNT(*) AS 学生总数 FROM [Sheet1$]"
-------------------------------
'统计数学平均成绩(FROM [Sheet1$])。SQL的AVG、SUM、MAX和MIN用于数值型字段
14、"SELECT AVG(数学) AS 数学平均成绩 FROM [Sheet2$]"
-------------------------------
'sheet1和sheet2间表格交叉检索
15、"SELECT [sheet1$].姓名,[sheet2$].数学 FROM [sheet1$],[sheet2$] WHERE [sheet1$].学号=[sheet2$].学号"
16、"SELECT [sheet1$].姓名,[sheet2$].数学 FROM [sheet1$],[sheet2$] WHERE [sheet1$].学号=[sheet2$].学号 AND [sheet2$].数学>90"
4、SQL操作学生数据EXCEL文档案例
I、窗体设计
- ListBox1:列表框,打开窗体时设置常用SQL SELECT语句;
- TextBox1:文本框,鼠标在列表框中选择SQL SELECT语句时,自动填写该语句;
- CommandButton1:【条件检索】命令按钮,鼠标点击后根据TextBox1文本框中SQL SELECT语句检索数据、并写入sheet1;
- CommandButton2:【嵌套检索】命令按钮,鼠标点击后按字段关联检索sheet1和sheet2。
II、窗体初始化代码
Private Sub UserForm_Initialize()
'---ListBox1列表框初始化---
ListBox1.AddItem "SELECT * FROM [Sheet1$]"
ListBox1.AddItem "SELECT * FROM [Sheet1$] ORDER BY 学号"
ListBox1.AddItem "SELECT * FROM [Sheet1$] ORDER BY 学号 DESC"
ListBox1.AddItem "SELECT DISTINCT 学号 FROM [Sheet1$]"
ListBox1.AddItem "SELECT * FROM [Sheet1$] ORDER BY 学院, 省份"
ListBox1.AddItem "SELECT 学号, 姓名, 性别 FROM [Sheet1$]"
ListBox1.AddItem "SELECT * FROM [Sheet1$] WHERE 姓名 Like '王_' AND 性别='男'"
ListBox1.AddItem "SELECT * FROM [Sheet1$] WHERE 姓名 Like '[王李]%' AND 性别='男'"
ListBox1.AddItem "SELECT TOP 10 * FROM [Sheet1$] WHERE 姓名 Like '[王李]%' AND 性别='男'"
ListBox1.AddItem "SELECT * FROM [Sheet1$] WHERE 省份 IN('黑龙江','吉林','辽宁') AND 性别='男'"
ListBox1.AddItem "SELECT * FROM [Sheet1$] WHERE YEAR(生日)=1990"
ListBox1.AddItem "SELECT * FROM [Sheet1$] WHERE Month(生日)=11 AND DAY(生日)=13"
ListBox1.AddItem "SELECT * FROM [Sheet2$] WHERE 数学 BETWEEN 90 AND 100"
ListBox1.AddItem "SELECT COUNT(*) AS 学生总数 FROM [Sheet1$]"
ListBox1.AddItem "SELECT AVG(数学) AS 数学平均成绩 FROM [Sheet2$]"
ListBox1.AddItem "SELECT [sheet1$].姓名,[sheet2$].数学 FROM [sheet1$],[sheet2$] WHERE [sheet1$].学号=[sheet2$].学号"
ListBox1.AddItem "SELECT [sheet1$].姓名,[sheet2$].数学 FROM [sheet1$],[sheet2$] WHERE [sheet1$].学号=[sheet2$].学号 AND [sheet2$].数学>90"
ListBox1.ListIndex = 0
TextBox1.Text = ListBox1.Text
End Sub
III、鼠标点击ListBox1列表框选项代码
Private Sub ListBox1_Click()
TextBox1.Text = ListBox1.Text
End Sub
IV、CommandButton1【条件检索】命令按钮
Private Sub CommandButton1_Click()
Dim conn As Object
Dim rs As Object
Dim strSQL As String
Dim filePath As String
Dim c, i, k As Integer
filePath = "D:\excelTest\strdentSQL.xlsx"
Set conn = CreateObject("ADODB.Connection")
conn.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & filePath & ";Extended Properties=""Excel 12.0;HDR=YES"""
conn.Open
' 读取SQL SELECT语句
strSQL = TextBox1.Text
Set rs = conn.Execute(strSQL)
Sheet1.Cells.Clear
' 输出表头行
c = rs.Fields.Count
For i = 1 To c
Sheet1.Cells(1, i) = rs.Fields(i - 1).Name
Next i
' 输出数据
k = 2
Do Until rs.EOF
For i = 1 To c
Sheet1.Cells(k, i) = rs.Fields(i - 1).Value
Next i
k = k + 1
rs.MoveNext
Loop
conn.Close
Set rs = Nothing
Set conn = Nothing
End Sub
V、项目应用
- 打开窗体:
- 鼠标选择列表SQL SELECT语句:
- 鼠标点击【条件检索】命令按钮,sheet1数据如下:
分别选择列表中选择不同SQL SELECT语句,观察sheet1数据输出效果。
VI、表格嵌套检索
嵌套检索也称“子查询”或者“嵌套查询”,是指将一个 SELECT查询的结果作为另一个 SQL 语句的数据来源或者判断条件。例如,
SELECT 姓名, 学院, 专业 FROM [Sheet1$] WHERE 学号=(SELECT 学号 FROM [Sheet1$] WHERE 数学>90)
由于EXCEL VBA的SQL SELECT语句不支持SELECT嵌套检索,需要自编EXCEL VBA代码来完成。【嵌套检索】命令按钮代码如下:
Private Sub CommandButton2_Click()
Dim conn As Object
Dim rt As Object
Dim rs As Object
Dim strSQL, strSQL1 As String
Dim filePath As String
Dim c, i, k As Integer
Dim id As String
filePath = "D:\excelTest\strdentSQL.xlsx"
Set conn = CreateObject("ADODB.Connection")
conn.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & filePath & ";Extended Properties=""Excel 12.0;HDR=YES"""
conn.Open
'设置 检索sheet1的SQL SELECT语句
strSQL = "SELECT * FROM [Sheet1$] WHERE 姓名 Like '[王李]%' AND 性别='男'"
Set rs = conn.Execute(strSQL)
Sheet1.Cells.Clear
'写表头标题
Sheet1.Cells(1, 1) = "学号"
Sheet1.Cells(1, 2) = "姓名"
Sheet1.Cells(1, 3) = "数学"
'读取数据
k = 2
'第1个数据集循环
Do Until rs.EOF
'获得关联字段(学号)值
id = rs.Fields(0).Value
'设置 检索sheet2的SQL SELECT语句
strSQL1 = "SELECT 数学 FROM [Sheet2$] WHERE 学号='" & id & "'"
Set rt = conn.Execute(strSQL1)
'第2个数据集循环
Do Until rt.EOF
'按字段名称写数据到sheet1
Sheet1.Cells(k, 1) = rs.Fields("学号").Value
Sheet1.Cells(k, 2) = rs.Fields("姓名").Value
Sheet1.Cells(k, 3) = rt.Fields("数学").Value
k = k + 1
rt.MoveNext
Loop
rs.MoveNext
Loop
conn.Close
Set rt = Nothing
Set rs = Nothing
Set conn = Nothing
End Sub
代码用【"SELECT * FROM [Sheet1$] WHERE 姓名 Like '[王李]%' AND 性别='男'"】语句从sheet1中检索出姓王或姓李的男生,然后再有对应(关联)学号通过【"SELECT 数学 FROM [Sheet2$] WHERE 学号='" & id & "'"】语句检索出数学成绩。通过这种方法可以实现多表嵌套查询。
在窗体中运行【嵌套检索】命令按钮,sheet1数据显示如下:
使用SQL技术操作EXCEL文档需要注意以下事项:
- EXCEL文档数据要规范、“干净”;
- EXCEL文档命名、存储地址要有规律,这样便于批量操作;
- EXCEL表格中为原始数据,尽量不用函数或对数据进行格式化。如果需要用EXCEL函数将数据格式化或标准化,数据处理完成要按值分组、粘贴后存储;
- 通过ADO连接访问Excel文档时,Excel应该在后台保持关闭状态,否则可能会出现冲突或无法正常访问的问题。
SQL SELECT检索语句可以灵活、高效地组合成任意查询语句,单表条件查询、多表交叉查询和嵌套查询,每个查询语句就是一个EXCEL数据报表。在实际工作中,面对众多EXCEL表格,只需要建立ADO连接,任何复杂的数据分析和统计报表工作都可以通过SELECT查询语句来处理。
请先 后发表评论~