您好,欢迎来到九壹网。
搜索
您的当前位置:首页Excel编程连接数据库

Excel编程连接数据库

来源:九壹网


Excel一个重要的数据分析平台,自然就少不了与数据库连接。在Excel上就有直接打开数据源的选项,如下图所示:

尽管这种方式用起来很方便,这种连接数据源的方式和其他功能一样,不是很灵活。查到的数据会被放到一个工作表里,并做自动筛选。如果我们有特别的要求,比如希望将数据表的左左上角定位在B10单元格,这种方式就不能满足要求。另外,鉴于SQL的强大,这些“好用”的功能到了高级用户手里就会一无是处。最后,这种方式不能把Excel的数据Insert到数据库中。所以,利用VBA连接并操作数据库就显得很必要了。

要相操纵数据库,首先添加对Microsoft ActiveX Data Objects X.X Library的引用。其中的X.X是版本号。对于本教程使用的功能来讲,版本号是无所谓的——根本用不到那些新功能。这个库是一个把数据库操作对象化的库,使用起来和其他的库很类似。

然后就可以写一个Sub来连接数据库了。首先,需要新建一个连接对象。

Dim con As New ADODB.Connection

注意其中的New关键字用于创建一个新的对象。这也可以写成

Dim con As ADODB.Connection

Set con = New ADODB.Connection

然后,就要设置连接字符串了。在这个例子中,我建了一个Access 2007的数据库mydb来做实验。这样,连接字符串就是:

con.ConnectionString = \"Provider=Microsoft.ACE.OLEDB.12.0;Data

Source=D:\\MyDoc\\Documents\\mydb.accdb\"

当然,如果你连接其他的数据库,连接字符串是不一样的,比如连接SQL Server就可能是

\"Provider=SQLOLEDB;Data name];UID=[user]; pwd=[password]\"

Source=[db source];DATABASE=[db

每种数据库都有自己的连接字符串格式,你需要查阅文档才能知道到底该怎么写这个连接字符串。不过连接字符串的一般格式是一致的,即一组被分号;分开的key=value的项目。Provider是指数据库的驱动类型;Data Source是指数据库文件;Database是指数据库名;UID是用户名;pwd是密码;有的时候,需要用Windows集成帐户校验,这时还要加上Integrated Security=sspi。其外还有很多其他的项目,例如通讯方式,永续化方式,字符编码等。这些项目大多可选,如果不写也可以连上数据库,只有在希望对连接方式进行精细调整的情况下才需要写它们。

设置好了连接字符串后,就可以用以下代码打开数据库

con.Open

最常见的数据库使用方式就是查询了。为了存储查询结果,必须首先新建一个记录集对象。

Dim rs As New ADODB.RecordSet

然后可以定义一条SQL查询语句

queryText = \"select * from Person\"

你可以书写任意复杂的SQL语句,并将其拼成一个字符串。然后,就可以执行查询了。

rs.Open queryText, con

可以看到RecordSet的Open方法在这里接收两个参数,第一个是查询语句字符串,第二个是打开的数据库连接。当执行完这句后,查询结果就已经存储在rs之中了。当然,如果数据量巨大,就会花一些时间。

接下来的工作就是将查询结果从rs中读出,并显示在Excel工作表里。这里首先书写列头。

For i = 1 To rs.Fields.Count

ActiveSheet.Cells(1, i).Value = rs(i - 1).Name

Next

rs内部会有一个游标(Cursor)。刚查询完后,游标指向查询结果的第一条记录。每条记录有若干列,每一列被称为一个域(Field)。rs(index)就是指当前指向记录的第index个域。上面这段代码遍历每一个域,并将其Name显示出来,放到工作表第一行的对应列中。需要注意,Office的库中的索引一般从1开始计数,而数据库的索引都是从0开始计数的(因为它们都是用C/C++开发的)。所以rs的索引要用i-1。执行效果如下:

接下来就是遍历每条记录,将所有的数据显示出来。

r = 2

While (Not rs.EOF)

For i = 1 To rs.Fields.Count

ActiveSheet.Cells(r, i).Value = rs(i - 1).Value

Next

rs.MoveNext

r = r + 1

Wend

遍历以rs.EOF=false为条件。当EOF=true时,就说明游标已经到了所有查询结果的末尾。对于每一条记录,可以用rs(index).Value获取它的值。处理完一条记录后,用rs.MoveNext来将游标定位在下一条记录。执行后,可以看到效果:

当然,如果你想直接把rs的所有数据显示在单元格里有更简单的做法。比如希望显示位置的左上角在A2单元格,直接写一句Range.copyFromRecordSet就可以了。

Range(\"A2\").CopyFromRecordset rs

这个和上面显示数据的效果完全相同。不过它不会帮你把列头显示出来。

好了,说完了读取数据库,再说说修改数据库。修改数据库有Insert,Update和Delete三种。可以书写SQL语言直接进行这种操作。这里以Insert为例。在数据库连接打开后,直接用Connection.Execute来执行一个修改数据库的SQL命令,如下所示。

con.Execute \"Insert Into Person(PName, Gender) Values('Linda', 'F')\"

就能将数据插入到数据表中。因为PID在这个例子中是自动生成的,所以可以不用为它赋值。执行这条指令后,就会在数据库中看到下面的效果

然而RecordSet为我们提供了更方便的方式。在查询完成之后,我们可以直接对RecordSet进行修改,比如:

rs(\"PName\").Value = \"New Name\" 'modify the current record

...

rs.AddNew 'add a new record

rs(\"PName\").Value = \"Ivy\"

rs(\"Gender\").Value = \"M\"

...

rs.Delete 'delete the current record

等等。最后执行

rs.Update

RecordSet就会根据我们的修改,自动将插入,删除,和更新应用到数据库里。所以如果希望将工作表数据导入到数据库,就可以直接将数据放到一个空白的数据集中,然后再Update即可。当然SQL Server的T-SQL有更加方便的语句Open Source可以直接导入Excel数据。不过因为这是VBA教程,就不介绍它了。

不过为了使得这种修改可以执行,必须在rs被打开时指定可进行读写操作。就是说必须书写Record.Open的第四个参数。下面具体说一下其第三个和第四个参数的含义。

rs.Open queryText, connection,cursorMode, lockMode

其中cursorMode可以是:

0 = adOpenForwardOnly 打开仅向前类型游标。

1 = adOpenKeyset 打开键集类型游标。

2 = adOpenDynamic 打开动态类型游标。

3 = adOpenStatic 打开静态类型游标。

而lockMode可以是:

1 = adLockReadOnly (默认值)只读 — 不能改变数据。

2 = adLockPessimistic 保守式锁定(逐个) — 在编辑时立即锁定数据源的记录。

3 = adLockOptimistic 开放式锁定(逐个) — 只在调用 Update 方法时才锁定记录。

4 = adLockBatchOptimistic 开放式批更新 — 用于批更新模式(与立即更新模式相对)。

所以lockMode的默认值不允许rs.Update,需要手动设置一个可以修改的lockMode。

程序的最后请务必记住要关闭数据库连接。

conn.Close

另外,最好将两个对象的引用取消掉,使其可以释放空间:

conn=Nothing

rs=Nothing

这样做可以避免资源的浪费。

因篇幅问题不能全部显示,请点此查看更多更全内容

Copyright © 2019- 91gzw.com 版权所有 湘ICP备2023023988号-2

违法及侵权请联系:TEL:199 18 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务