[求助(已解决)]用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/> (vl-load-com)<br/> ;读取单元格数据<br/> (defun Excel-Get-CellValue(xlapp cell / xlsrng xlsval)<br/> (setq xlsrng (vlax-get-property xlapp "range" cell))<br/> (setq xlsval (vlax-variant-value (vlax-get-property xlsrng "Value")))<br/> ) <br/> (setq xfile (getfiled "打开法兰计算文件" "" "xls" 8))<br/> (if (setq fn (findfile xfile))<br/> (if (setq xlapp (vlax-get-or-create-object "Excel.Application"))<br/> (progn<br/> (vlax-invoke-method<br/> (vlax-get-property xlapp 'WorkBooks)<br/> 'Open<br/> fn<br/> )<br/> (vla-put-visible xlapp 0);1-可见,0-隐藏<br/> <br/> ;单元格数据读取<br/> (setq H8 (Excel-Get-CellValue xlapp "H8"))<br/> <br/> ;退出并关闭Excel进程<br/> (vlax-invoke-method xlapp 'quit)<br/> (vlax-release-object xlapp)<br/> )<br/> )<br/> )<br/> H8<br/>)</p><p><br/>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>></p><p>问题已解决<br/>下面是测试的程序:</p><p>;;;取出Excel文件中第一个工作表中指定单元格的数据<br/>(defun c:ttt ()<br/> (Excel-Get-data)<br/>)</p><p>(defun Excel-Get-data ( / xfile cell ADOCONNECT ADORECORDSET ConnectionString lst Sheet-name source cell-tmp cell-value)<br/> ;指定单元格的数据<br/> (defun Excel-Get-CellValue (Sheet-name cell)<br/> (setq source (strcat "SELECT * FROM [" Sheet-name cell":" cell "]"))<br/> (vlax-invoke-method ADORecordset "Open" source ADOConnect 1 3 nil)<br/> (setq cell-tmp (vlax-safearray->list (vlax-variant-value (vlax-invoke-method ADORecordset "GetRows" 1))))<br/> (vlax-variant-value (car (car cell-tmp))) <br/> )</p><p> (setq xfile (getfiled "打开法兰计算文件" "" "xls" 8))<br/> (setq ADOConnect (vlax-get-or-create-object "ADODB.Connection"))<br/> (setq ADORecordset (vlax-get-or-create-object "ADODB.Recordset"))<br/> (setq ConnectionString (strcat "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" xfile ";Extended Properties=;Excel 8.0;HDR=No" ))<br/> (if (not<br/> (vl-catch-all-error-p<br/> (vl-catch-all-apply<br/> (function vlax-invoke-method)<br/> (list ADOConnect "Open" ConnectionString "admin" "" nil)<br/> )<br/> )<br/> )<br/> (progn<br/> (setq lst<br/> (vlax-safearray->list<br/> (vlax-variant-value<br/> (vlax-invoke-method (vlax-invoke-method ADOConnect "OpenSchema" 4 ) "GetRows" 1)<br/> )<br/> )<br/> )<br/> (setq Sheet-name (vlax-variant-value (car (caddr lst))));确定"第一个"工作表的名称<br/> (setq cell-value (Excel-Get-CellValue Sheet-name "H16"));H16单元格<br/> (vlax-invoke-method ADORecordset "Close")<br/> (vlax-invoke-method ADOConnect "Close")<br/> )<br/> (progn<br/> (princ "\n打开Excel数据文件出错")<br/> (vl-catch-all-apply 'vlax-invoke-method (list ADOConnect "Close"))<br/> (setq cell-value nil)<br/> )<br/> )<br/> (vlax-release-object ADORecordset)<br/> (vlax-release-object ADOConnect)<br/> cell-value<br/>) </p><p></p><p>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>></p><p>不用ADO原来也是可以实现的</p> ;退出并关闭Excel进程<br/> (vlax-invoke-method xlapp 'quit)<br/> (vlax-release-object xlapp)<p>上边两句改成以下内容即可</p><p>;退出并关闭Excel文件<br/> (vlax-invoke-method<br/> (vlax-get-property xlapp 'ActiveWorkbook) <br/> 'close<br/> )</p> 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&replyid=567&id=73343&page=1&skin=0&landlord=0&Star=2">http://www.mjtd.com/bbs/dispbbs.asp?boardid=3&replyid=567&id=73343&page=1&skin=0&landlord=0&Star=2</a>处的程序,我已经基本上写好我需要的“不打开指定的Excel文件就能将其中指定单元格的数据读出来”,程序在一楼,有兴趣的朋友可以去看看。</p> 本帖最后由 渠辉 于 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) ) )
<p></p><p></p><p>(SETQ AA(msxl-GET-value1<br/> (msxl-get-range *XLAPP* "A1")</p><p> ))</p><p>(vlax-variant-value AA)</p><p>提取A1单元格的数据</p> <p>能给出完整程序么?</p><p></p><p>msxl-GET-value1,这个函数貌似加载不了<br/></p> <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> 的程序是一样的,具体表现形式和我一楼的程序也是一样的。还是做不到“不打开指定的Excel文件就能将其中的数据读出来”。还请高手们指点指点。</p><p>(defun Excel-Get-CellValue (xlapp cell /)<br/> (vlax-variant-value (msxl-GET-value (msxl-get-range xlapp cell)))<br/> )</p> <p>乍有可能不打开文件就能读取数据了?</p><p>谁都不能做的的!只是看你如何打开而已吧?</p><p>原来的excel程序是打开的,你就不要quit!</p><p>原来的文档是打开的你就不要close!</p><p>否则,就该乍的就乍的!这不就实现了不影响其它打开的Excel文件!</p> <p>咋就木有可能呢?</p><p>自己做不到不代表谁都做不到的,不然为啥上明经来问呢,不就是因为咱明经高人多么!</p><p>原来的文档不要close,我现在就是这么做的。</p><p>但是,做程序不就是要追求完美一些么?</p><p>老想着让用户该乍的就乍的,不再程序上下功夫是要不得的!!!!!!!</p><p></p> <p>如果楼主会VBA可以测试一下,VBA不用EXCEL.APPLICATION而是直接调用里的WORKSHEETS等对象,但只要调用了EXCEL类里的东西,就可以在任务管理器里看到EXCEL.EXE进程,所以如果不打开EXCEL文件而读取里面的内容应该是不可能的。</p><p>不过好像可以用数据库的SQL语句调用EXCEL数据库。具体怎么做就不是很清楚了。</p> <p>那就是说,应该还是有可能不打开EXCEL文件而读取里面的内容的~!只是会的人现在还没看到我的帖子罢了</p><p></p> 顶出个高手出来! <p>不打开当然读写不了数据,只是可以打开但不显示,表面上是不打开。</p><p>(Defun vlxls-app-open(XLSFile UnHide / ExcelApp WorkSheet Sheets ActiveSheet Rtn)<br/> ;;;function: this program can open an excelfile<br/> (setq XLSFile (strcase XLSFile))<br/> (if (null (wcmatch XLSFile "*.XLS"))<br/> (setq XLSFile (strcat XLSFile ".XLS")))<br/> (if (and (findfile XLSFile)<br/> (setq Rtn (vlax-get-or-create-object "Excel.Application")))<br/> (progn (vlax-invoke-method (vlax-get-property Rtn 'WorkBooks)<br/> 'Open XLSFile)<br/> (if UnHide<br/> (vla-put-visible Rtn 1)<br/> (vla-put-visible Rtn 0))))<br/> Rtn)</p><p></p><p>(setq *xlapp* (vlxls-app-open "C:/test.XLS" nil))</p><p>(SETQ AA(msxl-GET-value1<br/> (msxl-get-range *XLAPP* "A1")</p><p> ))</p><p>(vlax-variant-value AA)</p><p>(vlax-invoke-method *xlapp* 'QUIT) 关闭程序</p>