设为首页收藏本站Access中国

Office中国论坛/Access中国论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

12下一页
返回列表 发新帖
查看: 4203|回复: 10
打印 上一主题 下一主题

关于ADO理解的一些疑问

[复制链接]
跳转到指定楼层
1#
发表于 2011-10-27 10:15:45 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 williamwangc 于 2011-10-27 10:18 编辑

正如本人这个板块发的一些帖子,本人正在研究EXCEL中间数据的引用。roych版主也给了我不少建议和帮助。现在正在尝试使用ADO连接其它程序,如EXCEL。在翻看了不少参考书后,我想问以下几个问题:
首先我们先假设正在被使用ACCESS为甲方,另一个准备被引用的ACCESS或EXCEL为乙方。
1、ADO连接引擎到底是由甲方决定还是乙方决定?比方我用Provider=Microsoft.ACE.OLEDE.12.0是连接的是一个2007的数据库,那么我连接EXCEL应该用什么呢?
2.ADO连接引擎是双向的还是单向的?比如说我只能从甲方往乙方输入数据还是,既可以输入数据也可以引用数据?
3、如果是连接EXCEL,那么ADO模型如何转换呢?还是直接使用Excel.Application的VBA模型。
4、ADO打开对象的原理是什么?它是否像GETOBJECT真的打开对象?很占内存的说。
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏1 分享分享 分享淘帖 订阅订阅
2#
发表于 2011-10-27 19:48:20 | 只看该作者
1、ADO是客户端使用滴,无所谓甲方乙方。数据连接引擎应当以低版本来处理,否则低版本用户可能无法使用该项程序。这一点就好比你上传了2010版本的文件,使用2003版本的高手就无法打开这个文件,从而无法及时帮你解决问题。
2、ADO一般是用于快速读取数据,不建议多用户同时对数据进行操作,之前遇见过“记录集已打开”的错误提示,是否和这个有关,暂未确定。操作数据,建议用查询和绑定窗体等来完成。
3、直接通过ConnectionString就可以了,声明数据库引擎,版本,路径等相关信息即可。不必打开通过创建组件等方式打开Excel表。
4、其原理在于建立数据连接,通过对数据连接进行快速读取。另一个问题见回答3。至于内存的说法,以下是一段经典的评论:
“……相对于Excel对象,ADO的速度更快。Excel对象强迫Excel应用程序在后台加载。既消耗内存,又消耗处理器周期。同时,用户每次在Excel中引用一段信息,就必须耗费昂贵的未集成到进程的调用。相对于Access而言,当用户需要获取部分信息的时候,ADO运行同样订的程序将会节省大量资源。
“然而,从一个实际的观点上看,除非用户处理大量数据,或者运行实时应用程序,否则看不出来什么太大的区别。处理数据的逻辑没有什么不同。”
3#
 楼主| 发表于 2011-10-27 20:29:01 | 只看该作者
本帖最后由 williamwangc 于 2011-10-27 20:43 编辑
3、直接通过ConnectionString就可以了,声明数据库引擎,版本,路径等相关信息即可。不必打开通过创建组件等方式打开Excel表。

那我是否可以这样理解,如果说ADO是客户端使用的。如果我要用ADO进行EXCEL和ACCESS的数据交换,需要使用两个connectionstring,本人客户端作为中转站进行转接呢?
上次我发给你的问题我已经解决了。我还是使用的是EXCEL对象模型。还有啊,上次在SQL对象中不能引用函数中参数的原因我想可能有两种可能。
1、我觉得最有可能的就是我关闭了excel对象的关系,内存被释放了。所以我这次是在ADO的recordset对象遍历了之后才关闭excel,获得了成功。此外,我在考虑是否可以声明一个TYPE变量,将函数中获得的字符串,保存在一段内存之中呢,是否可行呢?但我又考虑到一个问题,我要引用先后引用两个单元格的值,这样是否能两次分别存进这段内存,遍历之后再消除。该如何处理呢?
2、cell().value不是标准的对象,参数不可被后面的SQL语句直接辨认。可能是这个原因。
4#
 楼主| 发表于 2011-10-27 20:49:13 | 只看该作者
本帖最后由 williamwangc 于 2011-10-27 20:55 编辑
  1. Private Sub Command1_Click()
  2. Dim rst As New ADODB.Recordset
  3. Dim cnn As New ADODB.Connection
  4. Dim appExcel As New Excel.Application
  5. Dim wk As Excel.Workbook
  6. Dim ws As Excel.Worksheet
  7. Set wk = appExcel.Workbooks.Add(CurrentProject.path & "\导入资料.xls")
  8. Set ws = wk.Sheets(1)
  9. rst.Open "资料", CurrentProject.Connection, adOpenDynamic, adLockOptimistic
  10. Do While Not rst.EOF
  11. If Nz(rst!学校) = "" Then
  12. rst!学校 = ws.Cells(2, 2).Value
  13. rst.Update
  14. End If
  15. If Nz(rst!班级) = "" Then
  16. rst!班级 = ws.Cells(4, 2).Value
  17. rst.Update
  18. End If
  19. rst.MoveNext
  20. Loop
  21. rst.Close
  22. wk.Close
  23. End Sub
复制代码
这是我完成的代码。不足之处请指正。
版主是否可以把握这段代码的意思用ADO完成一个类似例子呢?我参考用ADO连接EXCEL,更新ACCESS中的数据。
PS.以上代码中CNN其实后来没用。忘记删除了。
5#
 楼主| 发表于 2011-10-27 22:42:33 | 只看该作者
本帖最后由 williamwangc 于 2011-10-27 22:45 编辑
  1. Private Sub Command2_Click()
  2. Dim rst2 As New ADODB.Recordset
  3. Dim cnn1 As New ADODB.Connection
  4. Dim st As String
  5. cnn1.Open "provider=microsoft.jet.oledb.4.0;extended properties= excel 8.0;data source=C:\Users\wangcheng\Documents\exceld导入测试\导入资料.xls"
  6. st = Sheet1.Cells(2, 8).Value
  7. Debug.Print st
  8. cnn1.Close
  9. End Sub
复制代码
做了一个EXCEL的连接测试。到cnn1.open似乎是连上这个表了。后面我就不知道怎么直接引用这个表的内容了?
PS.我cnn1是(还有几个变量还未声明,1结尾的都是连接EXCEL表的)准备连接表的。
rst2准备连接数据库的。
6#
发表于 2011-10-28 03:04:37 | 只看该作者
关于Excel中的ADO部分,我曾写过一个例子,你先参考下:
http://www.office-cn.net/thread-96398-1-1.html
以下代码在Access中执行(俺{:soso_e147:},该{:soso__4963104980311759478_2:}了,因此代码暂未测试,请自行测试后再告知问题的所在,最好传上附件)。
  1. Private Sub Command2_Click()
  2. Dim rst2 As New ADODB.Recordset
  3. dim rst1 As New ADODB.Recordset
  4. Dim cnn1 As New ADODB.Connection
  5. Dim st As String
  6. cnn1.Open "provider=microsoft.jet.oledb.4.0;extended properties= excel 8.0;data source=C:\Users\wangcheng\Documents\exceld导入测试\导入资料.xls"
  7. '如果SQL过于复杂,则建议使用别名处理。例如Select A.A1 from [Sheet1$A3:D100] As A"。
  8. rst1.Open "Select * from [Sheet1$A3:D100]",cnn1,adOpenDynamic, adLockOptimistic
  9. rst2.Open "测试表",CurrentProject.Connection,adOpenDynamic, adLockOptimistic
  10. Do until rst1.EOF
  11. rst2.AddNew
  12. rst2(0)=rst1(0)
  13. ………………
  14. rst2.Update
  15. Loop
  16. rst1.Close
  17. Set rst1=Nothing
  18. cnn1.Close
  19. Set rst1=Nothing
  20. rst2.Close
  21. Set rst2=Nothing
  22. End Sub
复制代码
不过这样导入数据稍嫌麻烦。。。
7#
 楼主| 发表于 2011-10-28 07:42:40 | 只看该作者
谢谢斑竹。我参考看看。
8#
 楼主| 发表于 2011-10-28 18:24:30 | 只看该作者
调试中发现了两个问题:
1、当我打开ACCESS编辑vba过程中,EXCEL就无法访问,我是否可以理解为连接已经成功。
2、打开连接后我是否只能按照你的方法建立recordset呢?我只要引用某个单元格的值就可以了。不需要引用很大一块区域。如果我像你这样SELECT一段区域,似乎实际是无用的,因为没有标题的这一行的嘛。
另外,我又有了些感想
利用ADO,似乎克服了DOCMD.TRANSFORMSPREADSHEET不能引用不相邻区域的缺点。不知道这样理解是否正确。
9#
发表于 2011-10-29 03:55:36 | 只看该作者
1、连接成功后自然就无法对Excel写入数据了。
2、只需要某个单元格的话,可以有几种方法来处理:
a、链接表。——即便Excel表不规则,也是可以读取某行某列的值的。然后通过ADO来读取这个值进行下一步操作。
b、在Excel中处理。新建一个标准表,用公式引用过来(如果不嫌麻烦的话,你也可以写Excel宏处理),再链接表。
c、如果有固定规律,可以用我以上的select语句,具体需要根据Where条件进行预处理。
关于不连续区域:
a、DOCMD.TRANSFORMSPREADSHEET的参数里有个Range(范围)是可以指定区域的。
b、DOCMD.TRANSFORMSPREADSHEET和ADO对于不连续区域的操作的不同之处在于,前者需要多次执行,才能把不同区域的数据导入到表中(而且还得注意不能把前面数据给覆盖掉);而后者,则可以通过对不同的块进行联合查询,然后再一次性导入(或者说追加)。
10#
 楼主| 发表于 2011-10-29 08:47:49 | 只看该作者
做一个链接表啊?似乎可行。我好好想想。
关于不连续区域,a的回答。range范围我也知道。但不连续区域该如何表示呢?我曾经试着在excel中随便取个公式,划定一块不连续区域,看它如何表达。然后我再引用这种表达的方式,但似乎DOCMD无法辨识。另外,如果将这不连续区域重命名之后,似乎它也认不出来的样子。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

QQ|站长邮箱|小黑屋|手机版|Office中国/Access中国 ( 粤ICP备10043721号-1 )  

GMT+8, 2024-11-14 15:24 , Processed in 0.084566 second(s), 34 queries .

Powered by Discuz! X3.3

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表