VBA-数据库操作


基本概念

1 怎么样才能操作数据库?
使用ADO建立和数据库的连接,然后用ADO对象和sql语言对数据库进行操作。

2 SQL是什么?
SQL(Structured Query Language)是一种查询语言,可以查询、更新数据库中的数据。

3 SQL可以查询哪些数据库?
SQL是一种通用的查询语言,可以查询EXCEL,ACCESS,SQL SERVER等各种数据库

4 ADO是什么?
ADO是新的数据库存取技术,可以建立与各数据库库的连接,也可以对数据库数据进行添加、更新、删除等操作

5 我们学习SQL+ADO访问数据库有什么用处?
  1 可以在不打开EXCEL文件的情况下,从文件中提取数据.
  2 可以从建立连接的专业软件数据库中提取数据.如财务软件等.

6 怎么使用ADO?

  1) 引用法

工具--引用---Microsoft Activex..D...O"
引用后再声明: Dim conn As New Connection 声明链接对象
Dim rst As New Recordset 声明记录集对象
2) 创建法
使用CreateObject函数创建
Set conn = CreateObject("adodb.connection") '创建ado对象
Set rst = CreateObject("ADODB.recordset") '创建记录集

 

ADO的基本对象


一、Connection对象

数据库连接字符串(在类模块中定义)如下:

Property Get excel_driver(datasource)
    'Excel数据库 = "provider=microsoft.jet.oledb.4.0;extended properties=excel 8.0;data source=" & ThisWorkbook.path & "/Database/exceldata.xls"
    excel_driver = "provider=Microsoft.ACE.OLEDB.12.0;extended properties=excel 12.0;data source=" & datasource
End Property

Property Get access_driver(datasource)
    'Access数据库 = "provider=Microsoft.jet.OLEDB.4.0;data source=" & ThisWorkbook.path & "/Database/AccessData.mdb"
    access_driver = "provider=Microsoft.jet.OLEDB.4.0;data source=" & datasource
End Property

Property Get mysql_driver(host, port, database, uid, pwd)
    mysql_driver = "Driver={MySQL ODBC 8.0 Unicode Driver};Server=" & host & ";Port=" & port & ";Database=" & database & ";Uid=" & uid & ";Pwd=" & pwd & ";OPTION=3;"
End Property

Property Get sqlserver_driver(id, database, uid, PassWordChr)
    sqlserver_driver = "Provider=sqloledb;Server=" & id & ";Database=" & database & ";Uid=" & uid & ";Pwd=" & PassWordChr & ";"
End Property

Property Get sqlite_driver(database)
    sqlite_driver = "Driver={SQLite3 ODBC Driver};Database=" & database
End Property

 


1 建立和数据库的连接
.Open
Dim conn As New Connection
conn.Open "provider=microsoft.jet.oledb.4.0;extended properties=excel 8.0;data source=" & ThisWorkbook.Path & "/Database/exceldata.xls"
Conn.Open:打开数据库的连接
provider=microsoft.jet.oledb.4.0 数据库引擎版本
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 = "Driver={MySQL ODBC 8.0 Unicode Driver};Server=" & host & ";Port=" & port & ";Database=" & database & ";Uid=" & uid & ";Pwd=" & pwd & ";OPTION=3;"
4) Oracle数据库
strDriver= "Provider=madaora;Data Source=MyOracleDB; User Id=UserID; Password=Password"

2 执行sql语句
.Execute SQL    # 返回的是Recordset对象
增加新表格:.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链接,
2 添加新记录
AddNew 单个字段或数组,单个值或数组



rst.AddNew 添加新的记录
rst.Fields("姓名") = "伍天明"   Fields("字段名")表示某列的记录
rst.Fields("年龄") = 28
rst.Fields("性别") = "男"
rst.Update 添加记录后要更新

 

'1 使用.Execute 执行 Insert 语句
Sub 添加1()
    Dim conn As New Connection
    Dim sql As String
    Dim data As New 数据库
    conn.Open data.Excel数据库
    sql = "Insert into [Sheet1$] (姓名, 年龄, 性别) VALUES('张三', 35, '男')"
    conn.Execute sql
    conn.Close
    Set conn = Nothing
End Sub
'2 使用AddNew方法添加记录
Sub 添加()
    Dim conn As New Connection
    Dim rst As New Recordset
    'Set conn = CreateObject("adodb.connection") '创建ado对象
    'Set rst = CreateObject("ADODB.recordset") '创建记录集
    Dim data As New 数据库
    conn.Open data.Excel数据库
    rst.Open "select *  from [Sheet1$]", conn, adOpenForwardOnly, adLockOptimistic
    rst.AddNew Array("姓名", "年龄", "性别"), Array("李楠", 25, "")
    'rst.AddNew '添加新的记录
    '    rst.Fields("姓名") = "伍天明w" 'Fields("字段名")表示某列的记录
    '    rst.Fields("年龄") = 28
    '    rst.Fields("性别") = "男"
    'rst.Update '添加记录后要更新
    rst.Close '关闭记录集
    conn.Close '关闭与数据库的链接
    Set rst = Nothing '释放对象
    Set conn = Nothing '释放对象
    MsgBox "已输入到数据库"
End Sub

Sub 添加到access()
    Dim cnn As New ADODB.Connection
    Dim rst As New ADODB.Recordset
    Dim sq1 As String
    Dim data As New 数据库
    cnn.Open data.Access数据库
    '链接方法同excel数据链接
    sq1 = "Select * from 员工" '从员工表中查询
    rst.Open sq1, cnn, adOpenKeyset, adLockOptimistic
    rst.AddNew
    rst.Fields("姓名") = "李楠"
    rst.Fields("年龄") = 23
    rst.Fields("性别") = ""
    rst.Update
    cnn.Close
    Set cnn = Nothing
    MsgBox "添加成功"
End Sub

 

 

3 修改记录
rst.Update 字段数组, 值或数组

Sub 记录修改()
    'Set conn = CreateObject("adodb.connection")
    Dim conn As New Connection
    Dim rst As New Recordset
    Dim sql As String
    Dim nl As String, xb As String, xm As String
    xm = "唐七七"
    xb = ""
    nl = 28
    conn.Open "provider=microsoft.jet.oledb.4.0;extended properties=excel 8.0;data source=" & ThisWorkbook.path & "/Database/exceldata.xls" sql = "update [Sheet1$] set 年龄=" & nl & ",性别='" & xb & "' where 姓名='" & xm & "'" conn.Execute sql
    conn.Close
    Set conn = Nothing
    MsgBox "数据库的记录已修改"
End Sub

Sub 记录修改2()
    Dim conn As New Connection
    Dim rst As New Recordset
    Dim sql As String
    Dim nl As String, xb As String, xm As String
    xm = "唐七七"
    xb = ""
    nl = 19
    conn.Open "provider=microsoft.jet.oledb.4.0;extended properties=excel 8.0;data source=" & ThisWorkbook.path & "/Database/exceldata.xls"
    sql = "Select * from [sheet1$] where 姓名='" & xm & "'"
    rst.Open sql, conn, adOpenKeyset, adLockOptimistic
    rst.Update Array("性别", "年龄"), Array(xb, nl)
    rst.Clone
    conn.Close
    Set rst = Nothing
    Set conn = Nothing
    MsgBox "数据库的记录已修改"
End Sub

 


4 删除记录
rst.delete

Sub ADO删除方法()
    Dim cnn As New ADODB.Connection
    Dim rst As New ADODB.Recordset
    Dim sq1 As String
    Dim data As New 数据库
    cnn.Open data.Access数据库
    sq1 = "delete  from 员工 where 姓名='" & "李楠" & " '" cnn.Execute sq1 MsgBox "删除成功"
    cnn.Close
    Set cnn = Nothing
End Sub

Sub ADO删除方法2()
    Dim cnn As New ADODB.Connection
    Dim rst As New ADODB.Recordset
    Dim sq1 As String
    Dim data As New 数据库
    cnn.Open data.Access数据库
    sq1 = "select * from 员工 where 姓名='" & "李楠" & " '"
    rst.Open sq1, cnn, adOpenForwardOnly, adLockOptimistic
    rst.Delete MsgBox "删除成功"
    cnn.Close
    Set cnn = Nothing
End Sub

 


5 在记录中循环
BOF 在记录的最前面
EOF 在记录的结尾
GetRows(默认值-1,Start, 字段)Start 0从当前记录开始,1从第一条记录,2从最后一条记录开始

Sub 在记录之间循环()
    Dim conn As New Connection
    Dim rst As New Recordset
    Dim data As New 数据库
    Dim x
    conn.Open data.Excel数据库
    rst.Open "select * from [Sheet1$] where val(年龄)>25", conn, adOpenKeyset, adLockOptimistic
    For x = 1 To rst.RecordCount
        If rst.EOF Then
            MsgBox "已到最后一条记录"
        Else
            Debug.Print rst.Fields("姓名") & rst.Fields("年龄")
            rst.MoveNext
        End If
    Next x
    rst.Close
    conn.Close
    Set rst = Nothing
    Set conn = Nothing
    
End Sub

Sub 在记录之间循环2()
    Dim conn As New Connection
    Dim rst As New Recordset
    Dim data As New 数据库
    Dim x, arr, arr1
    conn.Open data.Excel数据库
    rst.Open "select * from [Sheet1$] where val(年龄)>25", conn, adOpenKeyset, adLockOptimistic
    'MsgBox rst.RecordCount
    arr1 = Array("姓名", "年龄") arr = Application.Transpose(rst.GetRows( - 1, 1, arr1)) For x = 1 To UBound(arr, 1)
        Debug.Print arr(x, 1) & "," & arr(x, 2)
    Next x
    rst.Close
    conn.Close
    Set rst = Nothing
    Set conn = Nothing
    
End Sub

 

 

记录查找

Sub 筛选()
    Dim conn As New Connection
    Dim data As New 数据库
    conn.Open data.Excel数据库
    Range("a1:c100") = ""
    Range("a2").CopyFromRecordset conn.Execute("select * from [sheet1$] where val(年龄) > 25")
    conn.Close
    Set conn = Nothing
End Sub
Sub 查找()
    Set conn = CreateObject("adodb.connection")
    Set rst = CreateObject("ADODB.recordset")
    Dim data As New 数据库
    conn.Open data.Excel数据库
    rst.Open "select *  from [Sheet1$] " 'where 姓名='李楠2'", conn, adOpenKeyset, adLockOptimistic
    If rst.RecordCount < 1 Then
        MsgBox "找不到该姓名"
        Goto 100
    End If
    Debug.Print "年龄:" & rst.Fields("年龄")
    Debug.Print "性别:" & rst.Fields("性别")
    ' MsgBox "查找成功"
    100
    
    rst.Close
    conn.Close
    Set rst = Nothing
    Set conn = Nothing
End Sub

Sub FindX(xingming As String)
    Set conn = CreateObject("adodb.connection")
    Set rst = CreateObject("ADODB.recordset")
    Dim data As New 数据库
    conn.Open data.Access数据库
    rst.Open "select *  from 员工 where 姓名='" & xingming & "'", conn, adOpenKeyset, adLockOptimistic
    If rst.RecordCount < 1 Then
        MsgBox "找不到该姓名"
        Goto 100
    End If
    Debug.Print "年龄:" & rst.Fields("年龄")
    Debug.Print "性别:" & rst.Fields("性别")
    ' MsgBox "查找成功"
    100
    
    rst.Close
    conn.Close
    Set rst = Nothing
    Set conn = Nothing
End Sub

 

 

sql应用

一 按条件筛选

'按条件筛选--多个条件
'用and,OR连接
Sub 按条件筛选5()
    Dim sql As String
    Dim data As New 数据库
    sql = "Select * from [sheet1$] Where 出库日期 between  #2005-1-4# and #2005-1-10# and 销售单价>100"
    data.执行筛选 data.Excel数据库, sql
End Sub
''按条件筛选--模糊条件
'%表示任意多个字符,_(下划线)表示单个占位符
Sub 按条件筛选6()
    Dim sql As String
    Dim data As New 数据库
    sql = "Select * from [sheet1$] Where 物品名称 like '%扶手%'"
    data.执行筛选 data.Excel数据库, sql
End Sub
''按条件筛选--插入变量
Sub 按条件筛选7()
    Dim sql As String
    Dim data As New 数据库
    Dim sr
    sr = "挡泥板"
    sql = "Select * from [sheet1$] Where 物品名称 ='" & sr & "'"
    data.执行筛选 data.Excel数据库, sql
End Sub
''按条件筛选--在字符串组里
Sub 按条件筛选8()
    Dim sql As String
    Dim data As New 数据库
    sql = "Select * from [sheet1$] Where 物品名称 in('车衣','扶手箱')"
    data.执行筛选 data.Excel数据库, sql
End Sub
''按条件筛选--借用函数
Sub 按条件筛选9()
    Dim sql As String
    Dim data As New 数据库
    sql = "Select * from [sheet1$] Where left(物品代码,3)='028'"
    data.执行筛选 data.Excel数据库, sql
End Sub

 

二 筛选方式

Option Explicit

'筛选方式是指结果的样式

'1 筛选全部字段
'*表示全部字段
Sub 筛选全部字段()
    Dim sql As String
    Dim data As New 数据库
    sql = "Select * from ChuKu"
    data.执行筛选 data.Access数据库, sql
End Sub

'2 筛选指定字段
'在from前面列出要显示的所有字段,如果要跳过的用""""
Sub 显示指定字段()
    Dim sql As String
    Dim data As New 数据库
    sql = "Select """",出库日期,"""",物品代码,"""",规格,单位 from ChuKu"
    data.执行筛选 data.Access数据库, sql
End Sub

'3 筛选不重复的
'Distinct 字段名 筛选不重复的记录
Sub 不重复筛选()
    Dim sql As String
    Dim data As New 数据库
    sql = "Select Distinct """",物品代码 from ChuKu"
    data.执行筛选 data.Access数据库, sql
End Sub

'4 筛选前N个
'TOP N 只显示前N个记录
Sub 筛选前10个() '按个数筛选
    Dim sql As String
    Dim data As New 数据库
    sql = "Select top 10 * from ChuKu"
    data.执行筛选 data.Access数据库, sql
End Sub

'Top N percent 可以显示前百分之N的记录
Sub 筛选百分之N() '按百分比筛选
    Dim sql As String
    Dim data As New 数据库
    sql = "Select top 30 Percent * from ChuKu"
    data.执行筛选 data.Access数据库, sql
End Sub

'5 格式化显示的结果
'可以对筛选的字段用函数进行进一步的处理和格式化
Sub 格式化字段() '按百分比筛选
    Dim sql As String
    Dim data As New 数据库
    sql = "Select  ID,Format(出库日期,""yyyy-mm-dd"") from ChuKu"
    data.执行筛选 data.Access数据库, sql
End Sub

'6 对筛选后的结果排序

Sub 排序() '
    'Desc降序
    'Asc升序
    Dim sql As String
    Dim data As New 数据库
    sql = "Select  * from ChuKu Order by 出库日期 asc,销售单价 desc"
    data.执行筛选 data.Access数据库, sql
End Sub
Sub 筛选销售数量前10() '
    Dim sql As String
    Dim data As New 数据库
    sql = "Select  Top 10 * from ChuKu Order by 出库日期 asc,销售单价 desc"
    data.执行筛选 data.Access数据库, sql
End Sub

'7 分组显示
'Group by 可以配合函数进行分组求和,分组求最大值等.
Sub 分组() '
    Dim sql As String
    Dim data As New 数据库
    sql = "Select  """","""",物品代码,"""","""","""",sum(出库数量) from ChuKu group by 物品代码"
    data.执行筛选 data.Access数据库, sql
End Sub
Sub 按条件显示分组记录() '
    Dim sql As String
    Dim data As New 数据库
    sql = "Select  """","""",物品代码,"""","""","""",sum(出库数量) from ChuKu group by 物品代码 HAVING sum(出库数量)>=3"
    data.执行筛选 data.Access数据库, sql
End Sub

 

三 SQL函数应用

Option Explicit

'1 SUM函数求和,count计数
Sub 求和()
    Dim sql As String
    Dim data As New 数据库
    sql = "Select sum(出库数量),count(出库数量) from ChuKu where 物品代码='0270001'"
    data.执行筛选 data.Access数据库, sql
End Sub

'2 left,right,mid,instr,format文本函数
Sub 文本()
    Dim sql As String
    Dim data As New 数据库
    sql = "Select 物品代码, ""左三位:"" & left(物品代码,3),right(物品代码,4),mid(物品代码,2,2),instr(物品代码,""1"") from ChuKu"
    data.执行筛选 data.Access数据库, sql
End Sub

'3 year,month,day,datediff,DateSerial日期函数
Sub 日期()
    Dim sql As String
    Dim data As New 数据库
    sql = "Select 出库日期, year(出库日期),month(出库日期),day(出库日期),DateDiff(""m"",出库日期,now) from ChuKu"
    data.执行筛选 data.Access数据库, sql
End Sub
'4 max,min,first,last 最值函数
Sub 最小值()
    Dim sql As String
    Dim data As New 数据库
    sql = "Select 物品名称,min(销售金额) from ChuKu group by 物品名称"
    data.执行筛选 data.Access数据库, sql
End Sub

Sub 最新值()
    Dim sql As String
    Dim data As New 数据库
    sql = "Select 物品名称,last(销售金额) from ChuKu group by 物品名称"
    data.执行筛选 data.Access数据库, sql
End Sub

 

四 多表查询

'Union (AlL) 多个select查询结果合并在一起
Sub 合并工作表数据()
    Dim data As New 类1
    Dim sql As String
    sql = "select  * from [Sheet1$a:c] union all select * from [sheet2$a:c]"
    data.执行筛选 sql, "a2"
End Sub

Sub 合并工作表数据2()
    Dim data As New 类1
    Dim sql As String
    sql = "select  * from [Sheet1$a:c] union  select * from [sheet2$a:c]"
    data.执行筛选 sql, "a2"
End Sub

'查找两个表中相同的
'Select 字段 from 表1,表2 where 表1.字段=表2.字段
Sub 列出相同()
    Dim data As New 类1
    Dim sql As String
    sql = "select [Sheet1$a:c].* from [Sheet1$a:c],[Sheet2$a:c] where [Sheet1$a:c].类别=[Sheet2$a:c].类别"
    data.执行筛选 sql, "a2"
End Sub
'Select 字段 from 表1 Inner Join 表2 on 条件
Sub 列出相同2()
    Dim data As New 类1
    Dim sql As String
    sql = "select [Sheet1$].*,[sheet2$].库别 from [Sheet1$] Inner Join [sheet2$] on [Sheet1$].类别=[sheet2$].类别"
    data.执行筛选 sql, "a2"
End Sub

'两表汇总
Sub 汇总()
    Dim data As New 类1
    Dim sql As String
    Dim sq As String
    sql = "select * from [sheet1$a:c] union all select * from [sheet2$a:c]"
    sq = "select 类别,sum(数量),sum(金额) from (" & sql & ") group by 类别"
    data.执行筛选 sq, "a2"
End Sub

'
Sub 合并()
    Dim data As New 类1
    Dim sql As String
    sql = "select [Sheet1$].*,[sheet2$].库别 from [Sheet1$]  left Join [sheet2$] on [Sheet1$].类别=[sheet2$].类别"
    data.执行筛选 sql, "a2"
End Sub

'JOIN: 如果表中有至少一个匹配,则返回行
'LEFT JOIN: 即使右表中没有匹配,也从左表返回所有的行
'RIGHT JOIN: 即使左表中没有匹配,也从右表返回所有的行
'FULL JOIN: 只要其中一个表中存在匹配,就返回行,可惜的是在EXCEL VBA中不支持

 

自定义SQL拼接函数

Sub excelTest()
    Dim conn As New Connection
    conn.Open "provider=microsoft.ace.oledb.12.0;extended properties='excel 12.0';data source=" & ThisWorkbook.FullName
    sql = parse_sql("select * from [test$] where age=?", Array(Range("D1")))
    Set rst = conn.Execute(sql)
    
    Range("A1").CopyFromRecordset rst
    
    conn.Close
    Set rst = Nothing
    Set conn = Nothing
End Sub


Function parse_sql(sql, params)
    arr = Split(sql, "?")
    temp = ""
    For i = 0 To UBound(arr)
        If i < UBound(arr) Then
            If IsNumeric(params(i)) Then
                temp = temp & arr(i) & params(i)
            Else
                temp = temp & arr(i) & "'" & params(i) & "'"
            End If
        End If
    Next i
    parse_sql = temp
End Function

 

 

 

 

 

end


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM