You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何提取源TEXT/MTEXT的文字高度并应用到待替换文字?

AutoLISP代码问题排查与修正

问题描述

我基于gileCAD的代码自行调整了一段AutoLISP程序,需求是替换选中TEXT/MTEXT内容的同时,继承源TEXT/MTEXT/ATTRIB的文字高度与颜色。但遇到两个问题:

  • 自行修改的代码运行时报错:Program ERROR: bad DXF group: 50.0
  • CAD开发者修改后的代码无报错,能正确应用源文本的高度与颜色,但无法替换选中TEXT/MTEXT的内容

第一段(自行修改报错)的代码

(defun c:MTP (/ cEnt elst text color ss i textSize)
    (if (and (setq cEnt (car (nentsel "\nSelect Source Text: ")))
                (member (cdr (assoc 0 (entget cEnt)))
                    '("TEXT" "MTEXT" "ATTRIB")
                )
        1)
        (progn
        (setq elst (entget cEnt)
              text (assoc 1 elst)
              color (cond ((assoc 62 elst))
                        (T '(62 . 256))
                    )
              textSize (cdr (assoc 40 elst)) ; get text size
        )
        (redraw cEnt 3)
                (if (setq ss (ssget '((0 . "TEXT,MTEXT"))))
                (repeat (setq i (sslength ss))
                (setq elst (entget (ssname ss (setq i (1- i)))))
                    (entmod
                        (subst text
                            (assoc 1 elst)
                                (if (assoc 62 elst)
                                (entmod (subst color (assoc 62 elst) elst))
                                (append elst (list color))
                            )
                            (entmod (subst textSize (assoc 40 elst) elst))
                            (append elst (list textSize))
                        )                   
                    )
                )
            )
        )
    )
    (command "_regenall")
    (princ)
)

CAD开发者修改后的代码(内容替换失效)

(defun c:MTP (/ cEnt elst text color ss i textSize)
    (if (and (setq cEnt (car (nentsel "\nSelect Source Text: ")))
                (member (cdr (assoc 0 (entget cEnt)))
                    '("TEXT" "MTEXT" "ATTRIB")
                )
        1)
        (progn
        (setq elst (entget cEnt)
              text (assoc 1 elst)
              color (cond ((assoc 62 elst))
                        (T '(62 . 256))
                    )
              textSize (cdr (assoc 40 elst)) ; get text size
        )
        (redraw cEnt 3)
                (if (setq ss (ssget '((0 . "TEXT,MTEXT"))))
                (repeat (setq i (sslength ss))
                (setq elst (entget (ssname ss (setq i (1- i)))))
                    (entmod
                       (subst text
                          (assoc 1 elst)
                          (if (assoc 62 elst)
                            (entmod (subst color (assoc 62 elst) elst))
                            (append elst (list color))
                          )
                       )
                    )
                    (entmod 
                       (if (assoc 40 elst)
                          (subst (cons 40 textSize) (assoc 40 elst) elst)
                          (append elst (list (cons 40 textSize)))
                       )                                            
                    )                                   
                )
            )
        )
    )
    (command "_regenall")
    (princ)
)

问题原因分析

第一段代码报错原因

  1. DXF组对格式错误:textSize是单纯的数值(比如2.5),但subst需要替换的是完整的DXF组对(格式为(40 . 数值)),直接传入数值会导致CAD识别无效的DXF组,触发bad DXF group错误。
  2. entmod嵌套调用错误:entmod是用于修改实体的函数,它的返回值不是供subst使用的DXF列表,在subst内部嵌套调用entmod会导致传递给entmod的参数混乱。

开发者修改后代码的内容替换失效原因

在文字替换的entmod中,嵌套调用了(entmod (subst color ...)):

  • 第一次entmod修改颜色后,返回的是修改后的DXF列表,但此时外部的elst还是旧的实体数据
  • 用旧的elst去替换文字内容,会导致文字替换的逻辑基于旧数据执行,最终无法正确更新内容

修正后的代码

(defun c:MTP (/ cEnt srcElst srcText srcColor srcTextSize ss i targetEnt targetElst)
    ;; 选择源文本并验证类型
    (if (and (setq cEnt (car (nentsel "\n选择源文本: ")))
             (member (cdr (assoc 0 (setq srcElst (entget cEnt))))
                     '("TEXT" "MTEXT" "ATTRIB")
             )
        )
        (progn
            ;; 提取源文本的内容、颜色、高度
            (setq srcText (assoc 1 srcElst)
                  srcColor (cond ((assoc 62 srcElst))
                                 (T '(62 . 256)) ; 默认随层颜色
                            )
                  srcTextSize (cons 40 (cdr (assoc 40 srcElst))) ; 转为DXF组对格式
            )
            (redraw cEnt 3) ; 高亮源文本
            
            ;; 选择需要替换的目标文本
            (if (setq ss (ssget '((0 . "TEXT,MTEXT"))))
                (repeat (setq i (sslength ss))
                    (setq targetEnt (ssname ss (setq i (1- i)))
                          targetElst (entget targetEnt)
                    )
                    ;; 构建修改后的DXF列表:先处理颜色,再处理文字,最后处理高度
                    (setq targetElst (if (assoc 62 targetElst)
                                         (subst srcColor (assoc 62 targetElst) targetElst)
                                         (append targetElst (list srcColor))
                                    )
                          targetElst (subst srcText (assoc 1 targetElst) targetElst)
                          targetElst (if (assoc 40 targetElst)
                                         (subst srcTextSize (assoc 40 targetElst) targetElst)
                                         (append targetElst (list srcTextSize))
                                    )
                    )
                    ;; 一次性应用所有修改
                    (entmod targetElst)
                )
            )
        )
    )
    (command "_regenall")
    (princ)
)

修正点说明

  1. 统一DXF组对格式:将源高度转为(40 . 数值)的标准DXF组对,避免格式错误。
  2. 取消entmod嵌套:先在内存中构建完整的修改后DXF列表,再一次性调用entmod应用所有修改,确保数据一致性。
  3. 变量命名更清晰:区分源文本和目标文本的变量,避免混淆。
  4. 逻辑顺序优化:先修改颜色,再替换文字,最后设置高度,确保每一步都基于最新的实体数据。

内容的提问来源于stack exchange,提问作者codeTester-

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 06:37:57