Can I insert attribute in all current opened drawing's layout?

Can I insert attribute in all current opened drawing's layout?

skchui6159
Advocate Advocate
4,779 Views
47 Replies
Message 1 of 48

Can I insert attribute in all current opened drawing's layout?

skchui6159
Advocate
Advocate

(defun reptag (tag newvalue ent / alist )
(if (and (= (type ent) (read "VLA-OBJECT")) newvalue)
(progn
(setq alist ( vlax-invoke ent 'GetAttributes))
(foreach a alist
(if (= (vla-get-tagstring a) tag)
(vlax-put-property a 'TextString newvalue)
);i
);fe
);p
(if (= 'ename (type ent)) (reptag tag newvalue (vlax-ename->vla-object ent)));i
);i
(princ));d

(defun c:OS ( / ent ss1)
;(setq ent (car (entsel)))
(foreach Layout (layoutlist)
(setq dateofinput "07/24")
(setq ss1 (ssget '(788 190 0)))
(setq ent (ssname ss1 0))
(reptag "ORIGINAL" "ORIGINAL" ent)
(reptag "SIGNED" "SIGNED" ent)
(reptag "GSTAUTHDATE" dateofinput ent)
(reptag "GSTFCHECKDATE" dateofinput ent)
(reptag "GST2CHECKDATE" dateofinput ent)
(reptag "GST1CHECKDATE" dateofinput ent)
(reptag "GSTDRAWDATE" dateofinput ent)
); foreach end
(princ))

 

The above lisp can run only single layout, but I want to apply all current opened drawing's? Anyone can help? Thx

0 Likes
4,780 Views
47 Replies
Replies (47)
Message 2 of 48

paullimapa
Mentor
Mentor

If you have an entire folder of dwgs that you need to run your code on you can try:

Script Writer | Lee Mac Programming (lee-mac.com)


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

skchui6159
Advocate
Advocate

Can you get me a example for write the script? Can it use in .LSP?😅

0 Likes
Message 4 of 48

paullimapa
Mentor
Mentor

It’s easy. The line of script is similar to the example shown on link I provided in my previous post. The difference is that you have to include statements to load your lisp  and the command to run it. So assuming your lisp file is called OS.lsp and is saved in one of the folders in AutoCADs Support file search path then the Script Writer edit box would look something like this:

 

_.Open *file* (load"OS") (c:OS) _.Qsave _.Close

 

 


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

skchui6159
Advocate
Advocate

Thx, Also I will to ask that there are no any response for the above lisp for the (foreach Layout (layoutlist), I will to use the function in all layout, but only the current layout give me the response. Any problem in my lisp?

0 Likes
Message 6 of 48

paullimapa
Mentor
Mentor

to make a layout current you need to include this code:

 (foreach Layout (layoutlist)
  (setvar "ctab" Layout) ; where Layout is an item from the list above

 


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

pbejse
Mentor
Mentor

@skchui6159 wrote:

(setq ss1 (ssget '(788 190 0)))


Unless there are multiple instance of the target block per layout tab [ which i doubt ], you are better off using a block name filter, instead of a point list, also you don't need to switch tab to edit the block

 


@skchui6159 wrote:

...(reptag "ORIGINAL" "ORIGINAL" ent)

..


We can modify reptag function to accept a data list instead of repeatedly invoking the function for every TAG name

 


@skchui6159 wrote:

The above lisp can run only single layout, but I want to apply all current opened drawing's? Anyone can help? Thx


That is definitely doable.

 

 

0 Likes
Message 8 of 48

skchui6159
Advocate
Advocate

It is my blank title block attached.

It is multiple instance in Initial.

I have corrected the lisp code.

No any response in other tab again.

Any revise can you advise?

My block name is "TITLE BLOCK-A".

 

(defun reptag (tag newvalue ent / alist )
(if (and (= (type ent) (read "VLA-OBJECT")) newvalue)
(progn
(setq alist ( vlax-invoke ent 'GetAttributes))
(foreach a alist
(if (= (vla-get-tagstring a) tag)
(vlax-put-property a 'TextString newvalue)
);i
);fe
);p
(if (= 'ename (type ent)) (reptag tag newvalue (vlax-ename->vla-object ent)));i
);i
(princ));d

(defun c:OS ( / ent ss1)
;(setq ent (car (entsel)))
(foreach Layout (layoutlist)
(setvar "ctab" Layout) ; where Layout is an item from the list above
(setq dateofinput "07/24")
(setq ss1 (ssget '(788 190 0)))
(setq ent (ssname ss1 0))
(reptag "ORIGINAL" "ORIGINAL" ent)
(reptag "SIGNED" "SIGNED" ent)
(reptag "GSTAUTHDATE" dateofinput ent)
(reptag "GSTFCHECKDATE" dateofinput ent)
(reptag "GST2CHECKDATE" dateofinput ent)
(reptag "GST1CHECKDATE" dateofinput ent)
(reptag "GSTDRAWDATE" dateofinput ent)
); foreach end
(princ))

 

0 Likes
Message 9 of 48

paullimapa
Mentor
Mentor
Accepted solution

try this updated code:

; OS updates attributes on all blocks found matching given name
; OP:
; https://forums.autodesk.com/t5/visual-lisp-autolisp-and-general/can-i-insert-attribute-in-all-current-opened-drawing-s-layout/m-p/12916173#M469166
(defun c:OS ( / dateofinput ent i obj reptag ss1)
 (setq blknam "TITLE BLOCK-A"
       dateofinput "07/24"
 ) ; setq
 (vl-load-com)  
 (defun reptag (tag newvalue ent / alist )
  (if (and (= (type ent) (read "VLA-OBJECT")) newvalue)
   (progn
    (setq alist ( vlax-invoke ent 'GetAttributes))
    (foreach a alist
     (if (= (vla-get-tagstring a) tag)
      (vlax-put-property a 'TextString newvalue)
     );i
    );fe
   );p
   (if (= 'ename (type ent)) (reptag tag newvalue (vlax-ename->vla-object ent)));i
  );i
  (princ)
 );d
 (if(setq ss1 (ssget "_X" (list '(0 . "INSERT") (cons 2 (strcat blknam ",`*U*")) '(66 . 1))))
  (progn
    (setq i 0)
    (repeat (sslength ss1)
      (setq ent (ssname ss1 i)
            obj (vlax-ename->vla-object ent)
      )
      (if (eq blknam (vla-get-effectivename obj))
        (progn
         (reptag "ORIGINAL" "ORIGINAL" ent)
         (reptag "SIGNED" "SIGNED" ent)
         (reptag "GSTAUTHDATE" dateofinput ent)
         (reptag "GSTFCHECKDATE" dateofinput ent)
         (reptag "GST2CHECKDATE" dateofinput ent)
         (reptag "GST1CHECKDATE" dateofinput ent)
         (reptag "GSTDRAWDATE" dateofinput ent)
        ) ; progn
      ) ; if
      (setq i (1+ i))
    ) ; repeat
    (princ(strcat"\nUpdated Blocks matching: " blknam)) 
  ) ; progn
  (princ(strcat"\nThere are no Blocks found matching: " blknam))
 ) ; if
(princ)
) ; defun

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

skchui6159
Advocate
Advocate

It works , many thank!

Could you please explain the above lisp?

0 Likes
Message 11 of 48

paullimapa
Mentor
Mentor

Well at the top of the code is where the block name and date is defined I placed it there so it’ll be easier for you to modify in the future 

(setq blknam "TITLE BLOCK-A"
       dateofinput "07/24"
 ) 

Then I used a selection set filter to select all instances of your block name including dynamic blocks since that’s what your title block contains:

(setq ss1 (ssget "_X" (list '(0 . "INSERT") (cons 2 (strcat blknam ",`*U*")) '(66 . 1))))

this filters also only blocks with attributes 

then if selection set is found I have to check each selected item to make sure the dynamic block selected matches your block name:

 (setq i 0)
    (repeat (sslength ss1)
      (setq ent (ssname ss1 i)
            obj (vlax-ename->vla-object ent)
      )

then if a match is found it’ll cycle through your function to fill in the matching attribute tag with corresponding values

  (if (eq blknam (vla-get-effectivename obj))
        (progn
         (reptag "ORIGINAL" "ORIGINAL" ent)
         (reptag "SIGNED" "SIGNED" ent)
         (reptag "GSTAUTHDATE" dateofinput ent)
         (reptag "GSTFCHECKDATE" dateofinput ent)
         (reptag "GST2CHECKDATE" dateofinput ent)
         (reptag "GST1CHECKDATE" dateofinput ent)
         (reptag "GSTDRAWDATE" dateofinput ent)
        ) ; progn
      ) ; if

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

pbejse
Mentor
Mentor
Accepted solution

@skchui6159 wrote:

My block name is "TITLE BLOCK-A".

As i describe on my previous post, the reptag subfunction will now accept a list.

Do you still want to to run on this on opened files?

We wrote this code in VL so we can processed files on opened drawings and even files in a folder

 

(defun c:OS (/ reptag dateofinput attV)
(defun reptag (lst attbLst  / found)
 
 (foreach itm attbLst
   (if (setq found (assoc (Car itm) lst))
     	(vla-put-textstring (Cadr itm)(cadr found)))
   )
  (princ)
)
(setq dateofinput "07/24")
(vlax-for blk (vla-get-blocks (vla-get-ActiveDocument (vlax-get-acad-object)))
		(cond
		  ((minusp (vlax-get blk 'isXref)))
		  ((vlax-for h blk
		     (cond
		       ((null (vlax-write-enabled-p h)))
		       ((and
			  (eq (vla-get-ObjectName h) "AcDbBlockReference")
			  (minusp (vlax-get h 'HasAttributes))
			  (wcmatch (vla-get-EffectiveName h) "TITLE BLOCK-*" )
			  (setq attV (mapcar '(lambda (at)
						(list (vla-get-tagstring at) at))
						(Vlax-invoke h 'GetAttributes)))
					    
			  )
			(reptag (append '(("ORIGINAL" "ORIGINAL")("SIGNED" "SIGNED"))
			  		(mapcar '(lambda (v)(list v dateofinput))  '("GSTAUTHDATE" "GSTFCHECKDATE" 
									"GST2CHECKDATE" "GST1CHECKDATE" "GSTDRAWDATE")))
			   attV	 				   
			   )
			  )
			)
		       )
		     )
		   )
	)
  (princ)
  )

 

HTH

 

 

0 Likes
Message 13 of 48

skchui6159
Advocate
Advocate

Very Helpful! Thank you very much! it works

0 Likes
Message 14 of 48

skchui6159
Advocate
Advocate

skchui6159_0-1723596603987.png

Why the some drawings shown the above program if I run a lisp?

How to fix it?

_.Open *file* (load "Rep222") (c:REP222) _.Qsave _.Close

 

If I write below that, it will stop the program.

 

_.Open *file* (load "Rep222") (c:REP222) _.Qsave _.Close N

0 Likes
Message 15 of 48

skchui6159
Advocate
Advocate

if some autocad file shown these message, I can write the "N" of the script but some drawing not show the above message, so the scripts stoped.

0 Likes
Message 16 of 48

paullimapa
Mentor
Mentor

you will have to troubleshoot which drawings cause the problem.

perhaps some other users have those drawings open while you're trying to access?

also is the problem related to the lisp "Load failed"

paullimapa_0-1723599754825.png

 


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

skchui6159
Advocate
Advocate

The problem was solved. Lisp can write the _.qsave and _.close in program. I write the command at the end of program. Like that

(command "_.qsave")

(command ".close" "N")

);defun end

wscript works. The program was not stopped.

0 Likes
Message 18 of 48

skchui6159
Advocate
Advocate

A more question, if I want to insert attribute on model space only?

0 Likes
Message 19 of 48

paullimapa
Mentor
Mentor

then you'll have to replace this line of code:

(if(setq ss1 (ssget "_X" (list '(0 . "INSERT") (cons 2 (strcat blknam ",`*U*")) '(66 . 1))))

to this which will only select blocks in Model tab:

(if(setq ss1 (ssget "_X" (list '(0 . "INSERT") (cons 2 (strcat blknam ",`*U*")) '(66 . 1) '(410 . "Model"))))

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

skchui6159
Advocate
Advocate

If I want to make the drawing no to (strcat "ABC/1/BL6/S" (getvar ('ctab))) and the case 2, how to do?

there are no response (In this condition only BM-111 ok, but other layouts are no response.) if i correct the above program.

Case 1: ABC/1/BL6/S/BM-111

skchui6159_0-1724067020421.png

Case 2: ABC/1/BL6/S/BM-111/A

skchui6159_1-1724067262696.png

I used the foreach function of lisp for the above conditions, no response. Can you assist, thank you?

 

0 Likes