Author Topic: Iterating a block  (Read 1928 times)

0 Members and 1 Guest are viewing this topic.

cadman6735

  • Guest
Iterating a block
« on: May 31, 2013, 11:59:28 AM »
Hi all,

I am working on this little macro to change elements from one layer to the next, the only issue I have is the layer is inside a block and I am trying to figure out how to iterate thru a block to change the sublayers...  I found in the help doc. for ssget ":N, :U, :V" but I am not skilled enought to them to work, pluse I think there is a different way to make this work with out using those selection methods, anyway if someone can give me a push in the right direction this would be helpful...
Code: [Select]
(defun c:test ( / ss cnt elist ent)

  (if (and (tblsearch "layer" "ROOMOV")
   (setq ss (ssget "X" (list (cons 8 "ROOMOV"))))
      )

    (progn
      (setq cnt 0)
      (repeat (sslength ss)
(setq elist (entget (ssname ss cnt)))
(setq ent (subst (cons 8 "ROOMNO")(assoc 8 elist) elist))
(entmod ent)
(setq cnt (+ 1 cnt))
      )
    )
  )

(princ)
)

Thanks

Lee Mac

  • Seagull
  • Posts: 12914
  • London, England
Re: Iterating a block
« Reply #1 on: May 31, 2013, 04:18:48 PM »
Although this task could equally be accomplished using only Vanilla AutoLISP, I would suggest the following:

Code - Auto/Visual Lisp: [Select]
  1. (defun c:test ( / doc lay ) ;; Define function, declare local variables
  2.     (cond
  3.         ;; Condition 1
  4.         (   (not (setq lay (tblsearch "layer" "ROOMOV"))) ;; Layer doesn't exist
  5.             (princ "\n\"ROOMOV\" layer not found.") ;; notify user
  6.         ) ;; end condition 1
  7.        
  8.         ;; Condition 2
  9.         (   (= 4 (logand 4 (cdr (assoc 70 lay)))) ;; Layer locked
  10.             (princ "\n\"ROOMOV\" layer is locked.") ;; notify user
  11.         ) ;; end condition 2
  12.        
  13.         ;; Condition 3 (always evaluated as 't' evaluates to True)
  14.         (   t
  15.             ;; Grab the active document for use later
  16.             (setq doc (vla-get-activedocument (vlax-get-acad-object)))
  17.          
  18.             (if (not (tblsearch "layer" "ROOMNO")) ;; If the new layer doesn't exist...
  19.                 (vla-add (vla-get-layers doc) "ROOMNO") ;; ...create it
  20.             ) ;; end if
  21.          
  22.             ;; For every block defined in the drawing
  23.             ;; - note that this includes the Modelspace container and all Paperspace Container blocks
  24.             (vlax-for block (vla-get-blocks doc)
  25.                 (vlax-for object block ;; For every object in the block
  26.                     (if (= "ROOMOV" (strcase (vla-get-layer object))) ;; If the object resides on the layer in question
  27.                         (vla-put-layer object "ROOMNO") ;; Assign it to the other layer
  28.                     ) ;; end if
  29.                 ) ;; end vlax-for
  30.             ) ;; end vlax-for
  31.  
  32.             ;; regen the drawing as we may have modified block definitions
  33.             ;; The regen will ensure any changes are reflected in all references of the definition
  34.             (vla-regen doc acallviewports)
  35.         ) ;; end condition 3
  36.     ) ;; end cond
  37.     (princ) ;; Suppress the return of the last evaluated expression
  38. ) ;; end defun
  39. (vl-load-com) ;; Load the ActiveX(COM) extensions
  40. (princ) ;; Suppress the return of the above when loading

Since the Modelspace & Paperspace container blocks appear in the Block Collection when accessed using ActiveX, it is easier to simply iterate over the objects in every block in the collection when the task is applicable to all objects in the drawing database, both primary & nested.

Using Vanilla AutoLISP one would need to either iterate over the drawing database using entnext or retrieve a selection set of all primary objects using ssget with the "X" mode string; and then iterate over every object in every block definition using a combination of tblnext / tblobjname / entnext - certainly not impossible, just some tasks are easier when approached from a Visual LISP perspective, others (such as working with dictionaries & xdata) are easier with Vanilla.
« Last Edit: May 31, 2013, 04:22:17 PM by Lee Mac »

cadman6735

  • Guest
Re: Iterating a block
« Reply #2 on: June 03, 2013, 10:09:05 AM »
Thank you Lee,

You sir go above and beyond, you gave me more than I wanted but exactly what I needed...  the extra verbage out to the side is ice'ing on the cake, I can't thank you enough for the break down.


It is not about the macro, I am trying to build my skill set nothing more.

Thanks

Lee Mac

  • Seagull
  • Posts: 12914
  • London, England
Re: Iterating a block
« Reply #3 on: June 03, 2013, 10:22:59 AM »
Thank you for your kind words & gratitude cadman, I'm glad that my explanations are clear & comprehensible.

Lee