Autolisp 例程仅在某些时候有效
Autolisp routine only works sometimes
我不得不在 Autocad 中更改几个块的文本样式和宽度属性。每个 dwg 上有 10-30 个块和将近 100 个 dg,我懒得手动将每个块转换为新标准。
https://forums.autodesk.com/t5/visual-lisp-autolisp-and-general/attribute-width-change/td-p/1525357
这个 link 有一个脚本可以将所有块(标题块和几个电子符号)的宽度更改为 1,并且作为第一遍,它会执行我想要的操作(由于 bad ; error: bad argument type: lentityp nil Command:
而在将其更改为手动后失败select 只需 select 我想要的块即可修复它)。但是我还需要将测试样式从任何内容更改为 "Standard"
https://www.afralisp.net/reference/dxf-group-codes.php
检查此 link 后我发现 "Text style name" 是代码 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 来完成所有文件,有时当它不起作用时(不起作用意味着我期望它时没有任何变化)在可视化 lisp 编辑器中打开脚本并点击加载活动 window 修复它。我会把它放在我身边,但为了学习的兴趣,因为我已经不得不两次更改标准,所以我很有可能不得不再次这样做,我想尝试解决这个问题。
考虑到仅将宽度更改为 1 的脚本在 100% 的情况下都有效,我认为问题不在于将它添加到启动 suite/opening 它在可视化 lisp 编辑器中,而是在于我的除了代码本身。但是我添加的行更改文本样式
(entmod (subst (cons 7 "Standard") (assoc 7 entinfo) entinfo))
与更改文本宽度的行似乎没有什么不同。
如果有人有任何见解,我将不胜感激。我有使用其他编程语言的经验,但在 Autolisp/lisp.
方面我完全是个新手
有几个问题可能会影响您的代码:
(setq ss (ssget))
如果没有过滤器列表参数只允许属性块,您的选择可以包括 any 实体类型,这意味着 entnext
调用将为任何没有子实体的对象 return nil
。这将因此导致 entget
调用 return 您正在目睹的以下错误:
error: bad argument type: lentityp nil
解决方案是包含一个过滤器列表以仅允许选择属性块:
(setq ss (ssget "_:L" '((0 . "INSERT") (66 . 1))))
_:L
模式字符串也排除锁定层上的实体。
(setq sslen (sslength ss))
如果不测试有效选择,变量 ss
可能是 nil
这将导致 (sslength ss)
到 return 错误:
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
表达式替换 original[= 中的 DXF 组 7 56=] DXF数据列表,不是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)
)
错误
bad ; error: bad argument type: lentityp nil
是空变量用于实体的结果。
当你使用 (setq ent (entnext blck))
时,你应该检查它是否为 nil。
(setq ent (entnext blck))
(if ent
(progn
(setq entinfo (entget ent))
在对 AutoLisp 进行故障排除时,您看到 lentityp 或 stringp = nil,这表明您正在使用的变量被设置为 nil,您需要找出位置和原因。
我不得不在 Autocad 中更改几个块的文本样式和宽度属性。每个 dwg 上有 10-30 个块和将近 100 个 dg,我懒得手动将每个块转换为新标准。
https://forums.autodesk.com/t5/visual-lisp-autolisp-and-general/attribute-width-change/td-p/1525357
这个 link 有一个脚本可以将所有块(标题块和几个电子符号)的宽度更改为 1,并且作为第一遍,它会执行我想要的操作(由于 bad ; error: bad argument type: lentityp nil Command:
而在将其更改为手动后失败select 只需 select 我想要的块即可修复它)。但是我还需要将测试样式从任何内容更改为 "Standard"
https://www.afralisp.net/reference/dxf-group-codes.php
检查此 link 后我发现 "Text style name" 是代码 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 来完成所有文件,有时当它不起作用时(不起作用意味着我期望它时没有任何变化)在可视化 lisp 编辑器中打开脚本并点击加载活动 window 修复它。我会把它放在我身边,但为了学习的兴趣,因为我已经不得不两次更改标准,所以我很有可能不得不再次这样做,我想尝试解决这个问题。
考虑到仅将宽度更改为 1 的脚本在 100% 的情况下都有效,我认为问题不在于将它添加到启动 suite/opening 它在可视化 lisp 编辑器中,而是在于我的除了代码本身。但是我添加的行更改文本样式
(entmod (subst (cons 7 "Standard") (assoc 7 entinfo) entinfo))
与更改文本宽度的行似乎没有什么不同。
如果有人有任何见解,我将不胜感激。我有使用其他编程语言的经验,但在 Autolisp/lisp.
方面我完全是个新手有几个问题可能会影响您的代码:
(setq ss (ssget))
如果没有过滤器列表参数只允许属性块,您的选择可以包括 any 实体类型,这意味着entnext
调用将为任何没有子实体的对象 returnnil
。这将因此导致entget
调用 return 您正在目睹的以下错误:error: bad argument type: lentityp nil
解决方案是包含一个过滤器列表以仅允许选择属性块:
(setq ss (ssget "_:L" '((0 . "INSERT") (66 . 1))))
_:L
模式字符串也排除锁定层上的实体。(setq sslen (sslength ss))
如果不测试有效选择,变量ss
可能是nil
这将导致(sslength ss)
到 return 错误: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
表达式替换 original[= 中的 DXF 组 7 56=] DXF数据列表,不是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)
)
错误
bad ; error: bad argument type: lentityp nil
是空变量用于实体的结果。
当你使用 (setq ent (entnext blck))
时,你应该检查它是否为 nil。
(setq ent (entnext blck))
(if ent
(progn
(setq entinfo (entget ent))
在对 AutoLisp 进行故障排除时,您看到 lentityp 或 stringp = nil,这表明您正在使用的变量被设置为 nil,您需要找出位置和原因。