Hi All,
We have to add a ton of attributes to all of our blocks.
I found code that was originally written by Lee Mac, but it was designed to type in the block name that you wanted.
I just want to be able to select all the blocks that I want and then have it insert the tags into all of the blocks that are selected.
I tried to change the "name enter box" to a select command but the program comes back with no blocks found.
Sorry I am new to this and may as well be trying to learn another language.
(defun c:addattribs ( / blk def )
; Get Entities
(while (not blk)
(princ "\nSelect Blocks to Update:")
(setq blk (ssget '((-4 . "<NOT") (0 . "INSERT,POLYLINE,VIEWPORT") (-4 . "NOT>"))))
) ;_ end while
)
(if (/= "" blk)
(progn
(setq def (vla-item (vla-get-blocks (vla-get-activedocument (vlax-get-acad-object))) blk))
(vla-addattribute def
(getvar 'textsize)
acattributemodelockposition
"New Attribute 1"
(vlax-3D-point 0 0)
"NEW_TAG1"
"New Value 1"
)
(vla-addattribute def
(getvar 'textsize)
acattributemodelockposition
"New Attribute 2"
(vlax-3D-point 0 (- (* 1.5 (getvar 'textsize))))
"NEW_TAG2"
"New Value 2"
)
(command "_.attsync" "_N" blk)
)
)
(princ)
)
(vl-load-com) (princ)
Thanks.
Solved! Go to Solution.
Solved by john.uhden. Go to Solution.
Solved by john.uhden. Go to Solution.
Solved by Ranjit_Singh1. Go to Solution.
Solved by john.uhden. Go to Solution.
Solved by Ranjit_Singh1. Go to Solution.
Solved by john.uhden. Go to Solution.
@Kyle.para wrote:
Hi All,
We have to add a ton of attributes to all of our blocks.
I found code that was originally written by Lee Mac, but it was designed to type in the block name that you wanted.
I just want to be able to select all the blocks that I want and then have it insert the tags into all of the blocks that are selected.
See post 4 of 4 here. Call the routine as (somefunc '("YourTAG1" "YourTAG2 "YourTAG3" .....) '("Value1" "Value2" "Value3" ......))
EDIT: Misunderstood the request. Ignore my reply
@Kyle.para wrote:
Hi All,
.............
I just want to be able to select all the blocks that I want and then have it insert the tags into all of the blocks that are selected.
...................
When you say all the blocks, do you mean different block definitions or just all instances of one particular block? If you are talking different block definitions then how will the computer decide on the tag position for each of these blocks? You need to specify one particular block, specify the position of the new tag(s) and then move to a different block. The below code will allow you to pick a block and then add the tag. All instances of that block should update.
(defun c:somefunc (/ vlaObj testblk) (setq vlaObj(vlax-ename->vla-object (cdr (assoc 330 (entget (tblobjname "block" (setq testblk (cdr (assoc 2 (entget (car (entsel)))))))))))) (while (setq pt1 (getpoint "\nEnter new Tag Position :") prm (getstring "\nEnter Tag Prompt :") tag (getstring "\nEnter Tag Name :") val (getstring "\nEnter Tag Value :")) (vla-addattribute vlaObj 20 acattributemodelockposition prm (vlax-3d-point pt1) tag val) (vl-cmdf "_.attsync" "_N" testblk)) (princ))
Hi Ranjit,
Yes sorry I was hoping we could just force the program to loop over and over again for different block definitions.
I have multiple blocks with different names that all need the exact same attributes
If I can only do one at a time that is OK though, but what I am looking for is to have the lisp push specified attributes to the block automatically without any input from the user.
For example I would select block A and it would add the following tags automatically Description, Model, Comments etc...
Then I would move to the next one say block B and have it automatically generate the same tags for that block.
I need to blocks to be invisible as well.
Here's the original program that Lee Mac did, that actually runs to see what I mean.
(defun c:addattribs ( / blk def ) (while (not (or (= "" (setq blk (getstring t "\nName of block to update: "))) (tblsearch "BLOCK" blk) ) ) (princ (strcat "\nBlock \"" blk "\" not found.")) ) (if (/= "" blk) (progn (setq def (vla-item (vla-get-blocks (vla-get-activedocument (vlax-get-acad-object))) blk)) (vla-addattribute def (getvar 'textsize) acattributemodelockposition "New Attribute 1" (vlax-3D-point 0 0) "NEW_TAG1" "New Value 1" ) (vla-addattribute def (getvar 'textsize) acattributemodelockposition "New Attribute 2" (vlax-3D-point 0 (- (* 1.5 (getvar 'textsize)))) "NEW_TAG2" "New Value 2" ) (command "_.attsync" "_N" blk) ) ) (princ) ) (vl-load-com) (princ)
This is exactly what I need, but I don't want to enter the name of specified block. I just want to select a block but do the same thing.
Thanks,
Try this variation (not tested)...
(defun c:addattribs ( / ss i blk blks def ) (and (setq ss (ssget "X" '((0 . "INSERT")))) (setq i (sslength ss)) (while (> i 0) (setq blk (cdr (assoc 2 (entget (ssname ss (setq i (1- i))))))) (if (not (vl-position blk blks))(setq blks (cons blk blks))) ) ) (foreach blk blks (setq def (vla-item (vla-get-blocks (vla-get-activedocument (vlax-get-acad-object))) blk)) (vla-addattribute def (getvar 'textsize) acattributemodelockposition "New Attribute 1" (vlax-3D-point 0 0) "NEW_TAG1" "New Value 1" ) (vla-addattribute def (getvar 'textsize) acattributemodelockposition "New Attribute 2" (vlax-3D-point 0 (- (* 1.5 (getvar 'textsize)))) "NEW_TAG2" "New Value 2" ) (command "_.attsync" "_N" blk) ) (princ) ) (vl-load-com) (princ)
I'm not sure what happens with XRefs. If you want to select the blocks instead of all of them, just remove "X"
John F. Uhden
You are required to pick a point and it will allow you only as many times to pick the point, as the number of elements in the list. If you do not specify a point in any block then it moves on to the next block and starts at TAG1. Call it like this (somefunc '("Prompt1" "Prompt2" "Prompt3") '("TAG1" "TAG2" "TAG3") '("VAL1" "VAL2" "VAL3")) If you wish to leave certain elements empty then do no pass those values but pass empty strings like (somefunc '("Prompt1" "Prompt2" "Prompt3") '("TAG1" "TAG2" "TAG3") '("" "VAL2" ""))
(defun somefunc (lst1 lst2 lst3 / checklst entname i prm pt1 tag testblk val vlaobj) (and (= (length lst1) (length lst2) (length lst3)) (mapcar '(lambda (x) (setq vlaobj (vlax-ename->vla-object (setq entname (cdr (assoc 330 (entget (tblobjname "block" (setq testblk (cdr (assoc 2 (entget x))))))))))) (and (not (member entname checklst)) (setq checklst (cons entname checklst)) (z2fd x) (setq i 0) (while (and (< i (length lst1)) (not (vl-catch-all-error-p (setq pt1 (vl-catch-all-apply 'getpoint '("\nEnter Tag Position :")))))) (setq prm (nth i lst1) tag (nth i lst2) val (nth i lst3)) (vla-addattribute vlaobj 20 acattributemodelockposition prm (vlax-3d-point pt1) tag val) (setq i (1+ i)) (command-s "._attsync" "_N" testblk)))) (mapcar 'cadr (ssnamex (ssget "_x" '((0 . "INSERT"))))))) (princ)) (defun z2fd (x) (setvar 'ctab (cdr (assoc 410 (entget x)))) (not (command-s "._zoom" "_O" x "")))
Hi John,
This is very close. I just would like to select them though.
I removed x but it came up with an error message. "error too few arguments"
Also what's the command to make the tag invisible?
Thanks a lot!
Hi Ranjit,
This is a silly question, but I don't even know how to run this.
Thanks,
I thought I explained it, maybe not well enough. Load both the lisp functions through appload (somefunc and z2fd). At the command prompt type
(somefunc '("Prompt1" "Prompt2" "Prompt3") '("TAG1" "TAG2" "TAG3") '("VAL1" "VAL2" "VAL3")). Use whatever values you need in place of Prompt1, Tag1, Val1 etc.
I am using 3 values as an example but you can use only 2 or how many ever you need. Fo rexample if you have 2 tag values then call the routine by typing (somefunc '("Prompt1" "Prompt2") '("TAG1" "TAG2") '("VAL1" "VAL2")) at command prompt.
No you probably explained it OK it's just me who has no clue.
Ok so I figured out how to get it to work and it works OK except when I click on a block and then click on the next box it's very glitchy.
Also the tags land in a very far off place under the blocks.
Thanks,
Check the text height value. I used a value of 20. You need to set it to whatever value you use in your drawing.
(vla-addattribute vlaobj 20 acattributemodelockposition prm (vlax-3d-point pt1) tag val); change the 20 to your text height and try
When I said to delete "X" I meant to change
(setq ss (ssget "X" '((0 . "INSERT"))))
to
(setq ss (ssget '((0 . "INSERT"))))
I'm not sure what you mean about tag visibility. I haven't run the routine, but maybe it leaves you looking at the block contents, so the ATTDEF is exposed.
But if you want the attibutes not to appear, you can either freeze their layer, or change their visibility code (vlax-put object 'visible 0), or maybe there's something specific about invisible attributes that I don't remember (but you can find it in help).
John F. Uhden
You need to change the mode argument of acAttributeModeLockPosition to acAttributeModeInvisible.
From the AutoCAD 2002 help:
"Mode
Sets options for attribute values associated with a block when you insert the block in a drawing.
The default values are stored in theAFLAGS system variable. Changing the AFLAGS setting affects the default mode for new attribute definitions and does not affect existing attribute definitions.
Invisible
Specifies that attribute values are not displayed or printed when you insert the block. ATTDISP overrides Invisible mode."
I don't know if that applies to the visibility of inserted attributes, but my former suggestions are valid.
I suppose we could make you an ATTVIS.lsp to turn on/off all attributes or just those in selected block insertions.
John F. Uhden
The program works now by selecting the blocks, I got it to work by removing the "X" as you suggested.
The only thing that will make this perfect is forcing CAD to build the Attributes invisibly in the blocks.
Here's a screenshot of the ATTDEF screen showing the option to check.
Thanks,
I wasn't aware that an ATTDEF has an "Invisible" property. This is not true for ATTRIBs.
It is not to be confused with the "Visible" property, which I think all graphic objects have.
Whatever code you use for creating the ATTDEFs, add the line (vlax-put attdef 'Invisible -1).
Note that "attdef" is what I named the vla-object here for example only. The actual symbol name in your code is probably different and must be used instead.
John F. Uhden
Man I am sorry but I have no clue what the name of the symbol is in this code. I tried to add that line but I'm not getting anywhere.
(defun c:addattribs ( / ss i blk blks def ) (and (setq ss (ssget "X" '((0 . "INSERT")))) (setq i (sslength ss)) (while (> i 0) (setq blk (cdr (assoc 2 (entget (ssname ss (setq i (1- i))))))) (if (not (vl-position blk blks))(setq blks (cons blk blks))) ) ) (foreach blk blks (setq def (vla-item (vla-get-blocks (vla-get-activedocument (vlax-get-acad-object))) blk)) (vla-addattribute def (getvar 'textsize)
(vlax-put ? 'Invisible -1) acattributemodelockposition "New Attribute 1" (vlax-3D-point 0 0) "NEW_TAG1" "New Value 1" ) (vla-addattribute def (getvar 'textsize)
(vlax-put ? 'Invisible -1) acattributemodelockposition "New Attribute 2" (vlax-3D-point 0 (- (* 1.5 (getvar 'textsize)))) "NEW_TAG2" "New Value 2" ) (command "_.attsync" "_N" blk) ) (princ) ) (vl-load-com) (princ)
I just found out that the vla-addattribute method can take a Mode code, so you could use the following...
(vla-addattribute def (getvar 'textsize)(vlax-put ? 'Invisible -1) acattributemodelockpositionacAttributeModeInvisible
"New Attribute 1"
(vlax-3D-point 0 0)
"NEW_TAG1"
"New Value 1"
)
Do this for as many attributes as you are creating. I think your example creates two.
Bear in mind:
"The Mode values are as follows:
acAttributeModeInvisible
Specifies that attribute values won't appear when you insert the block. The ATTDISP system variable overrides the Invisible mode.
..."
Also, get rid of that "X" again if you want to select the blocks
John F. Uhden
Thanks @Ranjit_Singh1 & @john.uhden
Ranjit had mentioned the acattributemodeinvisibile before and I tried to change it yesterday but it didn't work the way I was doing it.
I was hoping one of you could tell me one last thing. How do I change the height of the text?
Thanks,
Can't find what you're looking for? Ask the community or share your knowledge.