lazybug 发表于 2009-5-7 16:11:00

[求助(已解决)]用lisp读取Excel文件中指定单元格的数据

本帖最后由 作者 于 2009-5-25 20:33:40 编辑 <br /><br /> <p><br/>通过在明经、晓东里边转了一圈又一圈之后终于能从Excel里边把单元格的数据读出来了。但是,还有个大问题解决不了:<br/>1.<br/>(vla-put-visible xlapp 1);1-可见,0-隐藏<br/>这一句把所有打开的Excel文件都给隐藏掉了!!!!!</p><p>2.同样的<br/>(vlax-invoke-method xlapp 'quit)<br/>这一句把所有打开的Excel文件都给关掉了!!!!!!!!!!!!</p><p><br/>如何处理,能够让我可以把数据读出来且不影响其它打开的Excel文件?或者这么说:是否可以不打开指定的Excel文件就能将其中的数据读出来?</p><p>各位大神给伸伸手指点下吧,谢谢啦……</p><p></p><p>(defun excel-get-data (/ xlapp xlfile fn H8)<br/>&nbsp; (vl-load-com)<br/>&nbsp; ;读取单元格数据<br/>&nbsp; (defun Excel-Get-CellValue(xlapp cell / xlsrng xlsval)<br/>&nbsp;&nbsp;&nbsp; (setq xlsrng (vlax-get-property xlapp "range" cell))<br/>&nbsp;&nbsp;&nbsp; (setq xlsval (vlax-variant-value (vlax-get-property xlsrng "Value")))<br/>&nbsp; ) <br/>&nbsp; (setq xfile (getfiled "打开法兰计算文件" "" "xls" 8))<br/>&nbsp; (if (setq fn (findfile xfile))<br/>&nbsp;&nbsp;&nbsp; (if (setq xlapp (vlax-get-or-create-object "Excel.Application"))<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (progn<br/>&nbsp;(vlax-invoke-method<br/>&nbsp;&nbsp; (vlax-get-property xlapp 'WorkBooks)<br/>&nbsp;&nbsp; 'Open<br/>&nbsp;&nbsp; fn<br/>&nbsp;)<br/>&nbsp;(vla-put-visible xlapp 0);1-可见,0-隐藏<br/>&nbsp;<br/>&nbsp;;单元格数据读取<br/>&nbsp;(setq H8 (Excel-Get-CellValue xlapp "H8"))<br/>&nbsp;<br/>&nbsp;;退出并关闭Excel进程<br/>&nbsp;(vlax-invoke-method xlapp 'quit)<br/>&nbsp;(vlax-release-object xlapp)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; )<br/>&nbsp;&nbsp;&nbsp;&nbsp; )<br/>&nbsp;&nbsp;&nbsp; )<br/>&nbsp; H8<br/>)</p><p><br/>&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;</p><p>问题已解决<br/>下面是测试的程序:</p><p>;;;取出Excel文件中第一个工作表中指定单元格的数据<br/>(defun c:ttt ()<br/>&nbsp; (Excel-Get-data)<br/>)</p><p>(defun Excel-Get-data ( / xfile cell ADOCONNECT ADORECORDSET ConnectionString lst Sheet-name source cell-tmp cell-value)<br/>&nbsp; ;指定单元格的数据<br/>&nbsp; (defun Excel-Get-CellValue (Sheet-name cell)<br/>&nbsp;&nbsp;&nbsp; (setq source (strcat "SELECT * FROM [" Sheet-name cell":" cell "]"))<br/>&nbsp;&nbsp;&nbsp; (vlax-invoke-method&nbsp; ADORecordset "Open" source ADOConnect 1 3 nil)<br/>&nbsp;&nbsp;&nbsp; (setq cell-tmp (vlax-safearray-&gt;list (vlax-variant-value (vlax-invoke-method ADORecordset "GetRows" 1))))<br/>&nbsp;&nbsp;&nbsp; (vlax-variant-value (car (car cell-tmp)))&nbsp; <br/>&nbsp; )</p><p>&nbsp; (setq xfile (getfiled "打开法兰计算文件" "" "xls" 8))<br/>&nbsp; (setq ADOConnect (vlax-get-or-create-object "ADODB.Connection"))<br/>&nbsp; (setq ADORecordset (vlax-get-or-create-object "ADODB.Recordset"))<br/>&nbsp; (setq ConnectionString (strcat "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" xfile ";Extended Properties=;Excel 8.0;HDR=No" ))<br/>&nbsp; (if (not<br/>&nbsp;(vl-catch-all-error-p<br/>&nbsp;&nbsp; (vl-catch-all-apply<br/>&nbsp;&nbsp;&nbsp;&nbsp; (function vlax-invoke-method)<br/>&nbsp;&nbsp;&nbsp;&nbsp; (list ADOConnect "Open" ConnectionString&nbsp; "admin" "" nil)<br/>&nbsp;&nbsp; )<br/>&nbsp;)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; )<br/>&nbsp;&nbsp;&nbsp; (progn<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (setq lst<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (vlax-safearray-&gt;list<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (vlax-variant-value<br/>&nbsp;&nbsp; (vlax-invoke-method (vlax-invoke-method ADOConnect "OpenSchema" 4 ) "GetRows" 1)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; )<br/>&nbsp;&nbsp;&nbsp;&nbsp; )<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; )<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (setq Sheet-name (vlax-variant-value (car (caddr lst))));确定"第一个"工作表的名称<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (setq cell-value (Excel-Get-CellValue Sheet-name "H16"));H16单元格<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (vlax-invoke-method ADORecordset "Close")<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (vlax-invoke-method ADOConnect "Close")<br/>&nbsp;&nbsp;&nbsp; )<br/>&nbsp;&nbsp;&nbsp; (progn<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (princ "\n打开Excel数据文件出错")<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (vl-catch-all-apply 'vlax-invoke-method (list ADOConnect "Close"))<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (setq cell-value nil)<br/>&nbsp;&nbsp;&nbsp; )<br/>&nbsp; )<br/>&nbsp; (vlax-release-object ADORecordset)<br/>&nbsp; (vlax-release-object ADOConnect)<br/>&nbsp; cell-value<br/>) </p><p></p><p>&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;</p><p>不用ADO原来也是可以实现的</p>&nbsp;;退出并关闭Excel进程<br/>&nbsp;(vlax-invoke-method xlapp 'quit)<br/>&nbsp;(vlax-release-object xlapp)<p>上边两句改成以下内容即可</p><p>;退出并关闭Excel文件<br/>&nbsp;(vlax-invoke-method<br/>&nbsp;&nbsp; (vlax-get-property xlapp 'ActiveWorkbook)&nbsp;&nbsp; <br/>&nbsp;&nbsp; 'close<br/>&nbsp;)</p>

lazybug 发表于 2009-5-17 14:33:00

lkt209发表于2009-5-15 13:08:00static/image/common/back.gif注意隐藏的不是xlapp这是程序对象隐藏的是xfile打开的文件对象搞错了!

<p>xfile为lisp下的文件名,怎么变成vl对象?</p><p>PS:<strong><font face="Verdana" color="#da2549">感谢</font></strong><strong><font face="Verdana" color="#da2549">lzh741206版主</font></strong></p><p>另,参照<a href="http://www.mjtd.com/bbs/dispbbs.asp?boardid=3&amp;replyid=567&amp;id=73343&amp;page=1&amp;skin=0&amp;landlord=0&amp;Star=2">http://www.mjtd.com/bbs/dispbbs.asp?boardid=3&amp;replyid=567&amp;id=73343&amp;page=1&amp;skin=0&amp;landlord=0&amp;Star=2</a>处的程序,我已经基本上写好我需要的“不打开指定的Excel文件就能将其中指定单元格的数据读出来”,程序在一楼,有兴趣的朋友可以去看看。</p>

渠辉 发表于 2022-7-11 16:00:46

本帖最后由 渠辉 于 2022-7-16 15:16 编辑

(defun Excel:ReadRange (range / array) (setq value (vlax-get-property range 'Value2)) (if (= (vlax-variant-type value) 8204) (mapcar '(lambda (x) (mapcar 'vlax-variant-value x)) (vlax-safearray->list (vlax-variant-value value)) ) (vlax-variant-value value) ) )

modernyoung 发表于 2009-5-7 21:35:00

<p></p><p></p><p>(SETQ AA(msxl-GET-value1<br/>&nbsp;(msxl-get-range *XLAPP*&nbsp; "A1")</p><p>&nbsp;))</p><p>(vlax-variant-value AA)</p><p>提取A1单元格的数据</p>

lazybug 发表于 2009-5-7 23:18:00

<p>能给出完整程序么?</p><p></p><p>msxl-GET-value1,这个函数貌似加载不了<br/></p>

lazybug 发表于 2009-5-8 08:18:00

<p>把二楼的程序修改了一下,可以执行了。本质上这个和<a href="http://www.mjtd.com/Develop/ArticleShow.asp?ArticleID=667"><font color="#000000">http://www.mjtd.com/Develop/ArticleShow.asp?ArticleID=667</font></a>&nbsp;的程序是一样的,具体表现形式和我一楼的程序也是一样的。还是做不到“不打开指定的Excel文件就能将其中的数据读出来”。还请高手们指点指点。</p><p>(defun Excel-Get-CellValue (xlapp cell /)<br/>&nbsp;&nbsp;&nbsp; (vlax-variant-value (msxl-GET-value (msxl-get-range xlapp&nbsp; cell)))<br/>&nbsp; )</p>

飞诗(fsxm) 发表于 2009-5-8 12:01:00

<p>乍有可能不打开文件就能读取数据了?</p><p>谁都不能做的的!只是看你如何打开而已吧?</p><p>原来的excel程序是打开的,你就不要quit!</p><p>原来的文档是打开的你就不要close!</p><p>否则,就该乍的就乍的!这不就实现了不影响其它打开的Excel文件!</p>

lazybug 发表于 2009-5-8 13:02:00

<p>咋就木有可能呢?</p><p>自己做不到不代表谁都做不到的,不然为啥上明经来问呢,不就是因为咱明经高人多么!</p><p>原来的文档不要close,我现在就是这么做的。</p><p>但是,做程序不就是要追求完美一些么?</p><p>老想着让用户该乍的就乍的,不再程序上下功夫是要不得的!!!!!!!</p><p></p>

Saging 发表于 2009-5-8 13:36:00

<p>如果楼主会VBA可以测试一下,VBA不用EXCEL.APPLICATION而是直接调用里的WORKSHEETS等对象,但只要调用了EXCEL类里的东西,就可以在任务管理器里看到EXCEL.EXE进程,所以如果不打开EXCEL文件而读取里面的内容应该是不可能的。</p><p>不过好像可以用数据库的SQL语句调用EXCEL数据库。具体怎么做就不是很清楚了。</p>

lazybug 发表于 2009-5-9 00:24:00

<p>那就是说,应该还是有可能不打开EXCEL文件而读取里面的内容的~!只是会的人现在还没看到我的帖子罢了</p><p></p>

chpmould 发表于 2009-5-9 12:43:00

顶出个高手出来!

modernyoung 发表于 2009-5-9 13:05:00

<p>不打开当然读写不了数据,只是可以打开但不显示,表面上是不打开。</p><p>(Defun vlxls-app-open(XLSFile UnHide / ExcelApp WorkSheet Sheets ActiveSheet Rtn)<br/>&nbsp; ;;;function: this program can open an excelfile<br/>&nbsp; (setq XLSFile (strcase XLSFile))<br/>&nbsp; (if (null (wcmatch XLSFile "*.XLS"))<br/>&nbsp; (setq XLSFile (strcat XLSFile ".XLS")))<br/>&nbsp; (if (and (findfile XLSFile)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (setq Rtn (vlax-get-or-create-object "Excel.Application")))<br/>&nbsp;&nbsp;&nbsp; (progn (vlax-invoke-method (vlax-get-property Rtn 'WorkBooks)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 'Open XLSFile)<br/>&nbsp;(if UnHide<br/>&nbsp;&nbsp;&nbsp; (vla-put-visible Rtn 1)<br/>&nbsp;&nbsp;&nbsp; (vla-put-visible Rtn 0))))<br/>&nbsp; Rtn)</p><p></p><p>(setq *xlapp* (vlxls-app-open "C:/test.XLS"&nbsp; nil))</p><p>(SETQ AA(msxl-GET-value1<br/>&nbsp;(msxl-get-range *XLAPP*&nbsp; "A1")</p><p>&nbsp;))</p><p>(vlax-variant-value AA)</p><p>(vlax-invoke-method&nbsp;*xlapp* &nbsp;'QUIT) 关闭程序</p>
页: [1] 2 3 4
查看完整版本: [求助(已解决)]用lisp读取Excel文件中指定单元格的数据