Lisp for Attribute to text within a block

Lisp for Attribute to text within a block

Anonymous
Not applicable
5,576 Views
27 Replies
Message 1 of 28

Lisp for Attribute to text within a block

Anonymous
Not applicable

Hallo everybody

 

 

I found this great lisp on internet converting attributes into text

This routine will get all the attributes in a dwg ans make them into text except for attributes inside a block.

what do i need to do for this routine to make it work with block attributes as well?

 

 

(defun c:AttDef2Text (/ ActDoc LayoutCol tmpLayoutBlk)
 ; Changes attdef entities (attributes that haven't been put into a block) into dtext

 (vl-load-com)
 (setq ActDoc (vla-get-ActiveDocument (vlax-get-Acad-Object)))
 (vla-StartUndoMark ActDoc)
 (setq LayoutCol (vla-get-Layouts ActDoc))
 (vlax-for LayoutObj LayoutCol
 (setq tmpLayoutBlk (vla-get-Block LayoutObj))
 (vlax-for Obj tmpLayoutBlk
 (if (= (vla-get-ObjectName Obj) "AcDbAttributeDefinition")
 (progn
 (setq TextObj (vla-AddText tmpLayoutBlk (vla-get-textString Obj) (vla-get-InsertionPoint Obj) (vla-get-Height Obj)))
 (vla-put-Alignment TextObj (vla-get-Alignment Obj))
 (if (/= (vla-get-Alignment TextObj) 0)
 (vla-put-TextAlignmentPoint TextObj (vla-get-TextAlignmentPoint Obj))
 )
 (vla-put-Backward TextObj (vla-get-Backward Obj))
 (vla-put-Layer TextObj (vla-get-Layer Obj))
 (vla-put-Normal TextObj (vla-get-Normal Obj))
 (vla-put-ObliqueAngle TextObj (vla-get-ObliqueAngle Obj))
 (vla-put-Rotation TextObj (vla-get-Rotation Obj))
 (vla-put-ScaleFactor TextObj (vla-get-ScaleFactor Obj))
 (vla-put-StyleName TextObj (vla-get-StyleName Obj))
 (vla-put-UpsideDown TextObj (vla-get-UpsideDown Obj))
 (vla-Delete Obj)
 )
 )
 )
 )
 (vla-EndUndoMark ActDoc)
 (princ)
 )

Kind regards

 

0 Likes
5,577 Views
27 Replies
Replies (27)
Message 21 of 28

Anonymous
Not applicable

HI

 

Can you pls sent me your dwg as reference check for me?

it might be indeed some settings

 

 

0 Likes
Message 22 of 28

Anonymous
Not applicable

Found it

Only entities on layer 0 will be done
Everything on a layeer different then 0 will be excluded

@DGRL
Change all the entities in your block too 0 and it will work

@Kent1Cooper
Can you make it work for all entities no Mather what layer they on?





looks like something with the dwg used
i made a brand new dwg new block with attributes
just 3 and run the command
works fine
when using template of my client ( made in older version of acad i guess i get same result as @DGRL )
Maybe if you like you can try his dwg Pls do know that the block in his dwg is currently at scale .5 pls change to 1.0 before running command )

I exploded his block purged the dwg redifined the block again scale 1 allow explode
Run command again same result as before
So i wonder what setting is causing this

 

0 Likes
Message 23 of 28

DGRL
Advisor
Advisor

Forgot what i said about the change to _All
It will take whole dwg and make it a block lol

Its just weird that only entities on layer 0 will be done and not everything else

 

 

 

@Kent1Cooper


For the block i use there is something with the insertion point
the whole block is reinserted in wrong place
I know for sure it is not your code but something with the block it self
do you have any idea what that can be?
Copy of the block can be downloaded few post back

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

DGRL
Advisor
Advisor

@Kent1Cooper


I fixed the issue with my block
Only thing left in your code ( don't know what it is ) is to fix the issue that only layer 0 will be processed

Wicked lol

 

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

DGRL
Advisor
Advisor

@Kent1Cooper

 

I just found out that the issue we are talking about only accurse when Attributes are present in the block

When no attributes in block everything works just fine
As soon there is 1 attribute in the block then the _previous of the block command will only process entities that are in same layer as Attributes are or at least everything on layer 0

I hope I am not to confusing
Need more info pls let me know


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

Anonymous
Not applicable

@Kent1Cooper

 

Hi

 

Thank you for the reply
As mentioned earlier the routine only process the ATT's in a block after bursting
Do you know how to "fix" this?

 

0 Likes
Message 27 of 28

Kent1Cooper
Consultant
Consultant

@Anonymous wrote:

.... the routine only process the ATT's in a block after bursting
Do you know how to "fix" this?

 


My quick experiments must have been with everything drawn on Layer 0, so it worked according to @DGRL's description in Post 25.  The one possibility that comes to mind to fix it is to check for the last entity in the drawing before Bursting, and then find everything newer than that afterwards for the selection in the new Block definition.  That's not hard [there are a variety of routines on these Forums that do it], but it depends on the results of Bursting all being newer than everything else, which I expect would be the case, but I'd like to experiment [if someone else doesn't beat me to it].

Kent Cooper, AIA
0 Likes
Message 28 of 28

DGRL
Advisor
Advisor

 

UPDATE

Step 4 is needed coz you filter in step 6 the value of ATT and that is not set inside the AcDbAttributeDefinition ( at least not in my blocks)

 

 

@Kent1Cooper

 

 

Why approaching it so complicated?

What if you do this?

 

1.  get all entities inside the block

2.  Then filter all on ATTRIB and with dictnext filter on ACAD_FIELD ( I don't know if @Anonymous has fields in the ATTRIBS but I have )
3.  Get all the needed info like assoc 1 / 2 / 10 ect

4.  fill in the VALUE of the attrib extracted from the AcDbBlockReference and put it in AcDbAttributeDefinition ( im still thinking WHY/IF this step is needed )
5.  in the mean time construct lists that you can use later in the script.
6.  Start a new foreach and filter now on {ACAD_XDICTIONARY and (dictnext dict "ACAD_FIELD")

7.  read out needed values and construct list like step 3 and VLA-DELETE the ATTRIB

8. 

	(setq en (ssget "_X" '((2 . "YOURBLOCKNAME"))) )
(sssetfirst nil en); pre-selection for use by BURST
(C:BURST) (command "_.block" "Titelblok AFS11" "_yes" insert "_previous" "" "_.insert" "Titelblok AFS11" "_scale" 1 "_rotate" 0 insert ;"_.matchprop" blkref (entlast) "" ; for Layer, any other properties ;"_.erase" blkref "" ); command

 

9.  Now do vla-Add block

 

				(setq dx11 '(0.0 0.0 0.0)) ;insertionpoint like in blockeditor
				(setq	*acadobj* (vlax-get-acad-object)
						*acaddoc* (vla-get-activedocument *acadobj*)
						*blocks*  (vla-get-blocks *acaddoc*)
						BlkObj	  (vla-Add *blocks* (vlax-3D-Point dx11) blk)
				)

 

10.  you made a list before with needed info that you need now

11.From here with a foreach you could do  (vla-AddMText .....

 

 

I think I have some steps in this that are not needed but I think you get the point
Its easy to think but hard to code

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