乐筑天下

搜索
欢迎各位开发者和用户入驻本平台 尊重版权,从我做起,拒绝盗版,拒绝倒卖 签到、发布资源、邀请好友注册,可以获得银币 请注意保管好自己的密码,避免账户资金被盗
查看: 66|回复: 8

[编程交流] AUTOLISP按TAG1 Va查找块

[复制链接]

1

主题

1

帖子

0

银币

初来乍到

Rank: 1

铜币
5
发表于 2022-7-5 16:08:49 | 显示全部楼层 |阅读模式
所以我在这里尝试使用Lee Mac的LISP函数:
http://www.cadtutor.net/forum/showthread.php?84816-通过命令行查找并选择具有某些属性的块
 
我需要做的是:
我有一个街区
-块名称=“VIFCD_001”
-属性=“TAG1”值=“-M161”
**属性TAG1的值总是唯一的,但是可能有多个VIFCD_001块,每个块具有不同的TAG1值**
 
我需要一个LISP例程来查找TAG1=所在的块,然后将该特定块的属性“DESC”更改为
 
Lee的LISP函数能够按标记名选择块,这很好,但我似乎不知道如何告诉它然后在该块中查找DESC属性并更改值。
 
(定义c:setAttrVals(标记名descName)
.....
.....
....
(普林斯)
)
 
 
有人能帮忙吗?
回复

使用道具 举报

106

主题

1万

帖子

101

银币

顶梁支柱

Rank: 50Rank: 50

铜币
1299
发表于 2022-7-5 16:18:55 | 显示全部楼层
您可以从拾取块开始,以更通用的方法获得其名称,然后选择具有该名称的所有块,然后检查所有这些块的属性标记名=TAG1,然后查看值并更改它。对于所有样式的方法,我最近使用了属性位置而不是所需的标记名,这适用于任何块名。
 
试试这个
  1. (defun c:test ( / oldtag1 obj bname newstr)
  2. (setq oldtag1 "TAG1") ; attribute tag name
  3. (setq obj (vlax-ename->vla-object (car (entsel "\nPick object"))))
  4. (setq bname (vla-get-name obj)) ; block name need a check for picked a block
  5. (setq ss (ssget "x"  (list (cons 0  "INSERT") (cons 2 bname))))
  6. (princ "\n")
  7. (setq newstr (getstring "Please enter new value"))
  8. (setq x (sslength ss))
  9. (foreach att (vlax-invoke (vlax-ename->vla-object (ssname SS (setq x (- x 1)) )) 'getattributes)
  10. (if (= oldtag1 (strcase (vla-get-tagstring att)))
  11. (vla-put-textstring att newstr)
  12. ) ; end if
  13. ) ; foreach
  14. )
回复

使用道具 举报

114

主题

1万

帖子

1万

银币

中流砥柱

Rank: 25

铜币
543
发表于 2022-7-5 16:26:05 | 显示全部楼层
考虑以下代码:
  1. (defun c:doit ( / bln des ent enx flg fnd idx new sel tag )
  2.    (setq
  3.        bln "VIFCD_001"
  4.        tag "DESC"
  5.    )
  6.    (if (setq sel (ssget "_X" (list '(0 . "INSERT") '(66 . 1) (cons 2 bln))))
  7.        (progn
  8.            (setq fnd (strcase (getstring t "\nSpecify attribute value to find: "))
  9.                  new (cons  1 (getstring t (strcat "\nSpecify new value for "" tag "" attribute: ")))
  10.            )
  11.            (repeat (setq idx (sslength sel))
  12.                (setq ent (entnext (ssname sel (setq idx (1- idx))))
  13.                      enx (entget ent)
  14.                      des nil
  15.                      flg nil
  16.                )
  17.                (while (= "ATTRIB" (cdr (assoc 0 enx)))
  18.                    (cond
  19.                        (   (= tag (strcase (cdr (assoc 2 enx))))
  20.                            (setq des enx)
  21.                        )
  22.                        (   (or flg (setq flg (wcmatch (strcase (cdr (assoc 1 enx))) fnd))))
  23.                    )
  24.                    (setq ent (entnext ent)
  25.                          enx (entget  ent)
  26.                    )
  27.                )
  28.                (if (and des flg)
  29.                    (if (entmod (subst new (assoc 1 des) des))
  30.                        (entupd (cdr (assoc -1 des)))
  31.                    )
  32.                )
  33.            )
  34.        )
  35.        (princ (strcat "\nNo blocks called "" bln "" found in the active drawing."))
  36.    )
  37.    (princ)
  38. )
回复

使用道具 举报

66

主题

1552

帖子

1514

银币

后起之秀

Rank: 20Rank: 20Rank: 20Rank: 20

铜币
325
发表于 2022-7-5 16:35:11 | 显示全部楼层
Lee,当使用(while)循环在属性库中迭代时,为什么不使用“flg”变量来复制(vl some):
 
  1. (while (and (= "ATTRIB" (cdr (assoc 0 enx))) (not flg) )
  2. ...
  3. ); while
回复

使用道具 举报

114

主题

1万

帖子

1万

银币

中流砥柱

Rank: 25

铜币
543
发表于 2022-7-5 16:41:27 | 显示全部楼层
 
如果在遇到“tag”属性之前验证了wcmatch表达式,该怎么办?
回复

使用道具 举报

66

主题

1552

帖子

1514

银币

后起之秀

Rank: 20Rank: 20Rank: 20Rank: 20

铜币
325
发表于 2022-7-5 16:50:57 | 显示全部楼层
 
啊,我现在明白了,没有仔细阅读任务是什么=误解了编码。
 
FWIW,这里是另一种方法(从您那里复制了用户提示):
 
  1. (defun C:test ( / bnm tag n SS fnd new i o L )
  2. (setq
  3.    bnm "VIFCD_001"
  4.    tag "DESC"
  5. )
  6. (and
  7.    (setq n (_AttdefPosition bnm tag))
  8.    (setq SS (ssget "_X" (list '(0 . "INSERT") '(66 . 1) (cons 2 (strcat "`**," bnm)))))
  9.    (setq fnd (strcase (getstring t "\nSpecify attribute value to find: ")))
  10.    (setq new (getstring t (strcat "\nSpecify new value for "" tag "" attribute: ")))
  11.    (repeat (setq i (sslength SS))
  12.      (and
  13.        (eq bnm (vla-get-EffectiveName (setq o (vlax-ename->vla-object (ssname SS (setq i (1- i)))))))
  14.        (setq L (vlax-invoke o 'GetAttributes))
  15.        (vl-some (function (lambda (x) (wcmatch (strcase (vla-get-TextString x)) fnd))) L)
  16.        (vla-put-TextString (nth n L) new)
  17.      )
  18.    )
  19. )
  20. (princ)
  21. ); defun C:test
  22. (defun _AttdefPosition ( bnm tgnm / e i enx f )
  23. (and
  24.    (setq e (tblobjname "BLOCK" bnm))
  25.    (setq e (cdr (assoc -2 (entget e))))
  26.    (setq i -1)
  27.    (while (and e (not f))
  28.      (setq enx (entget e)) (setq e (entnext e))
  29.      (and (member '(0 . "ATTDEF") enx) (setq i (1+ i)))
  30.      (setq f (member (cons 2 tgnm) enx))
  31.      (and (member '(0 . "SEQEND") enx) (setq e nil))
  32.    )
  33. )
  34. (if f i)
  35. ); defun _AttdefPosition

 
我看到你在处理属性时试图限制最多一次迭代,很明显你喜欢想出这么聪明的方法。
回复

使用道具 举报

114

主题

1万

帖子

1万

银币

中流砥柱

Rank: 25

铜币
543
发表于 2022-7-5 16:55:37 | 显示全部楼层
 
我建议不要依赖与每个块引用中遇到属性引用的顺序相对应的块定义中遇到属性定义的顺序,因为可以独立于块定义生成属性引用,因此不能保证两者完全一致。使用属性时,使用属性标记来区分属性几乎总是更好的(除非您被迫使用其他标记,例如,如果使用了重复的标记-IMO,AutoCAD应该防止这种情况发生)。
 
 
谢谢——不过,在效率和可读性之间保持平衡总是值得的:极其高效的代码可能会变得难以置信地不可读,因此在一般应用程序中很难维护。
回复

使用道具 举报

114

主题

1万

帖子

1万

银币

中流砥柱

Rank: 25

铜币
543
发表于 2022-7-5 17:02:11 | 显示全部楼层
FWIW,如果你想使用vl-some来限制迭代,这里有另一种方法:
  1. (defun c:doit ( / bln dsc flg fnd idx new sel tag )
  2.    (setq
  3.        bln "VIFCD_001"
  4.        tag "DESC"
  5.    )
  6.    (if (setq sel (ssget "_X" (list '(0 . "INSERT") '(66 . 1) (cons 2 bln))))
  7.        (progn
  8.            (setq fnd (strcase (getstring t "\nSpecify attribute value to find: "))
  9.                  new (getstring t (strcat "\nSpecify new value for "" tag "" attribute: "))
  10.            )
  11.            (repeat (setq idx (sslength sel))
  12.                (if (vl-some
  13.                       '(lambda ( att )
  14.                            (or flg (setq flg (wcmatch (strcase (vla-get-textstring att)) fnd)))
  15.                            (or dsc (if (= tag (strcase (vla-get-tagstring att))) (setq dsc att)))
  16.                            (and flg dsc)
  17.                        )
  18.                        (vlax-invoke (vlax-ename->vla-object (ssname sel (setq idx (1- idx)))) 'getattributes)
  19.                    )
  20.                    (vla-put-textstring dsc new)
  21.                )
  22.                (setq flg nil dsc nil)
  23.            )
  24.        )
  25.        (princ (strcat "\nNo blocks called "" bln "" found in the active drawing."))
  26.    )
  27.    (princ)
  28. )
  29. (vl-load-com) (princ)
回复

使用道具 举报

66

主题

1552

帖子

1514

银币

后起之秀

Rank: 20Rank: 20Rank: 20Rank: 20

铜币
325
发表于 2022-7-5 17:14:53 | 显示全部楼层
 
谢谢李-我想听听你对我发布的(实验)代码的看法,因为我没有那么多经验,尽管我通常直接使用标记字符串比较方法处理属性引用。
 
 
 
啊,是的,我已经忘记了——在我迭代所有属性引用之前,直到我学会了如何使用(vl-some)并忘记了重复标记的可能性。
现在我明白了为什么您决定处理每个块的所有属性。
 
 
 
我同意这一点,除非代码被用作子函数,所以你只需要知道它的输入是什么,应该返回什么。
然后可以通过解析输入来避免调试上的麻烦。即。:
 
  1. (setq elephant (cow->elephant (sheep->cow (dog->sheep (cat->dog (mouse->cat (fly->mouse fly)))))))

 
我只是把我的机会留给读这篇文章的人(而不是试图辅导你)。
 
 
 
谢谢你把你的建议贴在(vl-some)上——这会让一些试图学习新东西的人感到困惑。
我喜欢你做的lambda部分:
 
  1. '(lambda ( att )
  2. (or flg (setq flg (wcmatch (strcase (vla-get-textstring att)) fnd)))
  3. (or dsc (if (= tag (strcase (vla-get-tagstring att))) (setq dsc att)))
  4. (and flg dsc)
  5. )

 
如果不同项目有多个需求,那么限制迭代似乎是非常方便的方法。
回复

使用道具 举报

发表回复

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

  • 微信公众平台

  • 扫描访问手机版

  • 点击图片下载手机App

QQ|关于我们|小黑屋|乐筑天下 繁体中文

GMT+8, 2025-3-13 19:53 , Processed in 0.487824 second(s), 70 queries .

© 2020-2025 乐筑天下

联系客服 关注微信 帮助中心 下载APP 返回顶部 返回列表