zoukankan      html  css  js  c++  java
  • Vba+access+Excel编程

    学习目的是建立简易的管理系统

    当前学习路线:excel的宏的简单了解→access数据库的了解→两者的结合

    excel的宏的简单了解:

    关于宏的使用,大部分文章都提到说Vba很难写,但是可以通过一段现成的代码,修改关键部分来为自己所用,现成代码的获得方式就是录制宏,在其自动生成的代码上添加循环等修改,达到自己想要的效果。

    关于宏的录制与代码的修改运行如下:

    1.首先要在excel中找到开发工具(WPS也有,但当前使用的是office的)

    在excel的“文件”→“选项”→“自定义功能区”的“主选项卡”部分,把“开发工具”一项勾选上,点击右下角的确定,这样excel的操作栏就会显示开发工具选项卡了

     接下来举例实现功能:录制宏操作,对A1:A10单元格添加批注,批注内容是“你好”

    首先,在开发工具中点击录制宏

    接下来做正常的批注操作,批注好之后点击停止录制

    然后点击Visual Basic 会弹窗出来如图所示的界面

     首先要在左侧的工程界面找到我们需要操作的对象,是example.xlsx的模块,打开后才会显示右侧的代码部分,宏2是录制下来的“本体”生成的代码,把它修改为宏1的形式就完成了从A列的1到10都批注“你好”的功能

    这里有一个小知识点:

    Cstr()函数可以将数字转换成字符,如 2 → “2”

    Val()函数可以将字符(数字字符)转换成数字, 如 “2” → 2

    代码写好之后,运行即可(注意!!!如果录制的宏是对A1批注,代码中的循环操作又包括了对A1的操作的话,会报错的,需要先把原A1的批注删除掉,即不能对已经存在的操作重复操作)

    access数据库的建立

    首先可以在目标文件夹新建一个.accdb格式的数据库文档

    数据库的数据来源可以手动添加,也可以根据excel导入(推荐),即可建立一个数据库可供使用

    如下图所示

    两者的结合

    首先明确一下目标:是为了通过对宏的编写和调用,实现excel和access连接,通过一些sql语句,将目标数据从数据库中提取到excel中

    在Visual Basic新建一个新的模块,即新建了一个宏,然后要现尝试着把excel和access连接起来,在Visual Basic for Applications的窗口中找到 “工具” → “引用”

    如图所示

    在可使用的引用中找到“Microsoft ActiveX Data Objects”(简称ADO)可能有很多版本,选择最高的版本即可,勾选然后点击确定

    接下来就是代码的实现了,代码部分如下

     1 Sub ConnectDBtest()
     2 '第一步,告诉电脑需要使用ADO工具,在工具→引用中找到ADO确认引用
     3 
     4 '第二步,创建连接对象
     5 '2-1,给连接对象取名字
     6 Dim con As ADODB.Connection    '声明对象变量
     7 '2-2,创建对象变量并赋值
     8 Set con = New ADODB.Connection   '创建对象变量
     9 
    10 '第三步,建立数据库的连接
    11 con.Open "provider=microsoft.ace.oledb.12.0;data source=" & ThisWorkbook.Path & "example.accdb"
    12 
    13 
    14 MsgBox "连接成功"
    15 
    16 
    17 End Sub

    第一行是给这部分代码命名

    第六行是声明对象变量的类型 Dim ...As ...

    第八行是正式创建这个变量

    第十一行是建立对象与数据库的连接,其中要注意两点,第一是数据驱动引擎即provider的版本,第二是所连接的数据库的位置

       1.版本: 可以根据数据库文件的后缀名进行简单的判断,03版的后缀名是.mdb,07版以上用的是accdb,对应使用的provider就是12.0的

       2.数据库的位置:本地的数据库可以照上方第十一行的写法,ThisWorkbook.Path,如果是其他位置的数据库,可以按照如下所示的方法,把数据库位置设置为变量

    1 '第三步,建立数据库的连接
    2 Dim mydblocation As String
    3 mydblocation = "数据库位置"
    4 con.Open "provider=microsoft.ace.oledb.12.0;data source=" & mydblocation & "example.accdb"
    5 MsgBox "连接成功"

    以上是确保了数据库与excel的连接,连接成功后会出现弹窗提示 “连接成功”【判断连接成功还有一个方法是通过查看本地是否出现了example.laccdb这样的一个文件,出现则表明数据库已经被打开了】

    接下来要实现把数据库的内容通过SQL语言来帅选出来,放入excel指定的位置,代码如下

     1 Sub ConnectDBtest()
     2 '第一步,告诉电脑需要使用ADO工具,在工具→引用中找到ADO确认引用
     3 
     4 '第二部,创建连接对象
     5 '2-1,给连接对象取名字
     6 Dim con As ADODB.Connection    '声明对象变量
     7 '2-2,创建对象变量并赋值
     8 Set con = New ADODB.Connection   '创建对象变量
     9 
    10 '第三步,建立数据库的连接
    11 Dim mydblocation As String
    12 mydblocation = "数据库远程的位置"
    13 con.Open "provider=microsoft.ace.oledb.12.0;data source=" & mydblocation & "example.accdb"
    14 MsgBox "连接成功"
    15 
    16 '第四步,查询表中满足条件的字段,这里是列出工作表 “Summary of frame-parallel test” decoder一列下为google的行的内容
    17 Sql = "select * from [Summary of frame-parallel test] where [decoder] = 'google'"
    18 Dim rs As New ADODB.Recordset    '创建记录集对象
    19 
    20 '第五步,执行sql查询语句
    21 Set rs = con.Execute(Sql)
    22 
    23 '获取字段名即col的title
    24 Dim i As Integer
    25 For i = 0 To rs.Fields.Count - 1
    26     Cells(1, i + 1) = rs.Fields(i).Name
    27 Next
    28 
    29 
    30 Sheets("sheet1").Range("A2").CopyFromRecordset rs    '将记录集rs中的数据返回到工作表中
    31 
    32 
    33 '清空缓存区
    34 rs.Close: Set rs = Nothing
    35 con.Close: Set con = Nothing
    36 
    37 
    38 End Sub

    第十七行是定义了数据库查询的内容

    第十八行和21行是定义了装载查询后结果的容器为rs,即记录集,21行是执行,执行后结果都放在rs中

    第24~27行是遍历获取数据库的列的title并写进excel的第一行

    第30行是复制了数据集rs中的内容到excel工作薄中,名为“sheet1”的工作表,且从A2开始写

    第34~35行是清空rs记录集和对象的缓存

    其中第21行生成记录集的方法:

    1.第21行的方法可以称之为“使用connection对象的Execute方法产生记录集”,这种方法产生的记录集特点:一.rs是只读的,不能修改记录,通常用于做一些不需要返回的操作。二.不能获取记录的条数

    2.还有一种方法较叫“使用recordset对象的open方法”产生记录集,这种方法获得的记录集是可读可写的,可以修改记录,语句是

    $  rs.Open sql,con,adOpenKeyset,adLockOptimistic

    其中Open后面跟的四个参数,第一个sql表示所执行的命令字符串(因为此例中第17行已经定义了查询语句为sql),第二个参数写的是当前连接的哪一个数据库,这里是连接了con数据库,第三个参数选游标的运动方式,选动态的(其实这里选固定的adOpenKeyset即可包括后面第四个参数也是一样)

    这种方式可以获取到符合条件的记录的条数,便于做判断,使表格使用更方便(如果无记录,使用if语句判断一下,弹窗提示即可,无需再生成一个空表格)

    如下代码所示,实现的是如果没有查找到记录,会弹窗提示无记录而不是报错

     1 Sub ConnectDBtest()
     2 '第一步,告诉电脑需要使用ADO工具,在工具→引用中找到ADO确认引用
     3 
     4 '第二部,创建连接对象
     5 '2-1,给连接对象取名字
     6 Dim con As ADODB.Connection    '声明对象变量
     7 '2-2,创建对象变量并赋值
     8 Set con = New ADODB.Connection   '创建对象变量
     9 
    10 '第三步,建立数据库的连接
    11 Dim mydblocation As String
    12 mydblocation = "数据库位置"
    13 con.Open "provider=microsoft.ace.oledb.12.0;data source=" & mydblocation & "example.accdb"
    14 MsgBox "连接成功"
    15 
    16 '第四步,查询表中满足条件的字段
    17 Sql = "select * from [Summary of frame-parallel test] where [decoder] = 'ci'"
    18 
    19 Dim rs As New ADODB.Recordset    '创建记录集对象方式1
    20 
    21 '第五步,执行sql查询语句
    22 rs.Open Sql, con, adOpenKeyset, adLockOptimistic
    23 
    24 If rs.RecordCount <= 0 Then      '表示没有满足条件的记录
    25     MsgBox "没有满足条件的记录"
    26 Else
    27     '获取字段名即col的title
    28     Dim i As Integer
    29     For i = 0 To rs.Fields.Count - 1
    30         Cells(1, i + 1) = rs.Fields(i).Name
    31     Next
    32     
    33     
    34     Sheets("sheet1").Range("A2").CopyFromRecordset rs    '将记录集rs中的数据返回到工作表中
    35 End If
    36 
    37 '清空缓存区
    38 rs.Close: Set rs = Nothing
    39 con.Close: Set con = Nothing
    40 
    41 
    42 End Sub

    如果用connection对象的Execute方法产生记录集,也可以实现判空的功能,代码如下

     1 Sub ConnectDBtest()
     2 '第一步,告诉电脑需要使用ADO工具,在工具→引用中找到ADO确认引用
     3 
     4 '第二部,创建连接对象
     5 '2-1,给连接对象取名字
     6 Dim con As ADODB.Connection    '声明对象变量
     7 '2-2,创建对象变量并赋值
     8 Set con = New ADODB.Connection   '创建对象变量
     9 
    10 '第三步,建立数据库的连接
    11 Dim mydblocation As String
    12 mydblocation = "数据库位置"
    13 con.Open "provider=microsoft.ace.oledb.12.0;data source=" & mydblocation & "example.accdb"
    14 MsgBox "连接成功"
    15 
    16 '第四步,查询表中满足条件的字段
    17 Sql = "select * from [Summary of frame-parallel test] where [decoder] = 'ci'"
    18 
    19 Dim rs As New ADODB.Recordset    '创建记录集对象方式1
    20 Set rs = con.Execute(Sql)
    21 
    22 'EOF表示记录的结尾,BOF表示记录的开头
    23 If rs.EOF And rs.BOF Then       '指针既指向开头又指向末尾,说明没有记录
    24 
    25 '第五步,执行sql查询语句
    26 'rs.Open Sql, con, adOpenKeyset, adLockOptimistic
    27 'If rs.RecordCount <= 0 Then      '表示没有满足条件的记录
    28     MsgBox "没有满足条件的记录"
    29 Else
    30     '获取字段名即col的title
    31     Dim i As Integer
    32     For i = 0 To rs.Fields.Count - 1
    33         Cells(1, i + 1) = rs.Fields(i).Name
    34     Next
    35     
    36     
    37     Sheets("sheet1").Range("A2").CopyFromRecordset rs    '将记录集rs中的数据返回到工作表中
    38 End If
    39 
    40 '清空缓存区
    41 rs.Close: Set rs = Nothing
    42 con.Close: Set con = Nothing
    43 
    44 
    45 End Sub

     窗体的设置

    excel要结合窗体才能实现更便捷的功能,设置方法如下:

    首先在excel的Visual Basic中找到对应工程,点击菜单栏中的插入→用户窗体

     接下来会出现如图所示的界面

     窗体调出来之后,是需要有个模块来专门编辑窗体信息的,在此再点击插入→模块,创建一个新的模块

    1 '定义一个函数名为OpenMenuWindow来打来窗体
    2 Sub OpenMenuWindow()
    3 
    4 '窗体名称.show可以调出目标窗体
    5 UserForm1.Show
    6 
    7 End Sub

    运行这个函数就可以打开窗体了

    窗体的外形和内容设计的方法是:在窗体的编辑页面下,右键点击窗体,再点击查看代码会出现如图所示的界面

     意思是当前的窗体UserForm是单击事件,我们需要把它改掉,进行初始化的设置

    可以先点进去UserForm1的界面,在工具箱的控件中选择“框架”,画出一个框架如图所示

     然后点击“列表框”,在框架中画出一个列表框

     在UserForm1的空白处点击一下,可以预览到大致的效果如图

     我们要对这个框架和列表框的名称进行修改,便于后续的调用操作,于是可以先选中列表框,在左侧的属性栏中,修改“名称”为“Listphone”,再选中框架,修改名称为“selectphone”,再把“caption”修改为“选择手机型号”,这样完成的效果为

     右键点击这个userform1,查看代码,可以把里面的东西都清除干净,然后,选择这个userform1的类型为initialize,补充函数如下

     1 Option Explicit
     2 Dim con As ADODB.Connection
     3 Dim rs As Recordset
     4 
     5 '当窗体加载时显示Android Phone这个列表框的内容
     6 Private Sub UserForm_initialize()
     7 
     8 Set con = New ADODB.Connection
     9 Set rs = New ADODB.Recordset
    10 '建立数据库的连接
    11 Dim mydblocation As String
    12 mydblocation = "数据库地址"
    13 con.Open "provider=microsoft.ace.oledb.12.0;data source=" & mydblocation & "example.accdb"
    14 MsgBox "连接成功"
    15 
    16 '提取不重复的手机类型
    17 Dim sql1 As String           '定义命令字符串变量
    18 sql1 = "select distinct [Android Phone] from [Summary of frame-parallel test]"
    19 rs.Open sql1, con, adOpenKeyset, adLockOptimistic
    20 
    21 Dim i As Integer
    22 With Listphone
    23     .Clear
    24     For i = 1 To rs.RecordCount
    25         .AddItem rs("Android Phone")
    26         rs.MoveNext
    27         
    28     Next i
    29 
    30 End With
    31 End Sub

    函数说明:

    2,3行分别是声明连接对象变量、声明记录集对象变量

    第6行往下就是这函数的正式内容了

    8,9行分别是创建连接对象变量,创建记录集对象变量

    11~14行是建立数据库的连接

    17~19行是用open方法去提取不重复的手机类型,把结果放入记录集rs中

    22是用with + 模块名称,表示操作对象(23行是清除此次之前的列表框中的记录)

    24行是表示开始遍历记录集中数据

    25行说明了要取的rs中的数据

    26行是将记录集中的指针指向下一条记录

    28行是指针+1

    30行,31行是结束with部分和结束函数部分

    样例分析

    此样例是实现了:对任意access数据库的数据表,任选三个字段名为条件进行筛选查询(目前存在的缺陷是数据中如果某字段名的列单元格为空,那么选这个字段为条件就会报错“类型不匹配”)

  • 相关阅读:
    浅谈命令混淆
    为你解惑之Silverlight经典10问详解 (转载)
    Prism 简介
    Prism学习笔记(二)简单的MVVM模式
    Prism学习笔记(一) 从Hello World开始
    修改Oracle数据库序列
    将身份证号转换为年龄
    获取文件类型
    下划线转驼峰
    驼峰转下划线
  • 原文地址:https://www.cnblogs.com/RuiRuia/p/14658420.html
Copyright © 2011-2022 走看看