autocad - Autolisp 例程仅有时有效

标签 autocad autolisp

我必须更改 Autocad 中几个 block 的文本样式和宽度属性。每个 dwg 上有 10-30 个 block ,近 100 个 dgs,我懒得手动将每个 block 转换为新标准。

https://forums.autodesk.com/t5/visual-lisp-autolisp-and-general/attribute-width-change/td-p/1525357 此链接有一个脚本,可将所有 block (标题 block 和几个电气符号)宽度更改为 1,并且作为第一遍,它会执行我想要的操作(由于 bad 失败;错误:错误的参数类型:lentityp nil 命令: 将其更改为手动选择并仅选择我想要的 block 后即可修复它)。但是我还需要将测试样式从任何内容更改为“标准” https://www.afralisp.net/reference/dxf-group-codes.php 检查此链接后,我发现“文本样式名称”的代码是 dxf 7 所以我将脚本更改为以下内容。

(defun C:StandardFromDWGTEXT (/ ss sslen cnt blck ent entinfo)
  (setq ss (ssget))
  (setq cnt 0)
  (setq sslen (sslength ss))
  (while (< cnt sslen)
    (setq blck (ssname ss cnt))
    (setq ent (entnext blck))
    (setq entinfo (entget ent))
    (while
      (and ent (= (cdr (assoc 0 entinfo)) "ATTRIB"))
       (entmod (subst (cons 41 1) (assoc 41 entinfo) entinfo))
;;;    (entupd ent)
;;;    (setq ent (entnext ent))
;;;    (setq entinfo (entget ent))    
       (entmod (subst (cons 7 "Standard") (assoc 7 entinfo) entinfo))
       (entupd ent)
       (setq ent (entnext ent))
       (setq entinfo (entget ent))      
    )
    (setq cnt (1+ cnt))
  )
  (princ)
)

现在它只适用于我注释掉的行(停止使用它们,但这也意味着它只改变文本样式而不是宽度)并且只改变一半的文本样式。我设法通过任意重新加载 auto-cad 来完成所有文件,有时当它不起作用时(不起作用意味着当我期望它时没有任何变化)在 Visual Lisp 编辑器中打开脚本并点击加载事件窗口修复它。我会把它放在我旁边,但为了学习的兴趣,而且因为我已经不得不两次更改标准,所以我很有可能不得不再次这样做,我想尝试解决这个问题。

考虑到脚本只需将宽度更改为 1,100% 的情况下都有效,我认为问题不在于将其添加到启动套件/在可视化 Lisp 编辑器中打开它,而在于我对代码的添加本身。但是我添加的用于更改文本样式的行 (entmod (subst (cons 7 "Standard") (assoc 7 entinfo) entinfo)) 似乎与更改文本宽度的行没有什么不同。

如果有人有任何见解,我将不胜感激。我有使用其他编程语言的经验,但在 Autolisp/lisp 方面我完全是新手。

最佳答案

有一些问题可能会导致您的代码出错:

  • (setq ss (ssget))

    如果没有过滤器列表参数仅允许属性 block ,您的选择可能包括任何 实体类型,这意味着 entnext 调用将为任何没有子实体的对象返回 nil。这将导致 entget 调用返回您所看到的以下错误:

    error: bad argument type: lentityp nil

    解决方案是包含一个过滤器列表,仅允许选择属性 block :

      (setq ss (ssget "_:L" '((0 . "INSERT") (66 . 1))))
    

    _:L 模式字符串还排除锁定图层上的实体。

  • (setq sslen (sslength ss))

    如果不测试有效选择,变量 ss 可能是 nil 这将导致 (sslength ss) 返回错误:

    error: bad argument type: lselsetp nil

  • (entmod (subst (cons 41 1) (assoc 41 entinfo) entinfo))
    (entmod (subst (cons 7 "Standard") (assoc 7 entinfo) entinfo))

    这里,第二个 subst 表达式正在替换 DXF 原始 DXF 数据列表中的组 7,而不是替换 DXF 组 41 后修改的 DXF 数据。这将产生反转 宽度系数的修改。


对上述问题实现修复(并调整其他一些内容)可能会产生以下代码:

(defun c:standardfromdwgtext ( / a i s x )
    (if (setq s (ssget "_:L" '((0 . "INSERT") (66 . 1))))
        (repeat (setq i (sslength s))
            (setq i (1- i)
                  a (entnext (ssname s i))
                  x (entget a)
            )
            (while (= "ATTRIB" (cdr (assoc 0 x)))
                (if (entmod (subst '(41 . 1.0) (assoc 41 x) (subst '(7 . "Standard") (assoc 7 x) x)))
                    (entupd a)
                )
                (setq a (entnext a)
                      x (entget  a)
                )
            )
        )
    )
    (princ)
)

关于autocad - Autolisp 例程仅有时有效,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57480373/

相关文章:

wolfram-mathematica - 在 Mathematica 中沿 3D 路径移动 AutoCad DXF 实体

c# - 有没有更快的方法来调试 ObjectARX 应用程序?

C# 导出到 DWG

attributes - Autolisp 没有为某些用户正确设置 block 属性

java - 如何从 AutoCAD DXF 文件获取详细信息到 Java 应用程序?

Lisp 与外部进程通信

lisp - 在闭合多段线上绘制多边形

autocad - 在 Lisp 退出时执行代码

lisp - 转换多个对象的vlax-ename->vla-object

lisp - 使用 Lisp(或 AutoLisp),关联列表的性能有多好?