Hi all,
My function builds a simple block table each row contains a block in the first column, block-name in the second column, & quantity in the third column.
One of my blocks does not have a preset attribute value and it gets added to the table with a blank attribute value. (kinda defeats the purpose.)
I found advice to use VLA-SETBLOCKATTRIBUTEVALUE to set the attribute value, but I cannot get it working.
In my code:
(VLA-SETCELLTYPE TblObj Rowcnt 0 ACBLOCKCELL) (VLA-SETCELLALIGNMENT TblObj Rowcnt 0 ACMIDDLECENTER) (VLA-SETBLOCKTABLERECORDID TblObj Rowcnt 0 (VLA-GET-OBJECTID (VLA-ITEM BlkCol BLKNam)) T) (VLA-SETBLOCKATTRIBUTEVALUE TblObj Rowcnt 0 (VLA-GET-OBJECTID (VLA-ITEM BlkCol "SLEEVE_TYPE")) NewVal) (VLA-SETBLOCKROTATION TblObj Rowcnt 0 4.71239)
Each part works except VLA-SETBLOCKATTRIBUTEVALUE. Do I have the syntax wrong? What's going on?
Thank you in advance for any suggestions.
Solved! Go to Solution.
Solved by Lee_Mac. Go to Solution.
Just a few ideas...
NewVal is a string, correct?
Are you on a 32 or 64 bit OS?
If you are in a 64 bit, test for the existence of the objectid32 property with vlax-property-available-p function, and if true get the objectid32 and set the new value with vla-setblockattributevalue32 function...
Mid-awe, sorry but is untested, at the moment I have no AutoCAD with me...
HTH
Henrique
The Object ID for the ActiveX setblockattributevalue method should be the ID for the Attribute Definition object (ATTDEF), not the Block Definition.
Furthermore, as Henrique correctly points out, you will need to use the associated setblocktablerecordid32 & setblockattributevalue32 64-bit methods & retrieve the objectid32 64-bit property to enable compatibility on a 64-bit system, which you can check using the following expression:
(wcmatch (getenv "PROCESSOR_ARCHITECTURE") "*64*")
Lee
I made changes based on the comments:
(VLA-SETCELLTYPE TblObj Rowcnt 0 ACBLOCKCELL) (VLA-SETCELLALIGNMENT TblObj Rowcnt 0 ACMIDDLECENTER) (IF (WCMATCH (GETENV "PROCESSOR_ARCHITECTURE") "*64*") (VLA-SETBLOCKTABLERECORDID32 TblObj Rowcnt 0 (VLA-GET-OBJECTID32 (VLA-ITEM BlkCol BlkNam)) T) (VLA-SETBLOCKTABLERECORDID TblObj Rowcnt 0 (VLA-GET-OBJECTID (VLA-ITEM BlkCol BlkNam)) T) ) (IF (VLAX-METHOD-APPLICABLE-P TblObj 'setblockattributevalue32) (VLA-SETBLOCKATTRIBUTEVALUE32 TblObj Rowcnt 0 (VLA-GET-OBJECTID32 (VLA-ITEM BlkCol BlkNam)) NewVal) (VLA-SETBLOCKATTRIBUTEVALUE TblObj Rowcnt 0 (VLA-GET-OBJECTID (VLA-ITEM BlkCol BlkNam)) NewVal) ) (VLA-SETBLOCKROTATION TblObj Rowcnt 0 4.71239)
I think I'm closer based on the suggestions but this still does not work. I am in unexplored territory for me, with no idea how to proceed.
(Maybe it doesn't work because the particular block that I'm using this for has two attributes and it's the first attribute that I want to change. attribute name is "SLEEVE_TYPE")
The problem is that you are using the Object ID of the Block Definition, not the Attribute Definition as required by the setblockattributevalue method.
I don't have much spare time these days, so the following code is hastily written and untested but should get you going in the right direction, assuming your variables are correctly defined:
(setq 64p (wcmatch (getenv "PROCESSOR_ARCHITECTURE") "*64*") tag (strcase "mytag") ) (vla-setcelltype tblobj rowcnt 0 acblockcell) (vla-setcellalignment tblobj rowcnt 0 acmiddlecenter) (if (and 64p (vlax-method-applicable-p tblobj 'setblocktablerecordid32)) (vla-setblocktablerecordid32 tblobj rowcnt 0 (vla-get-objectid32 (vla-item blkcol blknam)) :vlax-true) (vla-setblocktablerecordid tblobj rowcnt 0 (vla-get-objectid (vla-item blkcol blknam)) :vlax-true) ) (vl-catch-all-apply '(lambda nil (vlax-for obj (vla-item blkcol blknam) (if (and (= "AcDbAttributeDefinition" (vla-get-objectname obj)) (= tag (strcase (vla-get-tagstring obj))) ) (progn (setq att obj) (exit)) ;; not clean but only way to exit vlax-for loop prematurely ) ) ) ) (if (= 'vla-object (type att)) (if (and 64p (vlax-method-applicable-p tblobj 'setblockattributevalue32)) (vla-setblockattributevalue32 tblobj rowcnt 0 (vla-get-objectid32 att) newval) (vla-setblockattributevalue tblobj rowcnt 0 (vla-get-objectid att) newval) ) ) (vla-setblockrotation tblobj rowcnt 0 (* 1.5 pi))
You're very welcome mid-awe.
When working with the ActiveX component of Visual LISP, it greatly helps to first have a good understanding of the structure of the AutoCAD Object Model, and the hierarchy of how objects are stored and accessed.
For example, the Block Collection will contain the definitions for all blocks in the drawing, including the definitions for the Modelspace & Paperspace blocks representing each layout tab. However, these block definitions are Collections themselves, containing the block geometry to be transformed & displayed for each block reference inserted in the drawing (i.e. added to the Layout Block Definitions), and, for the case of the Layout blocks, the collection of all objects found in each layout.
And of course, I'm happy to explain these things as my time permits!
Lee
@Lee_Mac wrote:
When working with the ActiveX component of Visual LISP, it greatly helps to first have a good understanding of the structure of the AutoCAD Object Model, and the hierarchy of how objects are stored and accessed.
For example, the Block Collection will contain the definitions for all blocks in the drawing, including the definitions for the Modelspace & Paperspace blocks representing each layout tab. However, these block definitions are Collections themselves, containing the block geometry to be transformed & displayed for each block reference inserted in the drawing (i.e. added to the Layout Block Definitions), and, for the case of the Layout blocks, the collection of all objects found in each layout.
With AutoLISP we ask the acdb? I'll get it but I put off vlisp for too long. It's good to get help from intelligent people. Thank you again.
It's never too late to learn something new!
You're welcome mid-awe.