nonifo Posted April 23 Share Posted April 23 Hello everyone, As a newcomer to the forum, I'm reaching out for assistance on a task. I'm looking for guidance on efficiently updating attribute values in the provided file using Lisp. The block consistently bears the name EPCB000 and appears only once in each DWG file. Additionally, I'd appreciate insights on extracting values from the fields for targeted 'find and replace' operations. I'm grateful for any advice and examples you can share. Thank you in advance for your help. Best regards, Tony Drawing1.dwg Quote Link to comment Share on other sites More sharing options...
Steven P Posted April 23 Share Posted April 23 would this help? https://lee-mac.com/macatt.html Quote Link to comment Share on other sites More sharing options...
BIGAL Posted April 23 Share Posted April 23 (edited) What do you want to do maybe one of these. Copy atts in block to all similar blocks in layouts, fill in one 1 block attributes and blocks are updated in all layouts. Update sheet X of Y Update 1 attribute in all blocks using a dcl to select Please explain more. Ps make an Index from title blocks. Edited April 23 by BIGAL Quote Link to comment Share on other sites More sharing options...
nonifo Posted April 26 Author Share Posted April 26 I have my block EPCB000, which is my title block. I want to change all the text inside this block to new text. The drawing is a copy of an electric cabinet, but it needs new text details as it's for a new customer. Inside my block EPCB000, there are a few attributes: D12, D13, GODK_DAT, and so on. I want to update the value of those tags in bulk, and apply a few rules, such as using today's date. For example, if D12 holds the value "G11 This is a drawing", I want to update it to G12, and so on. However, I can't figure out how to read and write to those values. Quote Link to comment Share on other sites More sharing options...
BIGAL Posted April 26 Share Posted April 26 Ignore multiple dwg's for moment. As you say only have title block once then its easy. (setq ss (ssget "X" '((0 . "INSERT")(cons 2 "EPCB000")))) You now have a selection set containing the block. (setq obj (vlax-ename->vla-object (ssname ss 0))) (setq atts (vlax-invoke obj 'Getattributes)) The variable atts holds all the attributes. You can then say change the value in each attribute, as you want to change many it makes it easy. You can just loop trough the attributes and change the "TEXTSTRING" the value of the attribute, you can also check for a particular attribute and say change G11 to G12. Ok next question how do you propose to supply the new values ? One way is to make a list of the new values say keep the code in a lisp file and just change the 1 line with the new answers, or keep the values in a text file change it and then run on multiple dwg's if required. This is the type of question linked to excel which can read say a row of details. The excel containing multiple dwg names. 1 Quote Link to comment Share on other sites More sharing options...
mhupp Posted April 27 Share Posted April 27 gatte command? Quote Link to comment Share on other sites More sharing options...
nonifo Posted Monday at 10:05 AM Author Share Posted Monday at 10:05 AM On 4/27/2024 at 12:37 AM, BIGAL said: Ignore multiple dwg's for moment. As you say only have title block once then its easy. (setq ss (ssget "X" '((0 . "INSERT")(cons 2 "EPCB000")))) You now have a selection set containing the block. (setq obj (vlax-ename->vla-object (ssname ss 0))) (setq atts (vlax-invoke obj 'Getattributes)) The variable atts holds all the attributes. You can then say change the value in each attribute, as you want to change many it makes it easy. You can just loop trough the attributes and change the "TEXTSTRING" the value of the attribute, you can also check for a particular attribute and say change G11 to G12. Ok next question how do you propose to supply the new values ? One way is to make a list of the new values say keep the code in a lisp file and just change the 1 line with the new answers, or keep the values in a text file change it and then run on multiple dwg's if required. This is the type of question linked to excel which can read say a row of details. The excel containing multiple dwg names. With use of ChatGPT I got this code to write to my tags value, and it works, almost. It can't handel UTF-8 (swedish charter like ÅÄÖ), any tip how to solve that? This code let me write to the value: ;; Function to convert UTF-8 to ANSI (defun utf8-to-ansi (str) (vl-string-translate "\xC3\x84\xC3\x85\xC3\x96" "\x84\x85\x96" str) ) ;; Function to convert ANSI to UTF-8 (defun ansi-to-utf8 (str) (vl-string-translate "\x84\x85\x96" "\xC3\x84\xC3\x85\xC3\x96" str) ) ;; Set the coding system to UTF-8 (setq *coding-system* 'utf-8) ;; Retrieve all block references with type "INSERT" and name "EPCB000" (setq ss (ssget "X" '((0 . "INSERT")(2 . "EPCB000")))) (setq obj (vlax-ename->vla-object (ssname ss 0))) (setq atts (vlax-invoke obj 'Getattributes)) ;; Loop through the attributes and print their values (while atts (setq att (car atts)) (setq atts (cdr atts)) (setq tag (vla-get-tagstring att)) ;; Use utf8-to-ansi to convert character encoding (setq value (utf8-to-ansi (vla-get-textstring att))) ;; Check if the tag matches any of the attributes you want to update (cond ((equal tag "D8") (vla-put-textstring att (ansi-to-utf8 "ÅPA"))) ((equal tag "D7") (vla-put-textstring att (ansi-to-utf8 "ÖPPNA"))) ((equal tag "D6") (vla-put-textstring att (ansi-to-utf8 "STÄNG"))) ) ) (princ) ; Display the message in the command prompt This code let me read the tag and their value: ;; Function to read strings directly in UTF-8 (defun read-utf8-string (str) str ) ;; Set the coding system to UTF-8 (setq *coding-system* 'utf-8) (setq ss (ssget "X" '((0 . "INSERT")(2 . "EPCB000")))) (setq obj (vlax-ename->vla-object (ssname ss 0))) (setq atts (vlax-invoke obj 'Getattributes)) ;; Loop through the attributes and print their values (while atts (setq att (car atts)) (setq atts (cdr atts)) ;; Use read-utf8-string to read strings directly in UTF-8 (princ (strcat (read-utf8-string (vla-get-tagstring att)) ": " (read-utf8-string (vla-get-textstring att)) "\n")) ) (princ) ; Display the message in the command prompt Quote Link to comment Share on other sites More sharing options...
Steven P Posted Monday at 10:51 AM Share Posted Monday at 10:51 AM (edited) I think this is kind of what you are trying to do: It might do odd things if the block has 2 tags with the same name I've split this into 2 parts, the block updating part (UpdateBlock) which might be a useful one to have that can be used for several functions and test. Test is a dotted pair list, 'tag name . text string', I find this way easier to updated. You might be want a little function that can generate all this from a few user inputs or a dialog box. Note the first line of the list (cons "C2" "Project Name") ;; Project name is how you want it to be if the list is created via LISP otherwise the other format is OK if you edit the LISP file. I'd also add the note "Project Name" at the end of each to remind yourself what each line does Swedish characters: If they are in the character set used in the block then it should work OK - tested with Å (defun c:test ( / NewTitles ) ;;Tag Name : New Text (setq NewTitles (list ; create a list of block tags and their values (cons "C2" "Project Name") ;; Project Name '( "D3" . "Object Name") '( "D4" . "Function") '( "D12" . "File Name") '( "C10" . "Number") '( "D13" . "Another Number") '( "C11" . "Construction") '( "D6" . "ÅÅ") '( "D7" . "Date") '( "BLAD" . "Blad") '( "D10" . "Revision") '( "D25" . "Forts Blad") )) ; end list ; end setq (UpDateBlock NewTitles) ; use this list in 'UpDateBlock' function (princ) ; exit quietly ) (defun UpdateBlock ( NewTitles / ss obj atts att tag NewText) ;; Retrieve all block references with type "INSERT" and name "EPCB000" (setq ss (ssget "X" '((2 . "EPCB000")))) ; find the title block (here no need for (1 . "INSERT") ) (setq obj (vlax-ename->vla-object (ssname ss 0))) ; Get title block as VLA- object (setq atts (vlax-invoke obj 'Getattributes)) ; List the VLA- tags / attributes names (foreach att atts ; Loops through tags / attributes (setq tag (vla-get-tagstring att)) ; Get the 'real' tag name (setq NewText (assoc tag NewTitles)) ; Find tag dotted pair in the supplied list (if (= Newtext nil) ; Check if the tag is in the supplied list (progn (princ "\nTag: ")(princ tag)(princ ", ")(princ (vla-get-textstring att)(princ " not updated") ; report if the tag wasn't updated ) ; end progn (progn (setq NewText (cdr NewText)) ; get the new tag value (vla-put-textstring att NewText) ; update the tag ) ; end progn ) ; end if ) ; end foreach ) EDIT: Apologies if my translation in the list isn't quite what the tags mean in English. Edited Monday at 11:16 AM by Steven P Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.