Archiman86 发表于 2022-7-6 11:40:52

需要帮助提取属性

大家好,
 
我目前正在编写一个Lisp,需要一些帮助。在这里的情况下,我有3个不同的模板,从一个客户是不同的图纸尺寸。每种尺寸的图纸空间中都有不同的图形边框(属性块)。我想做的是根据使用的图形模板在Lisp中做出决定。我想出的最好办法是“弄清楚”图纸中的标题栏。为此,我提出了在绘图中列出块或列出属性值的方法。然而,我一直无法找到任何地方如何找到这些信息,以便我可以根据这些信息做出决定。如有任何建议,我们将不胜感激。

Lee Mac 发表于 2022-7-6 11:46:36

这将检索图形中所有属性插入的列表:
 

(defun c:blklist (/ ss i bname bnameLst)
(if (setq ss (ssget "X" (list (cons 0 "INSERT")(cons 66 1)
               (if (getvar "CTAB")
               (cons 410 (getvar "CTAB"))
               (cons 67 (- 1 (getvar "TILEMODE")))))))
   (progn
   (setq i (sslength ss))
   (while (not (minusp (setq i (1- i))))
   (setq bname (cdr (assoc 2 (entget (ssname ss i))))
       bnameLst (cons bname bnameLst))))
   (princ "\n<!> No Attributed Blocks Found. <!>"))
(princ))

 
(未经测试,书写速度快!)

Archiman86 发表于 2022-7-6 11:48:19

这应该行得通,我很感激。有没有办法从属性中提取值。假设标题栏中有一个属性,用于指定它是“D”大小、“E”大小还是“a”大小的图形。其中,属性标记为“大小”,标题栏中的值分别为“D”、“E”或“A”。是否有方法提取该值,以便根据该值确定大小、比例等。

Lee Mac 发表于 2022-7-6 11:53:32

这将生成属性值为Size的所有块的关联列表:
 

(defun c:AttLst (/ ss eLst bEnt aEnt aEntLst aVal blkLst)
(vl-load-com)
(if (setq ss (ssget "X" (list (cons 0 "INSERT") (cons 66 1)
               (if (getvar "CTAB")
               (cons 410 (getvar "CTAB"))
               (cons 67 (- 1 (getvar "TILEMODE")))))))
   (progn
   (setq eLst (vl-remove-if 'listp (mapcar 'cadr (ssnamex ss))))
   (foreach e eLst
   (setq bEnt (cdr (assoc 2 (entget e)))
         aEnt (entnext e))
   (while (= "ATTRIB" (cdr (assoc 0 (setq aEntLst (entget aEnt)))))
   (if (= (cdr (assoc 2 aEntLst)) "SIZE")
       (progn
         (setq aVal (cdr (assoc 1 aEntLst))
         blkLst (cons (cons bEnt aVal) blkLst))))
   (setq aEnt (entnext aEnt)))))
   (princ "\n<!> No Attributed Blocks Found <!>"))
(alert (vl-princ-to-string blkLst))
(princ))

Archiman86 发表于 2022-7-6 11:53:47

太棒了!再次感谢。如果有一天你觉得无聊,并且你不介意帮忙,我会非常感谢你解释一下这到底是怎么回事。我的意思是,完成我试图完成的任务很好,但仅供将来参考,以便我理解它,也便于我学习。

Lee Mac 发表于 2022-7-6 11:58:59

没问题,你想让我逐行检查吗?

Archiman86 发表于 2022-7-6 12:00:56

如果你不介意的话。我对AutoLisp有点陌生。我理解它的工作原理,但贯穿整个过程将非常有益。
 
提前谢谢。

Lee Mac 发表于 2022-7-6 12:05:44

毫无疑问,我很乐意帮助任何想更好地理解LISP的人:
 

(defun c:AttLst    (/ ss eLst bEnt aEnt aEntLst aVal blkLst) ; Define the function, localise the variables

(vl-load-com) ; Load the Visual LISP console (allows vl-... commands)

(if ; If there exists a selection set such that:
   (setq ss (ssget "X" ; "X" meaning search entire database for entities with:
             (list (cons 0 "INSERT") ; type: INSERT (Blocks, XRefs)
               (cons 66 1) ; Attributed
               (if    (getvar "CTAB") ; If there is a variable "CTAB" (newer releases - determines Model Space/Paper Space
               (cons 410 (getvar "CTAB")) ; Then filter by the CTAB variable
               (cons 67 (- 1 (getvar "TILEMODE"))) ; Otherwise use TILEMODE variable to filter.
               ) ; end if
             ) ; end list
          ) ; end Selection set aquirement
   ) ; end Variable Setting
   (progn ; Wrap the following code for use in the IF statement:
   (setq eLst ; Store the following list of entity names to variable "eLst"
      (vl-remove-if 'listp ; Remove from the list if the item is a List
          (mapcar 'cadr ; Produce a list of entity names (and possible coord values) from
            (ssnamex ss) ; Information provided by "ssnamex" about the Selection Set
            ) ; end Mapcar
          ) ; end vl-remove-if
       ) ; end variable setting
   (foreach e eLst ; For Each item (e) in the eLst (entity name list):
   (setq bEnt (cdr (assoc 2 (entget e))) ; Retrieve the Block Name
         aEnt (entnext e) ; Retrieve the Attribute Entity Name
   ) ; end Variable setting
   (while (= "ATTRIB" (cdr (assoc 0 (setq aEntLst (entget aEnt))))) ; While the Entity Type is "ATTRIB"
   (if (= (cdr (assoc 2 aEntLst)) "SIZE") ; If the ATTRIBute name is "SIZE"
       (progn ; wrap the following for use with the IF
         (setq aVal   (cdr (assoc 1 aEntLst)) ; Store the ATTRIBute value
         blkLst (cons
                (cons bEnt aVal) ; Create an Associative list (dotted pair) of Block Name and Att. Value.
                blkLst) ; Connect this to the main list
         ) ; End Variable Setting
       ) ; end Progn (code wrapper)
   ) ; end IF
   (setq aEnt (entnext aEnt)) ; Move onto next Attribute in Block
   ) ; End While
   ) ; End Foreach
   ) ; End Progn
   (princ "\n<!> No Attributed Blocks Found <!>") ; If No Selection Set, then No Attributed Blocks Found in Drawing.
) ; End IF
(alert (vl-princ-to-string blkLst)) ; Convert the Associative List to a String and Alert it in a Dialog Box to view result.
(princ) ; Exit Cleanly -
) ; End Function

 
以上内容应该可以帮助您更清楚地理解程序背后的过程,我已经对代码进行了格式化,使其更清晰、更简洁,并对每一行进行了注释和解释。
 
阅读愉快!
 
干杯
 

 
如果您有什么需要进一步解释的,请随时询问
 
希望这有帮助

Archiman86 发表于 2022-7-6 12:06:15

嘿,非常感谢你这么做。我真的很感激。另外,您对更详细地学习AutoLisp的参考资料(书籍等)有什么建议吗。我有一些非常基本的参考资料,但我想知道你是否有任何进一步深入研究这个主题的建议。
 
再次提前感谢。

Lee Mac 发表于 2022-7-6 12:09:32

显然,ACAD Visual LISP编辑器中的开发人员指南是一个很好的参考(只需在ACAD命令提示符下键入“vlide”)。
 
我建议:
AfraLISP公司
 
杰弗里·桑德斯
 
AutoLISP的ABC
 
 
但我相信还有更多的资源。
 
这些应该可以让你走了
 
干杯
 
页: [1] 2
查看完整版本: 需要帮助提取属性