Trying to isolate one block in a foreach loop and send it to subfunction

Trying to isolate one block in a foreach loop and send it to subfunction

Gorra
Advocate Advocate
874 Views
4 Replies
Message 1 of 5

Trying to isolate one block in a foreach loop and send it to subfunction

Gorra
Advocate
Advocate

I would think this easy but for some reason I'm only getting 'bad argument type' errors.

 

I have a foreach loop for all blocks in a selection set, (largely from paullimapa's efforts) and need to send the current block in the loop to a subfunction to get its attributes updated. The section of code with the erroring line in red is here (full lisp attached) :

 
(defun SelectBlocks (a / d name n out dBlkLst newdBlklkst newout itm attvallst)
  (if (setq name "SPLICE CLOSURE"  ;;selecting all dynamic blocks of this name
      Blklst (ssget "_X" '((0 . "INSERT")))
      n -1
      out (ssadd)
  )
  (while (setq Blck (ssname Blklst (setq n (1+ n))))
    (if (= :vlax-true (vla-get-IsDynamicBlock (vlax-ename->vla-object Blck)))
      (if (= (strcase (vla-get-Effectivename (vlax-ename->vla-object Blck))) (strcase name))
        (ssadd blck out)
      )
    )
  )
 (princ (strcat "No Dynamic Block found by the Name - " name))
) ;;end mass-select portion
(if (/= 0 (sslength out))
  (progn
  (setq dBlklst (mapcar 'cadr (ssnamex out))) ;;convert filtered dynamic block only selection set to entity list
  (setq newdBlklst dBlkLst) ; make a copy of this entity list to use to remove block entities with empty attributes 
  (sssetfirst nil out)
  (alert "foreach Blck begins")
  (foreach Blck dBlklst ;;for each block in filtered entity list
    (setq d (vlax-invoke (vlax-ename->vla-object blck) 'getattributes)) ;;Get attributes
    (setq AttLst (cons (append (setq attvallst (mapcar 'vla-get-textstring d))) AttLst)) ;;Compile list of attribute values
    (setq SPLICE_NUMBERex (nth 0 attvallst)) ;; get existing block's splice_number
    (setq ExNrth (getpropertyvalue Blck "Position/X"))
    (setq ExEst (getpropertyvalue Blck "Position/Y")) ;; get existing block's position
    (if 
      (and
         (eq SPLICE_NUMBERex SPLICE_NUMBERv) ;; if splice numbers match AND
         (>= Northing (- ExNrth 1.0)) ;; coordinates are close
         (<= Northing (+ ExNrth 1.0))
         (>= Easting (- ExEst 1.0))
         (<= Easting (+ ExEst 1.0))
      ) ;;then
        (progn 
          (alert "Splice match")
          (setq newout nil) ;; set any residual value for newout to nil
          (ssadd Blck newout) ;; add single block to selection set newout?
          (sssetfirst nil newout) ;; make newout selection set active?
          (alert "single selection?")
          (if (/= ACTIVITY_NUMBERv nil) ;; If new activity number isn't blank
             (progn
               (LM:vl-setattributevalues Blck ACTIVITY_NUMBER ACTIVITY_NUMBERv) ;; send Blck to LeeMack attribute setter
               (alert "written")
             ) ; end true progn  
          ) ; if
        ) ; end true progn
      ) ; if
    ) ; foreach
  ) ; progn
  ) ;  if
) ; defun
 
I've tried just sending the Blck variable to the attribute setting function without messing with the selections set, but get a similar 'bad argument' error. I've tried setting a new variable to be equal to the Blck and sending that out with no change. 
I'm hoping some fresh eyes can see what I'm missing. Thanks for any enlightenment.
 
Gorra
0 Likes
Accepted solutions (1)
875 Views
4 Replies
Replies (4)
Message 2 of 5

paullimapa
Mentor
Mentor
Accepted solution

just like at the beginning of the code you had (setq out (ssadd)), you'll need to do the same

after you (setq newout nil) ;; set any residual value for newout to nil

then you'll need (setq newout (ssadd)) to initialize this as a new selection set.


Paul Li
IT Specialist
@The Office
Apps & Publications | Video Demos
0 Likes
Message 3 of 5

Gorra
Advocate
Advocate

@paullimapa That's the step I was missing, thanks

0 Likes
Message 4 of 5

paullimapa
Mentor
Mentor

glad to have helped....cheers!!!


Paul Li
IT Specialist
@The Office
Apps & Publications | Video Demos
0 Likes
Message 5 of 5

ВeekeeCZ
Consultant
Consultant

Just wondering... 

 

is there any reason why you export the att values to csv without the tag names?

It would be much clearer, less prone to errors... easier to make later changes... 

tag;value

tag1;value2

...

 

And by the way... creating a variable for every single value (an attribute in this case) is sort of a rookie approach. The preferred way would be to create a list, possibly an associated list. It is a dynamic structure, flexible, more compact and efficient... The language is called autolisp (as list processing) for a reason.

 

Also... you can shorten things...

(if (/= ACTIVITY_NUMBERv nil) ;; If new activity number isn't blank
             (progn
               (LM:vl-setattributevalues Blck ACTIVITY_NUMBER ACTIVITY_NUMBERv) ;; send Blck to LeeMack attribute setter
               (alert "written")
             ) ; end true progn

;;   equals to

   (if ACTIVITY_NUMBERv
     (progn
       (setpropertyvalue Blck ACTIVITY_NUMBER ACTIVITY_NUMBERv)   ; Blck must be ename, not vla-object
       (alert "written")))

 

0 Likes