本帖最后由 和尚777 于 2022-12-16 16:56 编辑
- 论坛里有很多读写Excel数据的代码,大多是循环逐个读写,速度很慢
- Excel vba操作数组是非常方便快速的
- vlisp操作数组或许可以做到像Excel vba那样快速操作数据
- 附件有我写的几个函数以数组读写Excel数据,百万数据3秒左右
下面是源码
不缺函数! ket是WPS的app名,改成Excel就行!
;vlisp读写excel 超快
;类库函数我注释了,不需要加载,兼容WPS
- ; 2022-9-6 hs777
- (defun c:tt (/ lst time)
- (setq time(hs-jsq))
- (princ "\n数据构建时间")
- (setq lst(tt-t1 10 50));
- (hs-jsq-end time)
- (setq e(vlax-get-object "Excel.Application")) ;ket.Application
- ;(setq sht(E-Get-ActiveSheet e))
- (setq sht(vlax-get-property e "ActiveSheet"))
- (princ "\n数据写入excel时间")
- (setq time(hs-jsq))
- (E-Lst-2-Range sht "a1" lst)
- (hs-jsq-end time)
- (setq time(hs-jsq))
- (princ "\n读取excel数据时间")
- (setq newlst(E-Get-Range-Value (vlax-get-property sht "UsedRange")))
- (hs-jsq-end time)
- (princ)
- )
;读取
- (vl-load-com)
- (defun c:tt2()
- (setq time(hs-jsq))
- (princ "\n读取excel数据时间")
- (setq e(vlax-get-object "Excel.Application")) ;ket.Application
- (setq sht(vlax-get-property e "ActiveSheet"))
- (setq newlst(E-Get-Range-Value (vlax-get-property sht "UsedRange")))
- (hs-jsq-end time)
- )
;写入函数
- ;(E-Lst-2-Range sht "a1" (tt-t1 1 1))
- ;(E-Lst-2-Range sht "c2" (tt-t1 10 10000));百万数据
- ;(E-Lst2Range 工作表对象 "c2" lst)
- ;二维lst表数据写入Excel单元格,写入成功返回T
- (defun E-Lst-2-Range(sht a1 lst / arr c r range)
- ;可以不加载Excel类库函数,
- ;注释部分get,put,invoke 3个函数 完全代替类库
- (if(and sht a1 lst
- (setq arr(hs-lst2arr2 lst))
- ;(setq a1(E-Get-Range sht a1))
- (setq a1(vlax-get-property sht "range" a1))
- (setq r(length lst))
- (setq c(length (car lst)))
- ;(setq range (E-Get-Resize a1 r c))
- (setq range(vlax-get-property a1 "resize" r c))
- )
- (progn
- ;(E-Put-Value2 range arr)
- (vlax-put-property range "value2" arr)
- t
- )
- )
- )
;转换函数
- ;(setq lst '((1 5 6)(1 2 3)))
- ;二维lst表转二维变体数组
- ;返回数组
- (defun hs-Lst2Arr2(lst / a c r)
- (if (and lst (car(setq a(car lst)))
- (listp a)(setq c(length a))
- (vl-every '(lambda(x)(= c x))(mapcar 'length lst))
- )
- (vlax-safearray-fill
- (vlax-make-safearray
- vlax-vbVariant
- (cons 0 (1- (length lst)))(cons 1 c)
- ) lst)
- )
- )
;读取函数
- ;获取Excel单元格区域的值
- ;一个单元格返回一个值,一片区域返回二维lst表
- (defun E-Get-Range-Value(range / a arr)
- (if(and range
- ;(setq arr(e-get-value range))
- (setq arr(vlax-get-property range "value" nil))
- )
- (progn
- (if (< 8000(vlax-variant-type arr))
- (progn
- (setq a(vlax-safearray->list(vlax-variant-value arr)))
- (mapcar '(lambda(x)(mapcar 'vlax-variant-value x))a)
- )
- (progn
- (vlax-variant-value arr)
- )
- )
- )
- )
- )
;测试函数
- ;构建二维lst表
- (defun tt-t1(r c / a i s)
- (setq i 0 s nil)
- (repeat c
- (setq a nil)
- (repeat r
- (setq a(cons (setq i(1+ i)) a))
- )
- (setq s(cons (reverse a) s))
- )(setq s(reverse s))
- )
- (defun hs-jsq ()(setq $timebe(getvar "millisecs")))
- (defun hs-jsq-end (time / tt) ;计时器结束
- (or time (setq time $timebe))
- (setq tt(- (getvar "millisecs") time))
- (print(strcat"程序运行时间为:"(rtos(* 0.00000001(* tt 86400))2 4)"秒"))
- tt
- )
|