悬赏已过期 后悬赏过期
悬赏

ZWCAD中使用AutoLISP操作Excel后进程残留,导致后续操作异常

邀请:

在ZWCAD中运行AutoLISP代码操作Excel数据后,Excel进程(EXCEL.EXE或WPS的ET.EXE)会在后台残留,导致:

  1. 无法再次通过代码连接Excel(提示对象已存在)。
  2. 手动打开Excel时速度极慢(需等待后台进程彻底关闭)。
  3. 对比现象:同样的代码在 AutoCAD 环境下运行,即便有后台残留,也不影响后续使用
  4. 代码关键逻辑(已尝试的优化措施)​

    ;; 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”)

  5. 已尝试的解决方案

    1. 显式调用Quit方法并释放对象。
    2. 使用unwind-protect确保资源释放。
    3. 以管理员身份运行ZWCAD。
    4. 更换Excel版本(测试Microsoft Excel和WPS)。

    环境信息

    • ZWCAD版本:2025(请填写实际版本)
    • 操作系统:Windows 11
    • Excel/WPS版本:Microsoft Office 2024 / WPS 

    • CAD权限:已尝试管理员和非管理员模式。

    求助内容

    1. ZWCAD在处理COM对象释放时,是否有特殊配置或限制?
    2. 是否存在已知的进程残留问题(如特定版本缺陷)?
    3. 是否需要修改代码逻辑以适配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)
      )
收藏0
分享
您的回答

回答

默认排序 时间排序
图片审查中...
购物车
优惠劵
今日签到
有新私信 私信列表
搜索
复制链接
微信扫码
已复制到剪贴板