TheSwamp

Code Red => AutoLISP (Vanilla / Visual) => Topic started by: rgp on March 22, 2018, 02:07:58 PM

Title: Paper Space Objects
Post by: rgp on March 22, 2018, 02:07:58 PM
I would like to gather all instances of an attributed block that resides in paper space. So far I have the following code:

(vl-load-com)
      (setq acadObject (vlax-get-acad-object))
      (setq acadDocument (vla-get-ActiveDocument (vlax-get-acad-object)))
      (setq pSpace (vla-get-PaperSpace acadDocument))
      (setq block (vla-get-Blocks acadDocument))
   )

After making a selection set of that block (there could be 40 of them, each in a different paper space layout) I would like to replace the attribute values in the block with new ones. Because there is only one block to change I target that block with this code:

(defun findBlock ( )
(setq ss1 (ssget "X" '((0 . "INSERT")(66 . 1))))        ;filter for all blocks with attributes
   (if ss1                                                      ;if any are found
     (progn                                                       ;do the following
            (setq count 0                                      ;set the counter to zero
               emax  (sslength ss1)                      ;get the number of blocks
            );setq
            (while (< count emax)                   ;while the counter is less than the number of blocks
         (setq en   (ssname ss1 count)   ;get the entity name
                     ed (entget en)                   ;get the entity list
                     blkn (dxf 2 ed)                   ;get the block name
         );setq
         (if (= "4PROG_BOX" blkn)          ;if the block name is "4PROG_BOX"
              (setq count emax           ;stop the loop
                  found T              ;set the flag
              );setq
              (setq count (1+ count))   ;if not increment the counter
         );end if
            );while & if
            (if found                                          ;if the flag is set
      );if
      );progn
   );if
  );defun

It is here where I'm not sure how to replace the attribute values. It seems like replacing the values in one block and then pushing them out to all the other blocks might work. But I have no idea if there is a dxf code for those attributes.

this bit of code from Lee Mac should work:

(defun LM:vl-getattributevalue ( blk tag )
    (setq tag (strcase tag))
    (vl-some '(lambda ( att ) (if (= tag (strcase (vla-get-tagstring att))) (vla-get-textstring att))) (vlax-invoke blk 'getattributes))
)

But I don't know where to put it in the program. I'm thinking that there is a program already written that does this as it is pretty common for titleblocks and so on. Any help would be greatly appreciated.

Russ
Title: Re: Paper Space Objects
Post by: MP on March 22, 2018, 02:57:40 PM
A clearer narrative will help those keen to assist you.
Title: Re: Paper Space Objects
Post by: BIGAL on March 23, 2018, 05:03:14 AM
You can step through your layouts and limit a selection set to just that layout (410 . "layout1") etc
Title: Re: Paper Space Objects
Post by: ronjonp on March 23, 2018, 09:21:10 AM
Code - Auto/Visual Lisp: [Select]
  1. (ssget "_x" '((0 . "insert") (66 . 1) (410 . "~model")))
Title: Re: Paper Space Objects
Post by: rgp on March 24, 2018, 04:12:00 PM
I guess I don't understand the replies. I'll try again next week.

thanks for the comments.

Russ
Title: Re: Paper Space Objects
Post by: rayakmal on March 25, 2018, 06:07:25 AM
Code: [Select]
;;o~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~o
;; Change Attribut of Block
;;o~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~o

(defun attblkchange (enm blk tag newval)
 
   (if (and (= (dxf-code 0 enm) "INSERT") (= (dxf-code 2 enm) blk))
       (progn
          (while (= "ATTRIB" (dxf-code 0 (setq enm (entnext (dxf-code -1 enm)))))
             (setq elst  (entget enm))                       
             (cond ( (= (dxf-code 2 enm) tag)
                     (entmod (subst (cons 1 newval) (assoc 1 elst) elst))
                     (entupd enm)
                   )
             );end cond
          );end while
        );end progn
   );end if
)
Title: Re: Paper Space Objects
Post by: BIGAL on March 25, 2018, 07:18:15 PM
Pulling apart what ronjonp and I suggested
Code: [Select]
(setq doc (vla-get-activedocument (vlax-get-acad-object))) ; open Autocda database
(vlax-for lay (vla-get-Layouts doc)  ; get the layouts from the database
  (setq plotabs (cons (vla-get-name lay) plotabs)) ; make a list of the layout names
)
(setq x 0)
(repeat (length plotabs) ; step through the list looking at each layout
  (setq tabname (nth x plotabs)) ; get the 1st layout tab
  (if (/= tabname "Model") ; skip if "modelspace"
    (progn
      (setvar "ctab" tabname) ; set to current layout tab
; get all blocks "X" "insert"
; filter on the 2 "Block name"
; extra filter on the 410 "layout" name only
      (setq ss1 (ssget "x"  (list (cons 0 "INSERT") (cons 2 bname)(cons 410 tabname))))
.... do your thing with the blocks that have been selected for this layout tab only.
(setq x (+ x 1)) ; increase x so get next layout
) ; repeat
Title: Re: Paper Space Objects
Post by: ronjonp on March 26, 2018, 09:46:59 AM
Assuming your block is not dynamic, this will select all of them in paperspace:
Code - Auto/Visual Lisp: [Select]
  1. (sssetfirst nil (ssget "_x" '((0 . "insert") (2 . "4PROG_BOX") (66 . 1) (410 . "~model"))))
Then you can change the attribute value using the properties palette.
Title: Re: Paper Space Objects
Post by: Marco Jacinto on March 26, 2018, 12:05:44 PM
LeeMac has a variety of program to do this job
Title: Re: Paper Space Objects
Post by: DeeGeeCees_V.2.0 on March 26, 2018, 02:35:50 PM
I believe I grabbed this from Lee Mac at some point, then mashed together something similar as to what you're trying to accomplish. I've included remarks as to what each line accomplishes to help in understanding. I know it's helped me in the past:

Code: [Select]
(setq newtext1 "YOURTEXT") ;set argument to the text string you'd like to change the attribute to
  (setq ss (ssget "_X" '((0 . "INSERT")))) ;gather selection set of inserted objects
  (setq i -1) ;set a counter
  (if ss ;if a selection set exists
    (while (setq ent (ssname ss (setq i (1+ i)))) ;iterate through selection set, gathering info
      (if (and (setq obj (vlax-ename->vla-object ent)) ;gather selection set entity names
               (= (vla-get-objectname obj) "AcDbBlockReference") ;entity is a block
               (= (vla-get-hasattributes obj) :vlax-true) ;block contains attributes
          ) ;end and
        (progn ;if the above is true, do some things to that block entity
           (setq attributes (vlax-invoke obj 'getattributes)) ;gather the block attributes
           (foreach att attributes ;iterate through the block attributes
             (if (or (= "YOURATTNAME1" (vla-get-tagstring att)) ;if the attribute matches the name you want
                     (= "YOURATTNAME2" (vla-get-tagstring att)) ;or if the attribute matches the other name you want
                 ) ;end or
               (progn ;if above is true do some things
                 (vla-put-textstring att newtext1) ;populate the attribute with the new text string
                 (vla-update att) ;update the attribute with new string
               ) ;end progn
             ) ;end if
           ) ;end foreach
        ) ;end progn
      ) ;end if
    ) ;end while
  ) ;end if

It's been a while, so YMMV. Happy coding.
Title: Re: Paper Space Objects
Post by: GDF on March 28, 2018, 12:55:21 PM
I'm wanting to modify LeeMac's code to change the same attributes in multiple layouts. My code below his is the only way I could come up with.
((410 . "02,03,04,05,06")) does not work, it wants a unique block name for each layout.

How do I modify LeeMac's code?

Code: [Select]
(defun LM:setattributevalue ( blk tag val / end enx )
    (while
        (and
            (null end)
            (setq blk (entnext blk))
            (= "ATTRIB" (cdr (assoc 0 (setq enx (entget blk)))))
        )
        (if (= (strcase tag) (strcase (cdr (assoc 2 enx))))
            (if (entmod (subst (cons 1 val) (assoc 1 (reverse enx)) enx))
                (progn
                    (entupd blk)
                    (setq end val)
                )
            )
        )
    )
)

;;;my approach
(if (/= (getvar "ctab") "Model")
  (progn     
    (LM:setattributevalue (ssname (ssget "X" '((410 . "02"))) 0) "PLANNO" "2113AL Standard")
    (LM:setattributevalue (ssname (ssget "X" '((410 . "03"))) 0) "PLANNO" "2113AL Standard")
    (LM:setattributevalue (ssname (ssget "X" '((410 . "04"))) 0) "PLANNO" "2113AL Standard")
    (LM:setattributevalue (ssname (ssget "X" '((410 . "05"))) 0) "PLANNO" "2113AL Standard")
    (LM:setattributevalue (ssname (ssget "X" '((410 . "06"))) 0) "PLANNO" "2113AL Standard")
    (LM:setattributevalue (ssname (ssget "X" '((410 . "07"))) 0) "PLANNO" "2113AL Standard")   
 ))
[code/]
Title: Re: Paper Space Objects
Post by: ronjonp on March 28, 2018, 01:03:51 PM
Try this Gary:
Code - Auto/Visual Lisp: [Select]
  1. (defun c:foo (/ b)
  2.   (if (setq s (ssget "_x" '((0 . "insert") (66 . 1) (410 . "~model"))));<- might want to filter blockname too (2 . "name")
  3.     (foreach b (mapcar 'cadr (ssnamex s)) (lm:setattributevalue b "PLANNO" "2113AL Standard"))
  4.   )
  5.   (princ)
  6. )
Title: Re: Paper Space Objects
Post by: GDF on March 28, 2018, 01:17:32 PM
wow

Thanks Ron
Title: Re: Paper Space Objects
Post by: GDF on March 28, 2018, 01:29:25 PM
Updated code...Thanks again Lee and Ron

Code: [Select]
(if (setq s (ssget "_x" '((0 . "insert")(2 . "DRHortonTBA") (66 . 1) (410 . "~model"))))
    (foreach b (mapcar 'cadr (ssnamex s)) (lm:setattributevalue b "SHTNO" (getvar "ctab")))
  )
(if (setq s (ssget "_x" '((0 . "insert")(2 . "DRHortonTBA") (66 . 1) (410 . "~model"))))
    (foreach b (mapcar 'cadr (ssnamex s)) (lm:setattributevalue b  "DATE" (ARCH:C_DATE-ISSUE (getvar "tdupdate"))))
  )
(if (setq s (ssget "_x" '((0 . "insert")(2 . "DRHortonTBA") (66 . 1) (410 . "~model"))))
    (foreach b (mapcar 'cadr (ssnamex s)) (lm:setattributevalue b "DRHNO" "2113AL V1 R0"))
  )
(if (setq s (ssget "_x" '((0 . "insert")(2 . "DRHortonTBA") (66 . 1) (410 . "~model"))))
    (foreach b (mapcar 'cadr (ssnamex s)) (lm:setattributevalue b "BPSNO" (substr (getvar "dwgprefix") 13 (- (strlen (getvar "dwgprefix")) 13))))
  )
(if (setq s (ssget "_x" '((0 . "insert")(2 . "DRHortonTBA") (66 . 1) (410 . "~model"))))
    (foreach b (mapcar 'cadr (ssnamex s)) (lm:setattributevalue b "PLANNO" "2113AL Standard"))
  )
[code/]
Title: Re: Paper Space Objects
Post by: ronjonp on March 28, 2018, 03:02:53 PM
Gary,

You can change all those attributes in one fell swoop:
Code - Auto/Visual Lisp: [Select]
  1.  
  2. (if (setq s (ssget "_x" '((0 . "insert") (2 . "DRHortonTBA") (66 . 1) (410 . "~model"))))
  3.   (foreach b (mapcar 'cadr (ssnamex s))
  4.     (lm:setattributevalue b "SHTNO" "%<\\AcVar ctab>%");<-Linked field ;)
  5.     (lm:setattributevalue b "DATE" (arch:c_date-issue (getvar "tdupdate")))
  6.     (lm:setattributevalue b "DRHNO" "2113AL V1 R0")
  7.     (lm:setattributevalue
  8.       b
  9.       "BPSNO"
  10.       (substr (getvar "dwgprefix") 13 (- (strlen (getvar "dwgprefix")) 13))
  11.     )
  12.     (lm:setattributevalue b "PLANNO" "2113AL Standard")
  13.   )
  14. )
  15.  
  16.  
Title: Re: Paper Space Objects
Post by: GDF on March 28, 2018, 03:16:57 PM
OOOOOH NICE
Title: Re: Paper Space Objects
Post by: Lee Mac on March 28, 2018, 05:46:50 PM
Thanks for assisting in my absence Ron :-)

Gary, my Set Attribute Values (http://lee-mac.com/attributefunctions.html#alsetattributevaluesrc) function may be more applicable (and efficient) for this task -

Code - Auto/Visual Lisp: [Select]
  1. (setq l
  2.     (list
  3.        '("SHTNO"  . "%<\\AcVar ctab>%")
  4.        '("DRHNO"  . "2113AL V1 R0")
  5.        '("PLANNO" . "2113AL Standard")
  6.         (cons "DATE"  (arch:c_date-issue (getvar "tdupdate")))
  7.         (cons "BPSNO" (substr (getvar "dwgprefix") 13 (- (strlen (getvar "dwgprefix")) 13)))
  8.     )
  9. )
  10. (if (setq s (ssget "_x" '((0 . "insert") (2 . "DRHortonTBA") (66 . 1) (410 . "~model"))))
  11.     (repeat (setq i (sslength s))
  12.         (LM:setattributevalues (ssname s (setq i (1- i))) l)
  13.     )
  14. )

Title: Re: Paper Space Objects
Post by: ronjonp on March 28, 2018, 08:12:12 PM
Thanks for assisting in my absence Ron :)
...
Anytime Lee 😁
Title: Re: Paper Space Objects
Post by: GDF on March 29, 2018, 07:51:39 AM
Thanks Lee

I love the use of fields for the sheet number...need to catch up here.

Gary
Title: Re: Paper Space Objects
Post by: GDF on March 29, 2018, 01:00:28 PM
Need help with fields to update attribute

This field works:
("SHTNO"  . "%<\\AcVar ctab>%")

This field does not work:
("DATE" . "%<\\AcVar date>%")
Or this:
("DATE" . "%<\\AcVar Date \f "MMMM d, yyyy">%")
Title: Re: Paper Space Objects
Post by: Lee Mac on March 29, 2018, 01:05:27 PM
Try:

Code: [Select]
("DATE" . "%<\\AcVar Date \\f \"MMMM d, yyyy\">%")
It is also sometimes necessary to use the UPDATEFIELD command or issue a REGEN for the field to display when populating attribute values.
Title: Re: Paper Space Objects
Post by: ronjonp on March 29, 2018, 01:08:29 PM
Need help with fields to update attribute

This field works:
("SHTNO"  . "%<\\AcVar ctab>%")

This field does not work:
("DATE" . "%<\\AcVar date>%")
Or this:
("DATE" . "%<\\AcVar Date \f "MMMM d, yyyy">%")
You have to esc the \ and " like so: "%<\\AcVar Date \\f \"M/d/yyyy\">%"

DOH .. too slow :)
Title: Re: Paper Space Objects
Post by: GDF on March 29, 2018, 01:18:45 PM
Thanks

Forgot to mention, that I tried that also.

The field will not update with the current date.
Title: Re: Paper Space Objects
Post by: GDF on March 29, 2018, 01:24:05 PM
Unless I double click on the tag to bring up the field dialog box...why?
Title: Re: Paper Space Objects
Post by: Lee Mac on March 29, 2018, 01:29:00 PM
Forgot to mention, that I tried that also.

The field will not update with the current date.

Did you try UPDATEFIELD or REGEN?

Title: Re: Paper Space Objects
Post by: GDF on March 29, 2018, 01:32:12 PM
No, only a regen

Thanks

UPDATEFIELD is the way to go...and now I know and will start using fields.


Thanks guys
Title: Re: Paper Space Objects
Post by: Lee Mac on March 29, 2018, 01:36:47 PM
No, only a regen

Thanks

UPDATEFIELD is the way to go...and now I know and will start using fields.


Thanks guys

You're welcome Gary.

UPDATEFIELD only seems to be necessary for specific objects (attributes, multileader attributes), but isn't typically required when populating Text or MText with field expressions. Another point worth noting is when changing the field expression held by an object, it is sometimes necessary to clear the content first before populating the content with the new field expression (refer to the method used by my Quick Field (http://lee-mac.com/quickfield.html) program - line 205).
Title: Re: Paper Space Objects
Post by: GDF on March 29, 2018, 03:06:41 PM
Will do..Thanks

Just playing around will learning fields:
Code: [Select]
(setq arch#sern (substr (getvar "dwgprefix") 13 (- (strlen (getvar "dwgprefix")) 13)))
(if (/= (ssget "x" '((0 . "insert")(2 . "sc-96"))) nil)(setq arch#scms "Scale = 1/8\" = 1'- 0\""))

(setq l
    (list
       '("SHTNO"  . "%<\\AcVar ctab>%")
       '("DRHNO"  . "2113AL V1 R0")
       '("PLANNO" . "2113AL Standard")
       '("DATE" . "%<\\AcVar Date \\f \"MMMM d, yyyy\">%")
       '("SCALE" . "%<\\AcVar.17.0 Lisp.arch#scms \\f \"%tc3\">%")
       '("BPSNO"  . "%<\\AcVar.17.0 Lisp.arch#sern \\f \"%tc3\">%")
    )
)
[code/]