Visual LISP, AutoLISP and General Customization
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

VLA-SETBLOCKATTRIBUTEVALUE, please help

10 REPLIES 10
SOLVED
Reply
Message 1 of 11
mid-awe
1097 Views, 10 Replies

VLA-SETBLOCKATTRIBUTEVALUE, please help

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.

10 REPLIES 10
Message 2 of 11
hmsilva
in reply to: mid-awe

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... Smiley Sad

 

HTH
Henrique

EESignature

Message 3 of 11
mid-awe
in reply to: mid-awe

Thanks I'll give this a try.
Message 4 of 11
Lee_Mac
in reply to: mid-awe

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

Message 5 of 11
mid-awe
in reply to: Lee_Mac

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")

Message 6 of 11
Lee_Mac
in reply to: mid-awe

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))
Message 7 of 11
mid-awe
in reply to: Lee_Mac

I can't wait to try this. Thank you Lee.
Message 8 of 11
mid-awe
in reply to: Lee_Mac

Thank you very much Lee. This is exactly what I needed to understand what I was doing wrong and how to go about getting it right.

It seems the big issue I have is understanding what vlisp needs to do it's thing. All the nesting is difficult to follow. It's so different from the languages that I use often. With your help I've been getting closer.

Thank you again.
Message 9 of 11
Lee_Mac
in reply to: mid-awe

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

 

Message 10 of 11
mid-awe
in reply to: Lee_Mac


@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. Smiley Very Happy

Message 11 of 11
Lee_Mac
in reply to: mid-awe

It's never too late to learn something new! Smiley Happy

 

You're welcome mid-awe.

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk Design & Make Report

”Boost