Help with vlax-property-available-p

Help with vlax-property-available-p

msarqui
Collaborator Collaborator
2,164 Views
15 Replies
Message 1 of 16

Help with vlax-property-available-p

msarqui
Collaborator
Collaborator

Hi guys,

 

I am having a hard day trying to validate if a block has attributes.

I think is something with AcadBlockReference versus AcadBlock but no clue how to solve this.

Could you help me please?

 

(vlax-for blk (vla-get-blocks (vla-get-activedocument (vlax-get-acad-object)))	;For each block
 (if (and
     (= (vla-get-islayout blk) :vlax-false)		;If it is not the layout itself
     (= (vla-get-isxref blk) :vlax-false)		;If it is not a xref
     (vlax-property-available-p vlobj 'HasAttributes)	;If it has attributes
     );and
     (vlax-for subent blk				;For each object inside the block
     (vla-put-layer subent "Defpoints")			;Change its layer
     (vla-put-color subent 30)				;Change its color
     );vlax
     );if
);vlax

Thanks,

Marcelo

0 Likes
Accepted solutions (1)
2,165 Views
15 Replies
Replies (15)
Message 2 of 16

Kent1Cooper
Consultant
Consultant

@msarqui wrote:

.... 

I am having a hard day trying to validate if a block has attributes.

... 

....
(vlax-property-available-p vlobj 'HasAttributes) ;If it has attributes ....

The property is available for any Block, whether or not it has attributes, so that test will always return T.  The value of that property is what you want to know -- 0 if it doesn't have them, and [oddly] -1 if it does [or you can investigate the :vlax-false/true thingie if you prefer].

Kent Cooper, AIA
Message 3 of 16

dbroad
Mentor
Mentor

No block definition (as you are parsing) has the hasattributes property.

 

All block references have the hasattributes property available. 

 

To test whether the block reference has attributes, use (vla-get-hasattributes <blockreferenceobject>)

Architect, Registered NC, VA, SC, & GA.
0 Likes
Message 4 of 16

msarqui
Collaborator
Collaborator

Sorry guys, I realised I made a mistake. This is what I should have posted:

 

 

(vlax-for blk (vla-get-blocks (vla-get-activedocument (vlax-get-acad-object)))	;For each block
 (if (and
     (= (vla-get-islayout blk) :vlax-false)		;If it is not the layout itself
     (= (vla-get-isxref blk) :vlax-false)		;If it is not a xref
     (vlax-property-available-p blk 'HasAttributes)	;If it has attributes
     );and
     (vlax-for subent blk				;For each object inside the block
     (vla-put-layer subent "Defpoints")			;Change its layer
     (vla-put-color subent 30)				;Change its color
     );vlax
);if
);vlax

It will not work even if I replace the red line by (= (vla-get-hasattributes blk) :vlax-false)

Thanks

Marcelo

 

0 Likes
Message 5 of 16

msarqui
Collaborator
Collaborator

I think I found the way...

 

(defun c:test ( / doc effname)
(setq doc (vla-get-activedocument (vlax-get-acad-object)))
(vlax-for layout (vla-get-layouts doc)
	(vlax-for obj (vla-get-block layout)						;For each object in the layout
		(if	(and
			(= (vla-get-objectname obj) "AcDbBlockReference")
			(= (vla-get-hasattributes obj) :vlax-true)
			);and
			(progn
			(vla-put-layer obj "Defpoints")					;Change its layer
			(setq effname (vla-get-EffectiveName obj))			;Get the EFFECTIVE NAME
			(if (not (member effname blklst))				;If the block is not yet member of the list
				(setq blklst (cons effname blklst))			;Put it on the list
			)
			(vlax-for subent (vla-item (vla-get-blocks doc) effname)	;For each item inside the "effname" block
				(vla-put-layer subent "Defpoints")			;Change its layer
				(vla-put-color subent 30)				;Change its color
			);vlax
			);progn
		);if
	);vlax
);vlax
(foreach i blklst									;For each member of the list
	(command "_.attsync" "_N" i)							;Sincronise
)
);defun

What do you think?

0 Likes
Message 6 of 16

devitg
Advisor
Advisor

Hi Msarqui , as stated before, a BLK , as part of BLOCK-Collection do not have HAS-ATTRIBUTE property , only block-reference have has-attribute property , and it could be :vlax-false or :vlax-true. 

If you want to change the attribute LAYER and COLOR 

 

(VL-LOAD-COM)

(setq blk-col (vla-get-blocks (vla-get-activedocument (vlax-get-acad-object))))

(setq blk (vla-item blk-col 3)); block 0 MODEL , 1 and 2 LAYOUT, 3 the onlyblock named CIRCLE   




(setq blk-item (vla-item blk 1));item 0 the circle , item 1 the attribute 

;;;#<VLA-OBJECT IAcadAttribute2 188de544> 


(if ( =(setq blk-item-name (vla-get-objectname blk-item)) "AcDbAttributeDefinition")
(progn
     (vla-put-layer blk-item-name "Defpoints")			;Change its layer
     (vla-put-color blk-item-name 30)				;Change its color
    )
 )

  ;;;(vlax-dump-Object blk t)

 

Give it 

 

; IAcadBlock2: A block definition containing a name and a set of objects
; Property values:
;   Application (RO) = #<VLA-OBJECT IAcadApplication 00d73d3c>
;   BlockScaling = 1
;   Comments = ""
;   Count (RO) = 2
;   Document (RO) = #<VLA-OBJECT IAcadDocument 189b72d0>
;   Explodable = 0
;   Handle (RO) = "1B6"
;   HasExtensionDictionary (RO) = 0
;   IsDynamicBlock (RO) = 0
;   IsLayout (RO) = 0
;   IsXRef (RO) = 0
;   Layout (RO) = AutoCAD.Application: The property is not available in current state
;   Name = "circle"
;   ObjectID (RO) = -1092688
;   ObjectName (RO) = "AcDbBlockTableRecord"
;   Origin = (0.0 0.0 0.0)
;   OwnerID (RO) = -1135608
;   Path = AutoCAD.Application: Not applicable
;   Units = 4
;   XRefDatabase (RO) = AutoCAD.Application: No database
0 Likes
Message 7 of 16

hmsilva
Mentor
Mentor
Accepted solution

Hi Marcelo,
as others have stated in the 'blocks' collectiom from 'activedocument' is stored the 'BlockTableRecord', the block definition, and the attribute definition, if present, is stored inside the 'BlockTableRecord' as 'AttributeDefinition' like any other entity belonging to the block, therefore there is no marker in the 'BlockTableRecord' to tell us if an attribute is present in the block definition, we'll have to look if there are a 'AttributeDefinition'...

 

One way:

Untested...

 

(defun has_attributes (vlaobj / flag)
   (if (= "AcDbBlockTableRecord" (vla-get-objectname vlaobj))
      (vlax-for x vlaobj
         (cond ((= "AcDbAttributeDefinition" (vla-get-objectname x))
                (setq flag T)
               )
               ((= "AcDbBlockTableRecord" (vla-get-objectname x))
                (has_attributes x)
               )
         )
      )
   )
   flag
)
(vlax-for blk (vla-get-blocks (vla-get-activedocument (vlax-get-acad-object))) ;For each block
   (if (and (= (vla-get-islayout blk) :vlax-false) ;If it is not the layout itself
            (= (vla-get-isxref blk) :vlax-false) ;If it is not a xref
            (has_attributes blk) ; If it has attributes
       ) ;and 
      (vlax-for subent blk ;For each object inside the block
         (vla-put-layer subent "Defpoints") ;Change its layer
         (vla-put-color subent 30) ;Change its color
      ) ;vlax
   ) ;if
) ;vlax

 

Hope this helps,
Henrique

EESignature

0 Likes
Message 8 of 16

dbroad
Mentor
Mentor

@msarqui  To each his own.  Your last code acknowledges the correct use of the hasattributes property.  The purpose of such a program is suspect.  It doesn't make any sense to me but if it does what you want, then you have succeeded.

Architect, Registered NC, VA, SC, & GA.
Message 9 of 16

msarqui
Collaborator
Collaborator

Hi everyone!

 

dbroad: thanks for your feedback. We receive lots of dwgs from others to use as xrefs, and we need to clean them up and apply our own standards. The code will put all attributed blocks to defpoints because we need to preserve the information, but we do not need to plot it. This is only a small part of the code. It has other "features".

 

devitg: I tested your code in my dwg and in your attached file and I had this: ; error: bad argument type: VLA-OBJECT "AcDbAttributeDefinition"

 

hmsilva: working as a charm. It is realy interesting your "has_attributes" function.
 
 
Many thanks to all.
 
 
Marcelo

 

 

0 Likes
Message 10 of 16

Kent1Cooper
Consultant
Consultant

@msarqui wrote:

.... The code will put all attributed blocks to defpoints ....


If that's the only reason for all this, it can be done much more simply.  The (assoc 66) entry in entity data indicates whether a Block has Attributes [1 if it does, 0 if it doesn't]:

 

(if (setq attblks (ssget "_X" '((0 . "INSERT") (66 . 1))))

  (command "_.chprop" attblks "" "_layer" "Defpoints" "")

)

 

I would suggest not using the Defpoints Layer for this [a practice that is a holdover from the days long ago when you couldn't set a Layer to not plot, and Defpoints was the only one that didn't], because they're not Dimension definition points, but making a different for-the-purpose non-plotting Layer.

Kent Cooper, AIA
0 Likes
Message 11 of 16

devitg
Advisor
Advisor

Since the first post 

 

 

are we talking BLOCK from the Block-collection , or referencedBlock from the DWG ??

 

 

as get from 

(ssget "_X" '( '( 0 . "insert"))
0 Likes
Message 12 of 16

Kent1Cooper
Consultant
Consultant

@devitg wrote:

....

are we talking BLOCK from the Block-collection , or referencedBlock from the DWG ??

 

....

From the sentence I quoted in Post 10, and the paragraph it comes from in Post 9, I assumed Block references/insertions.  But it could be that they mean to move all the pieces within the definitions of all Blocks with Attributes to that Layer.

Kent Cooper, AIA
0 Likes
Message 13 of 16

dbroad
Mentor
Mentor

Devit,

Your selection set would collect block references (inserts).

Architect, Registered NC, VA, SC, & GA.
0 Likes
Message 14 of 16

devitg
Advisor
Advisor

From post  #1 from Msarquis 

 

 

 

Spoiler

I am having a hard day trying to validate if a block has attributes.

I think is something with AcadBlockReference versus AcadBlock but no clue how to solve this.

So it is about AcadBlock or AcadBlockReference ??

 

 

Up now I do not know if he need to change the Att at the AcadBlockReference or the 

"AcDbAttributeDefinition" at the AcadBlock

AS I understand , he need to change the AcadBlock as per it 

 

(vlax-for subent (vla-item (vla-get-blocks doc) effname)	;For each item inside the "effname" block
				(vla-put-layer subent "Defpoints")			;Change its layer
				(vla-put-color subent 30)				;Change its color
			);vlax

 

 

 

 

 

0 Likes
Message 15 of 16

dbroad
Mentor
Mentor

@devitg  The OP has solved his problem. There are certainly other ways he could have solved it but changing a block definition does not affect the attributes unless they are synchronized which as other unintended side effects.  Other sub-entities could be changed to defpoints as you suggest.

Architect, Registered NC, VA, SC, & GA.
0 Likes
Message 16 of 16

devitg
Advisor
Advisor

Ok , thanks.

 

0 Likes