明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
查看: 4777|回复: 19

[LISP]请教如何用LISP读写Access数据库

  [复制链接]
发表于 2004-10-15 21:57:00 | 显示全部楼层 |阅读模式
本帖最后由 作者 于 2004-10-16 11:53:38 编辑

在发表此帖之前,我先要感谢辉兄的帮助!           陈四清 chen4@py.gov.cn

在作城市地理测绘信息工作处理时要用到大量的坐标数据记录和基础情报资料(一般是成千上万条记录),这些资料现都是用Access数据库存放处理的,在作CAD成图处理时,本人太过愚钵,只会autolisp语言,且只会读写TXT文本文件,所以每次成图前不得不多次转换,麻烦而易出差错,在明经上看到郑先生<< VLISP应用技巧Visual LISP中使用ADO接口与MS-Access相连接>>的一文,很感兴趣,但试验了多次,老出错误,前几天,在辉兄的关照下,

给你一段程序,你看看,建议从主函数开始理解(C:TEST),用你给我的数据库,注意路径为E:/AAA.MDB,

(defun DbInitADO ( / ADO_DLLPath)
(if (null adom-Append)
(progn
(setq ADO_DLLPath
(strcat (getenv "systemdrive")
"\\Program Files\\Common Files\\System\\Ado\\")
)
;;
如果查找到类型库 ...
(if (findfile (strcat ADO_DLLPath "msado15.dll")) ;;
将其输入
(vlax-Import-Type-Library
:tlb-filename (strcat ADO_DLLPath "msado15.dll")
:methods-prefix "adom-"
:properties-prefix "adop-"
:constants-prefix "adok-"
)
;;
找不到时,则通知操作者
(alert (strcat "
不能找到以下文件\n" ADO_DLLPath "msado15.dll"))
)
)
)
)


;
生成MS-Access MS-SQL Server 数据库的连接字符串
;;;******************************************************************
;;;
使用ODBC(不需要DSN)连接MS-Access数据库
;;;
示例: (DbConnect_MSAccess1 "d:/dbfiles/products.mdb")
;;;******************************************************************

(defun DbConnect_MSAccess1 (dbFile)
(strcat
"Provider=MSDASQL;"
"Driver={Microsoft Access Driver (*.mdb)};"
"DBQ=" dbFile
)
)

;
从内存中释放VLA对象
(defun MxRelease (xObject)
vlax-object-released-p
(if (not (vlax-object-released-p xObject))
(vlax-Release-Object xObject)
)
)

;
关闭ADO Connection 对象并将内存释放出来
(defun DbCloseConnection (dbConnObject)
(vlax-Invoke-Method dbConnObject "Close")
(MxRelease dbConnObject)
)

;
关闭ADO RecordSet对象并将内存释放出来
(defun DbCloseRecordset (rsObject)
(vlax-Invoke-Method rsObject "Close")
(MxRelease rsObject)
)

;
布尔测试RecordSet 是否为 Closed (T nil)
(defun DbRsIsClosed (rsObject)
(= adok-adStateClosed (vlax-Get-Property rsObject "State"))
)

;
返回一个ADO RecordSet对象中的记录数
(defun DbRsCount (rsObject)
(vlax-Get-Property rsObject "RecordCount")
)

;
返回Field对象中给定字段数的字段名称
(defun DbGetFields (fObject fCount / FieldNumber)
(setq FieldNumber -1)
(while (> fCount (setq FieldNumber (1+ FieldNumber)))
(setq FieldList (cons (vlax-Get-Property (DbRsFieldItem FieldsObject FieldNumber) "Name") FieldList)); setq
); end while
); defun

;
RecordSet对象返回ADO Field对象
(defun DbRsFields (rsObject)
(vlax-Get-Property rsObject "Fields")
)

;
返回给定Field对象的字段数量
(defun DbRsFieldCount (fObject)
(vlax-Get-Property fObject "Count")
)

;
获取Field对象的字段名()
(defun DbRsFieldItem (fObject fNumber)
(vlax-Get-Property fObject "Item" fNumber)
)

;
返回RecordSet对象的RowSet对象
(defun DbRsGetRows (rsObject)
(vlax-Invoke-Method rsObject "GetRows" adok-adGetRowsRest)
)

;
应用一个ADO LOCK(锁定)类型到给定的RecordSet对象
(defun DbRsLockType (rsObject lockType)
(cond
( (= (strcase lockType) "OPTIMISTIC")
(vlax-Put-Property rsObject "LockType" adok-adLockOptimistic)
)
( (= (strcase lockType) "BATCHOPTIMISTIC")
(vlax-Put-Property rsObject "LockType" adok-adLockBatchOptimistic)
)
( (= (strcase lockType) "READONLY")
(vlax-Put-Property rsObject "LockType" adok-adLockReadOnly)
)
)
)

(defun Search(RSObject / lst FieldsObject FieldCount FieldList ReturnValue)
(defun getlst (var)
(setq lst nil)
(setq n (length var) i 0)
(while (< i n)
(setq lst (append lst (list (vlax-variant-value (nth i var)))))
(setq i (1+ i))
)
lst
)
(setq FieldsObject (DbRsFields RSObject) ;;
将字段作为对象
FieldCount (DbRsFieldCount FieldsObject) ;;
取得列的数量
FieldList (DbGetFields FieldsObject FieldCount) ;;
取得列表中所有列的名称
ReturnValue (list (reverse FieldList))) ; setq
(setq lst (vlax-safearray->list (vlax-variant-value (dbrsgetrows rsobject))))
(setq lst (mapcar 'getlst lst))
(setq lst (mapcar '(lambda(var1 var2) (append (list var1) (list var2))) (car returnvalue) lst))
(print lst)
)

;A sample...
(defun c:test (/ getlst dbconnection rsobject SqlString)
(DbInitADO) ;
初始化
(setq DBConnection (vlax-create-object "adodb.connection")) ;
创建并返回ADO Connection对象
(setq RSObject (vlax-create-object "adodb.recordset")) ;
创建并返回ADO RecordSet对象
(setq SqlString "select
点号,横坐标,纵坐标,井盖高 from pspoint")
(vlax-invoke-method DBConnection "open" (DbConnect_MSAccess1 "e:\\AAA.mdb") "admin" "" adok-adConnectUnspecified)
(vlax-invoke-method RSObject "open" SqlString DBConnection nil nil adok-adcmdtext)
(search rsobject)
(DbCloseRecordset rsobject)
(DbCloseConnection dbconnection)
(princ)
)

        meflying@mjtd.com
          2004-10-10

(经过辉兄的提醒,所述错误仅是一种表象,为减少网友的阅读负担,现删除太长的错误传述,而保留正确的程序,供各位网友使用)!

发表于 2004-10-16 08:39:00 | 显示全部楼层
昨天给你发的邮件没看到吗???
 楼主| 发表于 2004-10-16 11:42:00 | 显示全部楼层
辉兄:


  昨晚发帖时,查了一下邮箱,还没有信件。今早已经有了,刚才试验了一下,特别好用,我前两天是刚看到了表面现象,没有往文件里去调用,所以犯了错误,同时我也提醒各位网友注意:


  此程序很好,很实用的,大家尽可以放心地下载(复制即可)使用,我所说的“数据溢出错误”是不存在的,这是CAD文本编辑器的显示局限的表象,不要再被其迷惑。在这里,我、同时也代表得益于明经通道的朋友,再次感谢辉兄和各位版主的帮助和努力!


  我的下一个问题是我从CAD的图件上取了大量的图形群码数据(类似于X Y Z的坐标),如何将这些数据写入数据库中(规定字段的长度或其他格式)?


  还请辉兄及各位高手帮忙。


             陈四清 2004-10-16 午时二刻
发表于 2004-10-16 12:29:00 | 显示全部楼层
要写,你得先把数据库格式做好了,包括表名,关键字,字段名等等,,,这样的方法是不能新建数据库文件的...


其实读和写都是一样的操作,唯一不同就在里面的SQL语句,可以参考一下有关SQL语句的资料
 楼主| 发表于 2004-10-16 19:04:00 | 显示全部楼层
还是请辉兄,用我原来的数据库清空后,将现在lst表中的数据作一个写入操作的lisp程序吧。多谢谢了! 
发表于 2004-10-17 08:34:00 | 显示全部楼层
原来有很多数据的,你要写哪几项?你最好给一些原始数据吧
发表于 2006-5-17 12:06:00 | 显示全部楼层

请问meflying大侠:

(vlax-invoke-method RSObject "open" SqlString DBConnection nil nil adok-adcmdtext)

我拷来运行时到这一句就出错呢!

是不是没有数据啊

发表于 2006-5-18 10:02:00 | 显示全部楼层
发表于 2006-5-18 11:11:00 | 显示全部楼层
nameld001发表于2006-5-17 12:06:00 <FONT face=\"Times New Rom...

数据库的位置还有关键字改了没有?
发表于 2006-5-24 19:52:00 | 显示全部楼层
我看了下,OK了,就是不知道怎才能把数据写进,请楼上高手指点
您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|手机版|CAD论坛|CAD教程|CAD下载|联系我们|关于明经|明经通道 ( 粤ICP备05003914号 )  
©2000-2023 明经通道 版权所有 本站代码,在未取得本站及作者授权的情况下,不得用于商业用途

GMT+8, 2024-11-6 07:09 , Processed in 0.220776 second(s), 26 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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