WBLOCK-instances of block to separate files named as attribute

WBLOCK-instances of block to separate files named as attribute

buzzytrent
Enthusiast Enthusiast
537 Views
5 Replies
Message 1 of 6

WBLOCK-instances of block to separate files named as attribute

buzzytrent
Enthusiast
Enthusiast

Hi all,

 

I have a panel block named "TYPE 4 SIDES" that has an attribute named "PANEL-REF".

I have multiple instances of the block and each instance has a unique "PANEL-REF"

 

Eg: 3No instances of "TYPE 4 SIDES" block in a dwg that have "PANEL-REF" attributes - "W69" & "W70" & "W71"

 

I need to WBLOCK each instance into its own separate .dwg file and name the file the content of the "PANEL-REF" attribute, for instance; C:\Desktop\W69.dwg etc.

 

I have found this thread which is similar to my situation but I cannot edit the code to suit.

 

https://forums.autodesk.com/t5/visual-lisp-autolisp-and-general/wblock-automation-using-attributes-a...

 

Can anyone help create a lisp that can achieve this? 

 

0 Likes
Accepted solutions (1)
538 Views
5 Replies
Replies (5)
Message 2 of 6

paullimapa
Mentor
Mentor

Perhaps you can share your dwg that has all these block attributes with the different values entered into the attribute?

Also to clarify, are you saying that you want each of the wblock dwg to include all block attributes that matches that value and nothing else in the drawing?


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

Kent1Cooper
Consultant
Consultant

Something like this [untested -- I didn't set up your situation]?

 

(defun C:WHATEVER (/ ss n blk)
  (if (setq ss (ssget "_X" '((2 . "TYPE 4 SIDES"))))
    (repeat (setq n (sslength ss)); then
      (setq blk (ssname ss (setq n (1- n))))
      (command "_.wblock"
        (strcat "C:/Your/File/Path/" (getpropertyvalue blk "PANEL-REF"))
        "" ; <define new drawing> default
        "_non" (getpropertyvalue blk "Position"); insertion base
        blk "" ; object
        "_.oops" ; bring back into current drawing [optional]
      ); command
    ); repeat
  ); if
  (prin1)
)

 

Edit the "C:/Your/File/Path/" part and the command name to suit.

 

Kent Cooper, AIA
0 Likes
Message 4 of 6

paullimapa
Mentor
Mentor
Accepted solution

Code wba.lsp is based on the assumption that when block "TYPE 4 SIDES" are found with attribute tag "PANEL-REFall the items matching attribute value "W69" are written together to user's desktop as "W69.dwg" and same operation repeats for "W70.dwg" & "W71.dwg"

; wba selects all blocks with name "TYPE 4 SIDES" having attribute tag "PANEL-REF"
; and finds all matching attribute values "W69" "W70" & "W71" creating separate selection sets
; then wblocks each selection set onto users desktop with corresponing dwg name "W69" "W70" & "W71" 
; OP:
; https://forums.autodesk.com/t5/visual-lisp-autolisp-and-general/wblock-instances-of-block-to-separate-files-named-as-attribute/m-p/12086133#M451125
(defun c:wba (/ attribute_string attribute_tag blkname cmdecho ent idx lst menuecho obj sel wb)
;;;---load vl functions
(if(not(car (atoms-family 1 '("vl-load-com"))))(vl-load-com))
;;;---wblock with given nam as selection set & dwg name to desktop
(defun wb (nam / dwg len ss)
  (setq 
    dwg (strcat (getenv "UserProfile") "\\Desktop\\" nam ".dwg")
    ss (eval (read nam))
  )
  (if(not(zerop(setq len (sslength ss)))) ; if there are obects in the selection set
    (progn
     (if(findfile dwg)(vl-file-delete dwg)) ; delete existing found dwg 
     (vl-cmdf "_.Wblock" dwg "" (getvar"insbase") ss "" "_.Oops")   ; use current base as wblock dwg base
     (if(findfile dwg)
       (princ(strcat"\nSuccessfully Wblocked " (itoa len) " Objects to: " dwg))
       (princ(strcat"\nFailed Wblock for: " dwg))
     )
    )
    (princ(strcat"\nNo Attributes Found Matching Value: " nam))
  )
) ; defun
;; setup environment
(setq blkname "TYPE 4 SIDES" cmdecho (getvar"cmdecho") lst '("W69" "W70" "W71") menuecho (getvar"menuecho"))
(setvar "cmdecho" 0)
(setvar "menuecho" 0)  
(foreach itm lst (set (read itm) (ssadd))) ; initialize selection sets
;; search for matching blocks
(if (setq sel (ssget "_X" (list '(0 . "INSERT") (cons 2 (strcat "`*U*," blkname)) '(66 . 1))))
 (progn
  (repeat (setq idx (sslength sel)) ; repeat through selection set
   (setq obj (vlax-ename->vla-object (setq ent (ssname sel (setq idx (1- idx))))))
   (if (wcmatch (strcase (vla-get-effectiveName obj)) blkname) ; if block name matches
    (foreach attribute (vlax-invoke obj 'getAttributes) ; cycle through all attributes within block
     (setq attribute_tag (strcase (vla-get-tagString attribute))) 
     (setq attribute_string (strcase (vla-get-textString attribute)))
     (if (= attribute_tag "PANEL-REF") ;; if attribute tag matches
      (foreach itm lst ;; add matching entity to each selection set
        (if(= attribute_string itm)
          (ssadd ent (eval(read itm)))
        )
      ) ; foreach
     ) ; if
    )  ; foreach
   ) ; if
  ) ; repeat
  ;; run wb subfunction on each selection set
  (foreach itm lst (wb itm))
 ) ; progn
) ; if
;; restore environment
(setvar "menuecho" menuecho)
(setvar "cmdecho" cmdecho)
(princ) ; clean exit
) ; defun    

 


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

buzzytrent
Enthusiast
Enthusiast

Thank you @Kent1Cooper  & @paullimapa for your help. Sorry for late reply.

 

I thought I had attached the sample .dwg file so apologies for that.

 

@paullimapa your code worked brilliantly, although I failed to mention in my post that there is around 500 instances of the block from numbers 1-500. Due to maximum selection sets, I edited the code to split it into 5 versions that tacked 1-99, 100-199 etc and ran them separately. I am sure If I had explained it better you could have implemented that, so that's on me. Thanks again for your effort and I will read through the code and try and determine how you got there to learn from it.

 

All the best.

0 Likes
Message 6 of 6

paullimapa
Mentor
Mentor

Glad you found a way around the selection set limitation.

Perhaps it might help if I cleared the selection sets at the conclusion of the code with:

  (foreach itm lst (set (read itm) nil)) ; clear selection sets

 

paullimapa_0-1689022287318.png

But as an alternative I came up with this code wbb.lsp which implements lists instead.

If you get a chance, let me know how this works out for you.

; wbb selects all blocks with name "TYPE 4 SIDES" having attribute tag "PANEL-REF"
; and finds all matching attribute values "W69" "W70" & "W71" creating corresponding lists made up of entity names
; then wblocks from each corresponding list all the entity names included onto users desktop with corresponing dwg name "W69" "W70" & "W71" 
; OP:
; https://forums.autodesk.com/t5/visual-lisp-autolisp-and-general/wblock-instances-of-block-to-separate-files-named-as-attribute/m-p/12086133#M451125
(defun c:wbb (/ attribute_string attribute_tag blkname cmdecho ent idx lst menuecho obj sel wb)
;;;---load vl functions
(if(not(car (atoms-family 1 '("vl-load-com"))))(vl-load-com))
;;;---wblock with given nam as list & dwg name to desktop
(defun wb (nam / dwg i len lst)
  (setq 
    dwg (strcat (getenv "UserProfile") "\\Desktop\\" nam ".dwg")
    lst (eval (read nam))
    i 0
  )
  (if(not(zerop(setq len (length lst)))) ; if there are obects in the list
    (progn
     (if(findfile dwg)(vl-file-delete dwg)) ; delete existing found dwg 
     (vl-cmdf "_.Wblock" dwg "" (getvar"insbase")) ; use current base as wblock dwg base
     (repeat len (vl-cmdf (nth i lst))(setq i (1+ i))) ; cycle through items in list
     (vl-cmdf "" "_.Oops")   ; complete wblock & bring back objects
     (if(findfile dwg)
       (princ(strcat"\nSuccessfully Wblocked " (itoa len) " Objects to: " dwg))
       (princ(strcat"\nFailed Wblock for: " dwg))
     )
    )
    (princ(strcat"\nNo Attributes Found Matching Value: " nam))
  )
) ; defun
;; setup environment
(setq blkname "TYPE 4 SIDES" cmdecho (getvar"cmdecho") lst '("W69" "W70" "W71") menuecho (getvar"menuecho"))
(setvar "cmdecho" 0)
(setvar "menuecho" 0)  
(foreach itm lst (set (read itm) '())) ; initialize each list
;; search for matching blocks
(if (setq sel (ssget "_X" (list '(0 . "INSERT") (cons 2 (strcat "`*U*," blkname)) '(66 . 1))))
 (progn
  (repeat (setq idx (sslength sel)) ; repeat through selection set
   (setq obj (vlax-ename->vla-object (setq ent (ssname sel (setq idx (1- idx))))))
   (if (wcmatch (strcase (vla-get-effectiveName obj)) blkname) ; if block name matches
    (foreach attribute (vlax-invoke obj 'getAttributes) ; cycle through all attributes within block
     (setq attribute_tag (strcase (vla-get-tagString attribute))) 
     (setq attribute_string (strcase (vla-get-textString attribute)))
     (if (= attribute_tag "PANEL-REF") ;; if attribute tag matches
      (foreach itm lst ;; add matching entity to each list
        (if(= attribute_string itm)
          (set (read itm) (append (eval(read itm)) (list ent)))
        )
      ) ; foreach
     ) ; if
    )  ; foreach
   ) ; if
  ) ; repeat
  ;; run wb subfunction on each list
  (foreach itm lst (wb itm))
  (foreach itm lst (set (read itm) '())) ; clear each list
 ) ; progn
) ; if
;; restore environment
(setvar "menuecho" menuecho)
(setvar "cmdecho" cmdecho)
(princ) ; clean exit
) ; defun    

 

 


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