Hardeight 发表于 2022-7-6 15:14:01

循环以删除重复项

我的头撞在墙上,试图让这个回路工作。
只要列表中有偶数个重复项,我几乎可以让它工作。一旦得到奇数,它就会失控,无法正确过滤出我的选择集。这是我到目前为止得到的。。
 
(setq endlist (sslength ssid2))
      (setq endlist2 (sslength ssid2))   
      (while (< curcnt endlist2)
            (progn
      (Setq nxtcnt 1)      
      (setq tltcnt 0)
      (setq curid (ssname ssid2 0))
      (setq curnum (avalue curid "PARTNUMBER"))
            (while    (<= tltcnt endlist)
            (progn
                (setq nxtid (ssname ssid2 nxtcnt))
                (if (/= nxtid nil)            
                      (progn
                (setq nxtnum (avalue nxtid "PARTNUMBER"))
                  (if (equal curnum nxtnum)                           
                        (ssdel curid ssid2)                           
                        (setq nxtcnt (1+ nxtcnt))
                  );if end
                      );progn end
         );if end
      (setq tltcnt (1+ tltcnt))
      );progn end
    );while end
    (setq curcnt (1+ curcnt))
    (setq endlist2 (sslength ssid2))
      );progn end
      
    );while end
    )
      )

Lee Mac 发表于 2022-7-6 15:19:16

基本上,我有一个选择集,从绘图中抓取我的所有块。我将使用该集合在以后的例程中创建一个列表。我的问题是,一旦我有了所有的块,有些是重复的。对于列表中的每个部分,我只需要一个块。所以我试图过滤掉我的集合,使其只包含唯一的实例。enitre例程变得相当大,所以我现在只发布选择集例程。如果还不足以画出一幅清晰的图画,我可以把其余的贴出来。
请原谅我的假笔记。他们帮助我学习和理解正在发生的事情。
 
; Returns the value of an attribute
(defun avalue (bname aname)
       (setq cnt 0)
       (setq ent bname)
       (while (= cnt 0)
         (setq ent (entnext ent))
         (setq entl (entget ent))
         (setq entn (cdr (assoc 2 entl)))
         (if (equal entn aname)
             (progn
            (setq cnt 1)
            (setq aval (cdr (assoc 1 entl)))
             );progn
         ); if
      ); while
); avalue

Lee Mac 发表于 2022-7-6 15:28:14

硬八
 
有点困惑。(cons 2“PARTID”)过滤器意味着只接受1个块名。插入的哪一部分是重复的?插入点?属性值?
 
(ssdel)可以从选取集中删除实体,但需要一些参数进行比较-大卫

Hardeight 发表于 2022-7-6 15:31:05

David,我假设复制了多个同名的块,并且该属性具有不同的属性值:PARTNUMBER。
 
因此,在我的代码中,我在集合中洗牌,列出att值,然后,如果后面的块具有已经看到的属性值,则将其从集合中删除。

Lee Mac 发表于 2022-7-6 15:36:29

刚刚使用以下代码测试了我的LISP:
 
请参阅随附的视频示例
 

; Returns the value of an attribute

(defun avalue (bname aname)
(setq ent (entnext bname))
(while (/= "SEQEND" (cdadr (setq elist (entget ent))))
   (if (equal (cdr (assoc 2 elist)) aname)
       (setq aval (cdr (assoc 1 elist))))
   (setq ent (entnext ent)))
) ; avalue

 
希望这有帮助!
SSFilter。拉链

David Bethel 发表于 2022-7-6 15:44:00

只是想摆脱多次排序列表,然后只要检查下一步是什么,如果相同的跳过并继续通过列表一次。

Lee Mac 发表于 2022-7-6 15:47:09

还有一个解决方案。Higlight并返回已清理的选择集。
 
; The function below collects part number blocks (partid) to use in creating a schedule
; Define the Function
(defun getpart ()
;;; Sets ID selection set ("SSID") to a list and gets every entity in the drawing and filters out to only   ;;; blocks ("(cons 0 "INSERT")") and only blocks named "PARTID" ("(cons 2 "PARTID")")
(SETQ SSID (ssget "X" (list (cons 0 "INSERT") (cons 2 "PARTID")(cons 66 1))))
(if (= ssid nil)
   (progn
   (alert
   "\nCannot find any Item Blocks.
   \n    Check your drawing."
   );alert
   (princ);clean
   );progn end   
   (PROGN;;;Do the following.....
   (SETQ idCOUNT 0);;;Sets the counter to 0
   (setq EMAX(SSLENGTH SSID));;;Sets a "EMAX" to the length ("SSLENGTH") of the ID Selection Set ("SSID")   
   (setq ssid2 (ssadd));creates ssid2 selection set
   (setq dupss (ssadd))
   (setq curcnt 0)
   (setq fnd t)
   (WHILE (< idCOUNT EMAX);;;While the count is less that "EMAX"....
   (setq tid (ssname ssid 0))
   (ssadd tid ssid2)
   (SSDEL TID SSID)
   (SETQ idcount(1+ idcount))
   );while   
      (setq endlist (sslength ssid2))
      (setq endlist2 (sslength ssid2))   
      (while (< curcnt endlist2)
            (progn
      (Setq nxtcnt 1)      
      (setq tltcnt 0)
      (setq curid (ssname ssid2 0))
      (setq curnum (avalue curid "PARTNUMBER"))
            (while    (<= tltcnt endlist)
            (progn
                (setq nxtid (ssname ssid2 nxtcnt))
                (if (/= nxtid nil)            
                      (progn
                (setq nxtnum (avalue nxtid "PARTNUMBER"))
                  (if (equal curnum nxtnum)                           
                        (ssdel curid ssid2)                           
                        (setq nxtcnt (1+ nxtcnt))
                  );if end
                      );progn end
         );if end
      (setq tltcnt (1+ tltcnt))
      );progn end
    );while end
    (setq curcnt (1+ curcnt))
    (setq endlist2 (sslength ssid2))
      );progn end
      
    );while end
    )
      );if end
   (setq copcnt 0)
   (setq copmax (sslength ssid2))
   (WHILE (< copCNT copMAX);;;While the count is less that "EMAX"....
   (setq tid (ssname ssid2 0))
   (ssadd tid ssid)
   (SSDEL TID SSID2)
   (SETQ copcnt(1+ copcnt)))
   );progn end      
(princ);finish clean
)

Lee Mac 发表于 2022-7-6 15:53:40

阿斯米,我认为你的方法与我的方法基本相同,只是你用VL代替。
 
只需将属性与列表中已经累积的属性进行比较,如果(member)返回T,则从SS中删除。

BIGAL 发表于 2022-7-6 15:54:03

leemacs的代码运行得很好,我只是一点都不懂,哈哈,但我正在剖析它,边走边学习。多亏了你们,我已经基本完成了我的第一套动作,我很快就会把它贴出来,也许有人可以看看它,对他们需要做的事情有一些想法。希望我能像别人一样帮助别人。
再次感谢!

ASMI 发表于 2022-7-6 16:03:28

如果你愿意,我可以和你一起运行我的代码,注释每一行
页: [1] 2
查看完整版本: 循环以删除重复项