How Can I Obtain an Attribute's Prompt Message
Hello:
I am just playing around with LISP trying to build a little program for myself and I have run into a problem, I can get to the value and tag of a selected attribute using
[code]
(setq entity (nentsel "\nSELECT AN ATTRIBUTE TO EDIT: ")) ;Select an attribute - no bad selection handling shown.
(setq SelectedAtt (cdr (assoc 2 (entget (car entity))))) ;Get the ID of the selected attribute
(setq Object (vlax-ename->vla-object (car entity))) ;Get the object reference for my selected entity
(setq AttValue (vla-get-textstring Object)) ;Grab the value of the selected attribute [/code]
So, the one thing I am missing is how to get the prompt for the attribute that the user selected (or hopefully selected as my code won't work if they don't select one).
Any ideas?
0
Comments
-
You have to dig a little deeper for the prompt string. It is a property of the corresponding attribute definition. It is one of the few thing that an attribute reference actually references.0
-
If you are trying to create a Lisp utility to edit a single attribute you should consider two things:
1.
There are mtext attributes which can contain special formatting. You cannot display this properly in a DCL dialog.
2.
If you double-clicks on an attribute the BC Attribute Editor will open with the value of that attribute preselected. So if you want to change a single attribute there is no need to scroll and search. Just type the new value and press OK.0 -
Hi Roy:Thanks for the tip, I am still struggling but I am hoping to make some progress later today...Yup, I am building a light weight attribute editor - sometimes I find the supplied dialog cumbersome, mainly that the enter button jumps to the next attribute instead of just accepting the changes. I did run into the formatting issue this am when attempting to edit an attribute who's value was 3"=1'-0", it will take some interesting programming to write something to parse through the string and escape the characters before putting them into a dialog...0
-
I did a bit more digging this am and realized that ENTNEXT is what I need to get to the ATTDEF, but the next entity is a (0 . "SEQEND") not an (0 . "ATTDEF") as expected.[code](setq entity (nentsel "\nSELECT AN ATTRIBUTE TO EDIT: "))[/code]Returns: (setq entity (nentsel "\nSELECT AN ATTRIBUTE TO EDIT: "))[code](entget (car entity))[/code]Returns: ((-1 . ) (0 . "ATTRIB") (5 . "3E2FB") (330 . ) (100 . "AcDbEntity") (67 . 0) (410 . "Model") (8 . "0") (6 . "ByBlock") (100 . "AcDbText") (10 11.1683605145269 6.6679508020378 0.0) (40 . 0.09375) (1 . "-") (50 . 0.0) (41 . 1.0) (51 . 0.0) (7 . "PGSNotes") (71 . 0) (72 . 1) (11 11.2085390859554 6.7148258020378 0.0) (210 0.0 0.0 1.0) (100 . "AcDbAttribute") (2 . "ID") (70 . 0) (73 . 0) (74 . 2) (280 . 0))
Returns: ((-1 . ) (0 . "SEQEND") (5 . "3E2FC") (330 . ) (100 . "AcDbEntity") (67 . 0) (410 . "Model") (8 . "TEXT") (-2 . ))
Should this last line of code not return an item that is (0 . "ATTDEF")?
The block that I am playing with is a simple rectangle with one attribute in it.
0 -
Have to repost, made a mistake with the output from the first line of code.....[code](setq entity (nentsel "\nSELECT AN ATTRIBUTE TO EDIT: "))[/code]Returns: ( (11.2454763312328 6.716128962967 0.0))[code](entget (car entity))[/code]Returns: ((-1 . ) (0 . "ATTRIB") (5 . "3E2FB") (330 . ) (100 . "AcDbEntity") (67 . 0) (410 . "Model") (8 . "0") (6 . "ByBlock") (100 . "AcDbText") (10 11.1683605145269 6.6679508020378 0.0) (40 . 0.09375) (1 . "-") (50 . 0.0) (41 . 1.0) (51 . 0.0) (7 . "PGSNotes") (71 . 0) (72 . 1) (11 11.2085390859554 6.7148258020378 0.0) (210 0.0 0.0 1.0) (100 . "AcDbAttribute") (2 . "ID") (70 . 0) (73 . 0) (74 . 2) (280 . 0))
Returns: ((-1 . ) (0 . "SEQEND") (5 . "3E2FC") (330 . ) (100 . "AcDbEntity") (67 . 0) (410 . "Model") (8 . "TEXT") (-2 . ))
Should this last line of code not return an item that is (0 . "ATTDEF")?
The block that I am playing with is a simple rectangle with one attribute in it.
0 -
To get to the attribute definition you have to start digging in the block definition.
You can do this using 'Classic' Lisp but I would use Visual Lisp instead.
[code]; (PromptStringAttRef (vlax-ename->vla-object (car (nentsel))))
(defun PromptStringAttRef (obj)
(cond
((= "AcDbAttributeDefinition" (vla-get-objectname obj))
(prompt "\nError: constant attribute ")
)
((= "AcDbAttribute" (vla-get-objectname obj))
(PromptStringBlockDef (vla-get-name (_Sys_ObjectOwner obj)) (vla-get-tagstring obj))
)
)
)
; (PromptString "TitleBlock_Small" "ClientAddress")
(defun PromptStringBlockDef (name tag)
(setq tag (strcase tag))
(if (tblobjname "block" name)
(vl-some
'(lambda (obj)
(if
(and
(= "AcDbAttributeDefinition" (vla-get-objectname obj))
(= tag (strcase (vla-get-tagstring obj)))
)
(vla-get-promptstring obj)
)
)
(vle-collection->list
(vla-item
(vla-get-blocks (vla-get-activedocument (vlax-get-acad-object)))
name
)
)
)
)
)
(defun _Sys_ObjectOwner (obj)
(vla-objectidtoobject (vla-get-database obj) (vla-get-ownerid obj))
)[/code]0 -
For comparison the 'Classic' approach.
[code]; (Classic_PromptStringAttRef (car (nentsel)))
(defun Classic_PromptStringAttRef (enme / elst)
(cond
((= "ATTRIB" (cdr (assoc 0 (setq elst (entget enme)))))
(Classic_PromptStringBlockDef
(cdr (assoc 2 (entget (cdr (assoc 330 elst))))) ; Block name from the insert.
(cdr (assoc 2 elst)) ; Tag from the attribute.
)
)
((= "ATTDEF" (cdr (assoc 0 (entget enme))))
(prompt "\nError: constant attribute ")
)
)
)
; (Classic_PromptStringBlockDef "TitleBlock_Small" "ClientAddress")
(defun Classic_PromptStringBlockDef (name tag / enme elst ret)
(setq tag (strcase tag))
(if (setq enme (tblobjname "block" name))
(while
(and
enme ; Will be set to nil if the attribute is found.
(setq enme (entnext enme))
(/= "ENDBLK" (cdr (assoc 0 (setq elst (entget enme)))))
)
(if
(and
(= "ATTDEF" (cdr (assoc 0 elst)))
(= tag (strcase (cdr (assoc 2 elst))))
)
(setq
ret (cdr (assoc 3 elst))
enme nil
)
)
)
)
ret
)[/code]0 -
Interesting, thank you for the tip, it looks like I cannot obtain the prompt directly from the attrib item, instead I need to grab the details of the parent block and go down from there. I appreciate the help!0
This discussion has been closed.