vlax-invoke obj 'getattributes returns textstring of *TEXT

vlax-invoke obj 'getattributes returns textstring of *TEXT

DGRL
Advisor Advisor
4,333 Views
24 Replies
Message 1 of 25

vlax-invoke obj 'getattributes returns textstring of *TEXT

DGRL
Advisor
Advisor

Dear coders

 

Have some strange outcomes of my code

 

Want to get the textstring of the ATTRIB and the ATTDEF

If i run the code below i also get back the text string of *TEXT and i wonder why since i am filtering on attribute
If i compare the print out of the block reference with the print out of the attribute definition then i see in the first list also text strings of *TEXT
How do i make sure i only get the text strings of ATTRIB and ATTDEF??

 


(vlax-for blk (vla-get-blocks (vla-get-activedocument (vlax-get-acad-object)));get block collection (vlax-for obj blk (cond ( (= "AcDbBlockReference" (vla-get-objectname obj)) (if (= :vlax-true (vla-get-hasattributes obj)) (foreach att (vlax-invoke obj 'getattributes) (print (vla-get-textstring att)) ) ) ) ( (= "AcDbAttributeDefinition" (vla-get-objectname obj)) (print (vla-get-textstring obj)) ) ) ); end of vlax-for obj blk (princ) ); end of vlax-for blk

 

 

If this was of any help please kudo and/or Accept as Solution
Kind Regards
0 Likes
4,334 Views
24 Replies
Replies (24)
Message 2 of 25

_gile
Consultant
Consultant

It should not.

 

Try this which may help you to diagnose, and if you still have an issue, post the drawing causing this.

 

(vlax-for blk (vla-get-blocks (vla-get-activedocument (vlax-get-acad-object))) ;get block collection
  (vlax-for obj blk
    (cond
      ((= "AcDbBlockReference" (vla-get-objectname obj))
       (if (= :vlax-true (vla-get-hasattributes obj))
         (foreach att (vlax-invoke obj 'getattributes)
           (print (strcat "Attribute Reference: " (vla-get-textstring att)))
         )
       )
      )
      ((= "AcDbAttributeDefinition" (vla-get-objectname obj))
       (print (strcat "Attribute Definition: " (vla-get-textstring obj)))
      )
    )
  )
  (princ)
)


Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 Likes
Message 3 of 25

DGRL
Advisor
Advisor

@_gile

 

I will  prepare a dwg for you to test because i get the same result
Thanks for the add you did it makes the print nicer 😄

 

 

Found also another thing

 

When i have block X inserted 5 times it only gives back 1 ATTDEF and 5 ATTREF

Even though it is the same block i need the result to be 5 times ATTDEF and 5 times ATTREF

But this is for later

 

 

If this was of any help please kudo and/or Accept as Solution
Kind Regards
0 Likes
Message 4 of 25

DGRL
Advisor
Advisor

@_gile

 

I have to apologize to you.

 

The reason why i got *text back in the result is because some ***  placed attribute's in the template with fields referring to *text objects in the same template

 

That's why i thought that the result given contained *text while in fact it is just the text string of the field

 

 

 

If this was of any help please kudo and/or Accept as Solution
Kind Regards
0 Likes
Message 5 of 25

DGRL
Advisor
Advisor

@_gile

 

 

I still have issues with the length of the list

 

_$ (length fexpp)
58
_$ (length fexpp1)
55
_$

 

Any idea what this can be?

it seems that there are  3 ATTRIBS in the block but not as ATTDEF

will dive into this and see what i can find

 

If this was of any help please kudo and/or Accept as Solution
Kind Regards
0 Likes
Message 6 of 25

_gile
Consultant
Consultant

@DGRL wrote:

@_gile

 

 

I still have issues with the length of the list

 

_$ (length fexpp)
58
_$ (length fexpp1)
55
_$

 

Any idea what this can be?

 


Absolutely none.

I do not know anything about neither fexpp nor fexpp1...

 

Anyway some block references may have attributes references different from the attribute definitions in the block defefinition* until you synchronize the attributes with ATTSYNC.

 

* you can insert  some block in the drawing, then edit/add/remove the attribute definitions in the block definition.



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 Likes
Message 7 of 25

DGRL
Advisor
Advisor

@_gile

 

Excuse for not mentioning what fexpp and fexpp1 is

 

Fexpp   is the (get-text-string) of "AcDbBlockReference" (ATTRIB)

Fexpp1 is the (get-text-string) of "AcDbAttributeDefinition" (ATTDEF)

 

It is kinda weird that the length of the list for blockreference is 58 and the length of the list for AcDbAttributeDefinition is 55

 

And attsync had been done but will redo to be sure

will let you know

 

 

If this was of any help please kudo and/or Accept as Solution
Kind Regards
0 Likes
Message 8 of 25

_gile
Consultant
Consultant

Is there exactly one block reference per block definition (including nested blocks)?



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 Likes
Message 9 of 25

DGRL
Advisor
Advisor

i am preparing the dwg for you

might take some time i will filter a lot of working att's out of the dwg for you @_gile

 

If this was of any help please kudo and/or Accept as Solution
Kind Regards
0 Likes
Message 10 of 25

DGRL
Advisor
Advisor

@_gile

 

After filtering out the working att's i ended up with a different of 5

thats the block inserted 6 times

1 time counted miss 5

 

Is there a way that i will process every block maybe by ename or handle?

 

If this was of any help please kudo and/or Accept as Solution
Kind Regards
0 Likes
Message 11 of 25

Anonymous
Not applicable

Sorry, I do not understand what you're trying to achieve.

 

(vlax-for blk (vla-get-blocks (vla-get-activedocument (vlax-get-acad-object)))
  (vlax-for obj blk
    ...
  )
)

This expression will iterate through any entity in any 'block definition' (including spaces).

You can trust it, it's more reliable than counting attribute references or definitions by yourself.

0 Likes
Message 12 of 25

DGRL
Advisor
Advisor

@_gile

 

I will re write my code and will let you know the result

 

If this was of any help please kudo and/or Accept as Solution
Kind Regards
0 Likes
Message 13 of 25

DGRL
Advisor
Advisor

@_gile@Anonymous

 

Take a look at the dwg

1 block

inserted 6 times

below code is result

 

(vlax-for blk (vla-get-blocks (vla-get-activedocument (vlax-get-acad-object)))
	(vlax-for obj blk
		(cond
		((= "AcDbBlockReference" (vla-get-objectname obj))
		(if (= :vlax-true (vla-get-hasattributes obj))
			(foreach att (vlax-invoke obj 'getattributes)
			(print (strcat "Attribute Reference: " (vla-get-textstring att)))
			
			)
		)
		)
		((= "AcDbAttributeDefinition" (vla-get-objectname obj))
		(print (strcat "Attribute Definition: " (vla-get-textstring obj)))
		)
		)
	)
)

 

Result

 

"Attribute Reference: \\W0.8000;1"
"Attribute Reference: \\W0.8000;2"
"Attribute Reference: \\W0.8000;3"
"Attribute Reference: \\W0.8000;4"
"Attribute Reference: \\W0.8000;5"
"Attribute Reference: \\W0.8000;6"
"Attribute Definition: \\W0.8000;DREWSASD" nil

 

As you can see

6 times REFERENCE

1 time  DEFINITION

 

I need 6 times REF and 6 times DEF

 

If this was of any help please kudo and/or Accept as Solution
Kind Regards
0 Likes
Message 14 of 25

ActivistInvestor
Mentor
Mentor

Your drawing contains 6 insertions of a block named "AnnoCircle".

 

What I, and probably most others here are completely baffled by is:

 

    "I need 6 times REF and 6 times DEF"

 

What does that mean?  There is only one block definition (and within that, only one attribute definition) in the drawing, along with 6 insertions of the block.

 

It seems that you're problem stems from a basic misunderstanding of the relationship between the definition and the reference (either blocks or attributes).

 

You need to provide overview of what your code's ultimate objective is.

 

 


@DGRLwrote:

@_gile@Anonymous

 

Take a look at the dwg

1 block

inserted 6 times

below code is result

 

(vlax-for blk (vla-get-blocks (vla-get-activedocument (vlax-get-acad-object)))
	(vlax-for obj blk
		(cond
		((= "AcDbBlockReference" (vla-get-objectname obj))
		(if (= :vlax-true (vla-get-hasattributes obj))
			(foreach att (vlax-invoke obj 'getattributes)
			(print (strcat "Attribute Reference: " (vla-get-textstring att)))
			
			)
		)
		)
		((= "AcDbAttributeDefinition" (vla-get-objectname obj))
		(print (strcat "Attribute Definition: " (vla-get-textstring obj)))
		)
		)
	)
)

 

Result

 

"Attribute Reference: \\W0.8000;1"
"Attribute Reference: \\W0.8000;2"
"Attribute Reference: \\W0.8000;3"
"Attribute Reference: \\W0.8000;4"
"Attribute Reference: \\W0.8000;5"
"Attribute Reference: \\W0.8000;6"
"Attribute Definition: \\W0.8000;DREWSASD" nil

 

As you can see

6 times REFERENCE

1 time  DEFINITION

 

I need 6 times REF and 6 times DEF

 


 

0 Likes
Message 15 of 25

DGRL
Advisor
Advisor

@ActivistInvestor

 

What i mean is,

 

 

Since every insert has its own ename

((-1 . <Entity name: 7ffffb53b50>) (0 . "INSERT")
((-1 . <Entity name: 7ffffb53b30>) (0 . "INSERT")

((-1 . <Entity name: 7ffffb53b40>) (0 . "INSERT")

((-1 . <Entity name: 7ffffb53b80>) (0 . "INSERT")

((-1 . <Entity name: 7ffffb53b60>) (0 . "INSERT")

((-1 . <Entity name: 7ffffb53b70>) (0 . "INSERT")

 

These six insertion which happens to be one block definition  still contains the entget assoc list which as far as i know can be used to access that particular block
And therefore i assumed that it might be possible to generate a list that contains the text string of the ATTRIB and the ATTDEF

The reason why i need to make a list of the text value from both ATTDEF and ATTRIB is quit long and does not add value

 

 

 

 

 

If this was of any help please kudo and/or Accept as Solution
Kind Regards
0 Likes
Message 16 of 25

ActivistInvestor
Mentor
Mentor

I can see no purpose to generating a list of items that contain data from both the attribute reference (ATTRIB) and the attribute definition (ATTDEF), because the value for the attribute definition in each list element will be the same value, because all of the ATTREFs refer to the same ATTDEF.

 

What purpose is there to doing that?

 


@DGRLwrote:

@ActivistInvestor

 

What i mean is,

 

 

Since every insert has its own ename

((-1 . <Entity name: 7ffffb53b50>) (0 . "INSERT")
((-1 . <Entity name: 7ffffb53b30>) (0 . "INSERT")

((-1 . <Entity name: 7ffffb53b40>) (0 . "INSERT")

((-1 . <Entity name: 7ffffb53b80>) (0 . "INSERT")

((-1 . <Entity name: 7ffffb53b60>) (0 . "INSERT")

((-1 . <Entity name: 7ffffb53b70>) (0 . "INSERT")

 

These six insertion which happens to be one block definition  still contains the entget assoc list which as far as i know can be used to access that particular block
And therefore i assumed that it might be possible to generate a list that contains the text string of the ATTRIB and the ATTDEF

The reason why i need to make a list of the text value from both ATTDEF and ATTRIB is quit long and does not add value

 

 

 

 

 


 

 

 

0 Likes
Message 17 of 25

DGRL
Advisor
Advisor

I need to check drawings containing more then these 6 blocks

And mostly only ,multiple inserts on 1 block definition

some made an error and place what supposed to be the ATTRIB value in the ATT default

Easy to fix only not when you have multiple inserts


But how about this

Even though there are 6 inserts of 1 block definition all the blocks still contains the ATT and therefore there are 6 ATT's

On database level there might be 1 definition but on entity level there are 6.

I still select 6 block or am i wrong thinking like this?

 

 

If this was of any help please kudo and/or Accept as Solution
Kind Regards
0 Likes
Message 18 of 25

ActivistInvestor
Mentor
Mentor

@DGRLwrote:

I need to check drawings containing more then these 6 blocks

And mostly only ,multiple inserts on 1 block definition

some made an error and place what supposed to be the ATTRIB value in the ATT default

Easy to fix only not when you have multiple inserts


But how about this

Even though there are 6 inserts of 1 block definition all the blocks still contains the ATT and therefore there are 6 ATT's

On database level there might be 1 definition but on entity level there are 6.

I still select 6 block or am i wrong thinking like this?

 

 


 

To correct erroneous data in an attribute definition, you don't need the insertions/attributes.  There is only one attribute definition, regardless of how many inserts/attributes of the block exist. I still can't figure out what your ultimate goal is, and without that I can't suggest any way to achieve it.

 

0 Likes
Message 19 of 25

_gile
Consultant
Consultant

The text in an attribute definition got with (cdr (assoc 1 ...)) or (vla-get-TextString ...) is the default value for the attribute reference, in other words, the 'value' of the attribute reference when you insert the block with ATTREQ = 0.



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 Likes
Message 20 of 25

DGRL
Advisor
Advisor

@ActivistInvestor

 

 

All I need is to access the  ; IAcadAttribute: AutoCAD Attribute Interface which contains the textstring I am after and I need to access the ; IAcadAttributeReference: AutoCAD Attribute Reference Interface

 

 

Do a dump of an attdef in a block and see for your self

 

If this was of any help please kudo and/or Accept as Solution
Kind Regards
0 Likes