Visual LISP, AutoLISP and General Customization
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

How to create a Command to update attributes within Blocks?

12 REPLIES 12
Reply
Message 1 of 13
Troy_FerrisVASYD
500 Views, 12 Replies

How to create a Command to update attributes within Blocks?

Hey Everyone,

 

I am very new to this stuff and was looking for some help.

I have a command that I would like to create that would perform the following task:

- Search a given folder for .dwg files

- Open the .dwg and search for a block named "x"

- Within that Block find attribute Tag "5"

- Change the value of this attribute. The value will always be an alphabetical letter (A or B etc...). I would like to take this value and change it to increase by 1 alphabetically.

- Then save Drawing

 

Any help you guys could give me please?

12 REPLIES 12
Message 2 of 13
EnM4st3r
in reply to: Troy_FerrisVASYD

Here is a function I use for attibute change of specific Blocks. Maybe this can help for the start

(defun change-attval (Blockname attname val / ss ent i changed-blocks) ; changes attribute value of Blocks
  (if (setq ss (ssget "_X" (list (cons 0 "INSERT")(cons 2 Blockname))))
    (progn
        (princ "\nProcessing Blocks..")
        (setq i 0)
        (setq changed-blocks 0)
        (while (< i (sslength ss))
          (setq ent (ssname ss i))
          (if (is-attribute-p ent attname)
            (progn
              (setpropertyvalue ent attname val)
              (setq changed-blocks (1+ changed-blocks))
            )
          )
          (setq i (1+ i))
        )
    )
    (progn
      (alert (strcat "Block \"" Blockname "\" not found."))
      (exit)
    )
  );if
  (princ (strcat "\nChanged Blocks: " (itoa changed-blocks)))
  (princ)
);defun


(defun is-attribute-p (bname attname /) ; checks if the given attribute is within the block, returns nil if it isnt
  (if (not (vl-catch-all-error-p (vl-catch-all-apply 'getpropertyvalue (list bname attname))))
    t 
    nil
  )
);defun

 

 

Message 3 of 13
EnM4st3r
in reply to: Troy_FerrisVASYD

so i found this Str+ function here: https://forums.autodesk.com/t5/visual-lisp-autolisp-and-general/increase-attribute-alphabetically/td...

 

i added this, see if this is how you expected it to work.

For the Opening / closing i would recommend a script

 

 

(defun c:changeblock ()
  (change-attval "X" "5")
)


(defun change-attval (Blockname attname / ss ent i changed-blocks val) ; changes attribute value of Blocks
  (if (setq ss (ssget "_X" (list (cons 0 "INSERT")(cons 2 Blockname))))
    (progn
        (princ "\nProcessing Blocks..")
        (setq i 0)
        (setq changed-blocks 0)
        (while (< i (sslength ss))
          (setq ent (ssname ss i))
          (if (is-attribute-p ent attname)
            (progn
              (setq val (str+ (getpropertyvalue ent attname)))
              (setpropertyvalue ent attname val)
              (setq changed-blocks (1+ changed-blocks))
            )
          )
          (setq i (1+ i))
        )
    )
    (progn
      (alert (strcat "Block \"" Blockname "\" not found."))
      (exit)
    )
  );if
  (princ (strcat "\nChanged Blocks: " (itoa changed-blocks)))
  (princ)
);defun


(defun is-attribute-p (bname attname /) ; checks if the given attribute is within the block, returns nil if it isnt
  (if (not (vl-catch-all-error-p (vl-catch-all-apply 'getpropertyvalue (list bname attname))))
    t 
    nil
  )
);defun

(defun Str+  (source / prefix rchar)
  (If (eq (type (read source)) 'INT)
    (itoa(1+ (atoi source)))
    (cond
      ((= source "") "A")
      ((= (setq prefix (substr source 1 (1- (strlen source))) rchar  (substr source (strlen source)))
          "Z"
        )
        (strcat (Str+ prefix) "A")
      )
      ((strcat prefix (chr (1+ (ascii rchar)))))
    )
  )
)

 

Message 4 of 13
Troy_FerrisVASYD
in reply to: EnM4st3r

Hey thanks a lot for your response. I am completely foreign to coding and don't know what I'm doing but I want a command like this to optimize my workflow. I put in the command you gave me but I got the response " Command: CHANGEBLOCK
Processing Blocks..
Changed Blocks: 0"

 

I was wondering if I could give you a drawing file with this border and you could help me out.

In my drawing the block wouldbe called "Ttl_b" and I would like to change the "Current Rev #" or Tag5

 

(defun c:changeblock () (change-attval "Ttl_b" "5") ) (defun change-attval (Ttl_b 5 / ss ent i changed-blocks val) ; changes attribute value of Blocks (if (setq ss (ssget "_X" (list (cons 0 "INSERT")(cons 2 Ttl_b)))) (progn (princ "\nProcessing Blocks..") (setq i 0) (setq changed-blocks 0) (while (< i (sslength ss)) (setq ent (ssname ss i)) (if (is-attribute-p ent 5) (progn (setq val (str+ (getpropertyvalue ent 5))) (setpropertyvalue ent 5 val) (setq changed-blocks (1+ changed-blocks)) ) ) (setq i (1+ i)) ) ) (progn (alert (strcat "Block \""Ttl_b"\" not found.")) (exit) ) );if (princ (strcat "\nChanged Blocks: " (itoa changed-blocks))) (princ) );defun (defun is-attribute-p (Ttl_b 5 /) ; checks if the given attribute is within the block, returns nil if it isnt (if (not (vl-catch-all-error-p (vl-catch-all-apply 'getpropertyvalue (list Ttl_b 5)))) t nil ) );defun (defun Str+ (source / prefix rchar) (If (eq (type (read source)) 'INT) (itoa(1+ (atoi source))) (cond ((= source "") "A") ((= (setq prefix (substr source 1 (1- (strlen source))) rchar (substr source (strlen source))) "Z" ) (strcat (Str+ prefix) "A") ) ((strcat prefix (chr (1+ (ascii rchar))))) ) ) )

Message 5 of 13

Just a suggestion, when playing with A B C etc (ascii char) eg (ascii "C") returns 67 so then use (chr (+ (ascii char) 1)) will give "D" 

 

(setq char "C")
"C"
(chr (+ (ascii char) 1))
"D"

 

There is some code out there that will handle Z+1 = AZ etc but if dwg revision doubtful to exceed 26. 

 

Your script rem the 1st 3 lines in code above.

 

Open dwg1
(load "your x att update")
(change-attval "X" "5")
Close Y
open dwg2
....
....

 

Message 6 of 13
EnM4st3r
in reply to: Troy_FerrisVASYD

this should work, you just need to Type in the Blockname and the attribute name correctly.

I attached the .lsp here, if you have this loaded and you type for example for the drawing you sent

(change-attval "Ttl_b" "#5")

then the letter of #5 should go up by 1.

 

So now what you need to do is save this .lsp file  somewhere so you can load it with your script.

Within the script you need to go somewhat like @Sea-Haven said.

The script should:


1. Open dwg

2. load the .lsp file

3. use change-attval with the right arguments

4. close and save

 

for this you could also use somthing liek Lee-macs script writer so its faster to use the script on every dwg within a folder.

Message 7 of 13
Troy_FerrisVASYD
in reply to: EnM4st3r

Thanks so much for your help, and I'm really sorry for how basic my questions are because I know none of this. My company is really pushing for us to be able to do this but I have zero background in coding or LISP at all. So I had a couple questions:

 

- In the LISP you attached, the code is filled with "Blockname" and "attname". Do I need to manually change these to my associated block and attribute name or should they be left as is?

- How do I get this code to run on a folder of drawings? Is this what the script is needed for?

- How do I "use change-attval with the right arguments" as you said in your previous reply? You were saying that I could load the lisp and type that, were would I type this? In my AutoCAD?

- Is there any chance you could help provide me a code that you think should fully be able to work without much modification based on the changing the #5 attribute that I talked about before in the Block shown below? Just for an example to help me out.

Troy_FerrisVASYD_0-1698672523114.png

I really appreciate all the help you're giving me. I understand that I'm probably asking very dumb/basic questions.

 

Message 8 of 13

Some question if the block is a Title block and is used in multiple layouts then is every layout to have the current revison changed ?  I ask as our layouts had current revision for just that layout.

Message 9 of 13

Yes I would be using it to change every revision for every DWG file in a given folder.

Message 10 of 13

Look into using acoreconsole it runs Autocad without any graphic works on the database so you can have 1 short script that loads the lisp then runs the correct 

(change-attval "Ttl_b" "#5")

 

You can batch multiple dwgs using acoreconsole its extremely fast. Once your happy with the lisp, but note there can be some functions that require an extra step to load a ARX file for those VL functions to work.

 

Do a google using acoreconsole. 

 

The other way is by making a script file that opens a dwg, loads and runs a lisp and closes it again. Yes multiple dwg's.

Message 11 of 13
EnM4st3r
in reply to: Troy_FerrisVASYD


- In the LISP you attached, the code is filled with "Blockname" and "attname". Do I need to manually change these to my associated block and attribute name or should they be left as is?


"Blockname" and "attname" here are the Arguments i mentioned. When using the command change-attval you need to provide the Blockname and the attribute name along with it.

 

 


- Is there any chance you could help provide me a code that you think should fully be able to work without much modification based on the changing the #5 attribute that I talked about before in the Block shown below


The Code should work on this Block. The arguments for the Blockname would be "Ttl_b" and for the attname "#5".

so its: 

(change-attval "Ttl_b" "#5")

 


- How do I get this code to run on a folder of drawings? Is this what the script is needed for?


yes thats what the script is needed for. 

About it running on multiple drawings, i dont know how to do that. Try looking into what @Sea-Haven said.

Maybe you could also try using Lee-macs script writer: http://www.lee-mac.com/scriptwriter.html

He also has a good Introduction to Script writing on his website if you want to have a look into it.

Message 12 of 13

Re read post 5 above has a example script just try on say 2-3 dwgs. 

 

Making scripts many ways but basically need a list of dwg names including full path. I am old fashioned and use old DOS methods to make file list. Then take advantage of replace function in a text file to make the rest of the script. 

Message 13 of 13
pbejse
in reply to: Troy_FerrisVASYD


@Troy_FerrisVASYD wrote:

Hey Everyone,

- Within that Block find attribute Tag "5"

 


What of the value on the revision box? 

 

pbejse_0-1699346834140.png

 

Should that be updated as well? along with the date and a description?

 

 

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Technology Administrators


Autodesk Design & Make Report