在ZWCAD中运行AutoLISP代码操作Excel数据后,Excel进程(EXCEL.EXE
或WPS的ET.EXE
)会在后台残留,导致:
- 无法再次通过代码连接Excel(提示对象已存在)。
- 手动打开Excel时速度极慢(需等待后台进程彻底关闭)。
- 对比现象:同样的代码在 AutoCAD 环境下运行,即便有后台残留,也不影响后续使用
- 代码关键逻辑(已尝试的优化措施):
;; 1. 强制退出Excel
(vl-catch-all-apply ‘vlax-invoke-method (list xlsapp “Quit”));; 2. 释放所有对象(工作表、工作簿、应用)
(if xlsht (vlax-release-object xlsht))
(if xlsapp (vlax-release-object xlsapp));; 3. 系统级终止进程(备用方案)
(vlax-invoke (vlax-create-object “WScript.Shell”) “Run” “taskkill /f /im excel.exe”) -
已尝试的解决方案:
- 显式调用
Quit
方法并释放对象。 - 使用
unwind-protect
确保资源释放。 - 以管理员身份运行ZWCAD。
- 更换Excel版本(测试Microsoft Excel和WPS)。
环境信息:
- ZWCAD版本:2025(请填写实际版本)
- 操作系统:Windows 11
- Excel/WPS版本:Microsoft Office 2024 / WPS
- CAD权限:已尝试管理员和非管理员模式。
求助内容:
- ZWCAD在处理COM对象释放时,是否有特殊配置或限制?
- 是否存在已知的进程残留问题(如特定版本缺陷)?
- 是否需要修改代码逻辑以适配ZWCAD的COM接口?
;;;===================================================== ;;; 一键匹配Q6 ;;;===================================================== ;;; 更新摘要: ;;; v3.0 - 支持混合选择+智能防重 ;;; v2.9 - 优化性能+状态提示 ;;; v2.8 - 增强Excel兼容性 ;;;===================================================== ;;; 严格保留原有辅助函数(前置声明) (defun E-Get-Range-Value (range / a arr) (if (and 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) ) (vlax-variant-value arr) ) ) ) ) (DEFUN C:q6 (/ *error* XLSAPP XLSHT NEWLST TILELST NUM BTLST SS I E STR LST1 BHSTR STR1 NEWSTR NEW_SS OLD_ENT NEW_ENT) ; 错误处理函数 (defun *error* (msg) (princ "\n错误: ") (princ msg) (princ) ) (vl-load-com) ;; --- 原有Excel处理代码 --- (or (setq xlsapp (vlax-get-object "ket.Application")) (setq xlsapp (vlax-get-object "Excel.Application")) ) (IF (NOT xlsapp) (PROGN (ALERT "请打开Excel表格") (VL-EXIT-WITH-VALUE 0)) ) (SETQ xlsht (vlax-get-property xlsapp "activesheet")) (SETQ newlst (E-Get-Range-Value (vlax-get-property xlsht "UsedRange"))) (SETQ tilelst (car NEWLST)) (SETQ num (- (vl-position "模板面积" tilelst) 1)) (SETQ BTLST (mapcar 'cdr (CDR NEWLST))) (SETQ BTLST (MAPCAR (FUNCTION (LAMBDA (X) (MAPCAR (FUNCTION (LAMBDA (Y) (VL-PRINC-TO-STRING Y))) X) )) BTLST ) ) (vlax-release-object xlsht) (vlax-release-object xlsapp) ;; --- 增强版基础编号提取 --- (defun Get-Base-Name (str / n len code result char) (setq n 0 len (strlen str) result "") (while (and (< n len) (setq char (substr str (setq n (1+ n)) 1)) (or (wcmatch char "[A-Za-z]") ; 字母 (wcmatch char "#") ; 数字 (and (> n 1) (wcmatch char "[0-9]"))) ; 首字符后允许数字 ) (setq result (strcat result char)) ) result ) ;; --- 原有分解逻辑 --- (setq ss (ssget '((0 . "TEXT,TCH_TEXT")))) (if (not ss)(VL-EXIT-WITH-VALUE 0)) (setq new_ss (ssadd)) (setq i 0) (while (< i (sslength ss)) (setq e (ssname ss i)) (if (= (cdr (assoc 0 (entget e))) "TCH_TEXT") (progn (setq old_ent (entlast)) (command "_.explode" e) (while (> (getvar 'cmdactive) 0)(command "")) (setq new_ent (entnext old_ent)) (while new_ent (if (= (cdr (assoc 0 (entget new_ent))) "TEXT") (ssadd new_ent new_ss) ) (setq new_ent (entnext new_ent)) ) ) (ssadd e new_ss) ) (setq i (1+ i)) ) (setq ss new_ss) ;; --- 增强处理逻辑 --- (setq i 0) (repeat (sslength ss) (setq e (ssname ss i)) (setq i (1+ i)) (setq str (cdr (assoc 1 (entget e)))) (setq str (vl-string-trim " " str)) (setq lst1 nil) ;; 优先级匹配规则 (cond ((setq LST1 (assoc (setq base (Get-Base-Name str)) BTLST))) ; 关键匹配逻辑 ((setq LST1 (assoc (strcat base ".0") BTLST))) ((setq LST1 (assoc str BTLST))) ((setq LST1 (assoc (strcat str ".0") BTLST))) (t (foreach x BTLST (SETQ BHSTR (CAR x)) (SETQ STR1 (if num (nth num x)(CADDR x))) (SETQ STR1 (vl-string-trim " " STR1)) (IF (AND (= (STRLEN str) (STRLEN STR1)) (APPLY 'AND (MAPCAR '= (vl-string->list str)(vl-string->list STR1))) ) (SETQ LST1 x) ) ) ) ) ;; 统一处理逻辑 (IF LST1 (PROGN (setq new_val (if num (nth num LST1)(CADDR LST1))) (setq final_str (if (wcmatch str "*[ /()x]*") ; 特殊字符检测 (strcat base "/" new_val) ; 使用基础编号 (strcat str "/" new_val) ; 原始编号 )) (ENTMOD (SUBST (CONS 1 final_str)(ASSOC 1 (entget e))(entget e))) ) ) ) (PRINC) )
- 显式调用