ljxkm
发表于 2019-9-11 16:53:39
谢谢crtrccrt的热心指正啊,是的那个初始化函数使用当中确实遇到了一些问题,但一般还是可以启动了,其实对excel版本问题的根本解决之道就是忘了版本,但那又是另外的话题了,为方便大家学习优化到这个地步够了,这一贴在你的推动下,还是有一定的含金量了,说了这么半天,有心的新手应该基本可以切入excel表了,通过你的指正,对mapcar函数又有新的认识,在此表示感谢啊
crtrccrt
发表于 2019-9-12 14:25:08
本帖最后由 crtrccrt 于 2019-9-12 14:26 编辑
LSP读取XLS还有另外一种方法,不依靠EXCEL程序。
大家自行搜索吧。
ljxkm
发表于 2019-9-14 10:05:50
ljx-read-excel-data、ljx-read-excel-data、Ljx-vlxls-get-range-value三个函数在收集的大量的函数的支持下运行成功,但这确实显得过于复杂繁琐,多年来自己收集了大量的函数,但换一个人来用就非常不方便,从自己使用的体会来看,越不要外挂,使用系统自带的东西就能运行,越是方便适用,来了点兴趣啊,按以上思路,不依靠那些类型库声明代码、不依靠大量mslx函数和自定义函数就能运行,现基本搞成,在自己的机子上运行良好,以下是经过修改后的函数和运行实例,excel表还是用原来的"ABC.xls"文件啊:
;;;;;读取excel数据函数
(defun Ljx-read-excel-data1 (vv hor sh) ;;;vv为列数直接输入字母、hor为 第几行,直接输入数字,sh为工作表对象sheet
(vlax-variant-value (vlax-get-property (vlax-get-property sh 'Range (strcat vv (itoa hor))) 'Value2))
)
;;;;;读取excel数据函数输出text格式
(defun Ljx-read-excel-text1 (vv hor sh ) ;;;vv为列数直接输入字母、hor为 第几行,直接输入数字,sh为工作表对象sheet
(vl-princ-to-string (vlax-variant-value (vlax-get-property (vlax-get-property sh 'Range (strcat vv (itoa hor))) 'Value2)))
)
;;;;;;取得单元格数据,支持区域输入
(defun ljx-vlxls-get-range-value1 ( sheet rangeid / range value valuelist )
(setq range (vlax-get-property sheet 'Range rangeid))
(setq value (vlax-get-property range 'Value2))
(cond
((= (vlax-variant-type value)8204);;;为数组时,即为区域;
(progn
(setq value (vlax-safearray->list(vlax-variant-value value)))
(setq valuelist (mapcar (function (lambda (x)(mapcar 'vlax-variant-value x))) value))
)
)
( T;;;;为单个单元格;
(setq valuelist (vlax-variant-value value))
)
);;;;cond
valuelist
)
;;;;运行函数
(defun test1 ()
(vl-load-com)
(setq exname "d:\\ABC.xls")
(setq *excel* (vlax-create-object "excel.application"))
(setq *xlapp* (vlax-invoke-method (vlax-get-property *excel* 'Workbooks) 'Open exname))
(vla-put-visible *excel* 1)
(setq *sheet* (vlax-get-property (vlax-get-property *xlapp* 'Worksheets) 'item "DEF"))
(setq dat0 (Ljx-vlxls-get-range-value1 *sheet* "E5")
dat1 (Ljx-vlxls-get-range-value1 *sheet* "E5:F5");;;;输出:((-25.10 "张三"))
dat2 (Ljx-vlxls-get-range-value1 *sheet* "E5:E6");;;;输出:((-25.10)(26.85))
dat3 (Ljx-vlxls-get-range-value1 *sheet* "E5:F6");;;;输出:((-25.10 "张三")(26.85 "李四"))
dat4 (Ljx-read-excel-data1"E" 5 *sheet*);;;;-->-25.10
dat5 (Ljx-read-excel-text1"E"5*sheet* );;;;-->"-25.10"
dat6 (Ljx-read-excel-data1"E"6 *sheet* );;;;-->26.85
dat7 (Ljx-read-excel-text1 "E"6 *sheet*);;;;-->"26.85"
dat8 (Ljx-read-excel-data1 "F"5 *sheet*);;;;-->“张三”
dat9 (Ljx-read-excel-text1 "F"5 *sheet*);;;;-->“张三”
dat10 (Ljx-read-excel-data1"F"6 *sheet* );;;;-->"李四"
dat11 (Ljx-read-excel-text1"F"6 *sheet* );;;;-->"李四"
)
(vlax-invoke-method (vlax-get-property *excel* "ActiveWorkbook") 'Close 0)
(vlax-invoke-method *excel* 'QUIT)
(vlax-release-object *sheet*)
(vlax-release-object *xlapp*)
)
;;;;具体使用时先将ABC.xls(解压ABC.zip)拷贝至d盘根目录下,加载test1.lsp文件,在CAD命令行输入 (test1)即可运行
czb203
发表于 2019-10-9 17:15:28
技术讨论很棒
vuiss
发表于 2019-10-11 11:47:53
踩个脚印~~
llsheng_73
发表于 2019-10-11 16:45:41
虽然绝大部分msxl函数都可能通过vlax-invoke、vlax-get、vlax-get来实现,并且要使用msxl函数确实需要初始化并连接MS-EXCEL库,看起来比较麻烦,但实际上 对于一些比较复杂东西,还是需要通过msxl更简单
实际上初始化并连接MS-EXCEL库也并不麻烦,
(defun ExcelTypeLib(/ obj path tlb)
(and(setq obj(vlax-get-or-create-object"Excel.Application"))
(setq path(vlax-get obj 'Path))
(or(vl-some'(lambda(x)(setq tlb(findfile(strcat path x))))
'("\\Excel8.olb""\\Excel9.olb""\\Excel10.olb""\\Excel.exe"))
(alert "系统内未找到MS-EXCEL初始化失败!")))
tlb)
(defun xlsinit(/ tlb)
(and(not msxl-xl24HourClock)
(setq tlb(ExcelTypeLib))
(vlax-import-type-library :tlb-filename tlb :methods-prefix"msxl-":properties-prefix"msxl-":constants-prefix"msxl-"))
)
ljxkm
发表于 2019-10-12 12:52:48
llsheng_73 发表于 2019-10-11 16:45
虽然绝大部分msxl函数都可能通过vlax-invoke、vlax-get、vlax-get来实现,并且要使用msxl函数确实需要初始 ...
这个初始化函数就比较经典全面了,谢谢长老啊
渠辉
发表于 2019-10-13 08:52:58
有用留下来
happy336
发表于 2019-10-14 20:27:38
谢谢分享,支持
lqplvhehe321
发表于 2019-11-12 17:13:24
请问,调用wps里的表格也可以直接这样用吗