Visual Basic Customization

Visual Basic Customization

Reply
Contributor
hakand
Posts: 14
Registered: ‎03-07-2012
Message 1 of 7 (667 Views)
Accepted Solution

Getting Constant Attribute using VB.net

667 Views, 6 Replies
03-20-2012 09:14 PM

Hey guys,

 

Just wondering how I would be able to grab the block constant attribute by searching via tag.

 

eg block has a constant attribute 'Color' with value of 'red' and I wish to attain 'red'

 

I am currently obtaining non constant attributes using:

Dim attRef As AttributeReference = DirectCast(tr.GetObject(attId, OpenMode.ForRead), AttributeReference)

and grabbing the '.textstring' when looking at the '.tag'

 

How do I go about this with similar logic but pointing to constant attributes?

 

I have tried searching thoroughly and almost all results for me were in VBA.

 

Many thanks

The c# statement

 

[Type] something=...... as [Type]

 

is not the same as DirectCast() in VB, rather it is similar to TryCast(). You cannot DirectCast() whatever in a block definition into an AttributeDefinition, if it is not an AttributeDefinition.

 

So, simple change this line:

 

Dim ad As AttributeDefinition = DirectCast(tr.GetObject(id, OpenMode.ForRead), AttributeDefinition)

To:

 

Dim ad As AttributeDefinition = TryCast(tr.GetObject(id, OpenMode.ForRead), AttributeDefinition)

Board Manager
StephenPreston
Posts: 418
Registered: ‎05-22-2006
Message 2 of 7 (661 Views)

Re: Getting Constant Attribute using VB.net

03-20-2012 10:11 PM in reply to: hakand

Constant attributes are stored as AttributeDefinitions in the BlockTableRecord. They're not stored with the BlockReference because they are constant across all BlockReferences.

 

Cheers,

Stephen Preston
Autodesk Developer Network
Contributor
hakand
Posts: 14
Registered: ‎03-07-2012
Message 3 of 7 (645 Views)

Re: Getting Constant Attribute using VB.net

03-21-2012 06:02 PM in reply to: StephenPreston

Ah thank you for the answer. I'm still trying to get my head around this as there aren't many examples available.

 

How would I cycle through my blocks and point to a specific constant tag and grab the textstring?

 

Could anyone please provide an example or something related in vb.net?

 

Or if anyone could please show how I would implement it into the below code I am currently using, that would be much appreciated.

 

 

 

            Dim idArray As ObjectId() = selSet.GetObjectIds()

            For Each blkId As ObjectId In idArray

 

                Dim blkRef As BlockReference = DirectCast(tr.GetObject(blkId, OpenMode.ForRead), BlockReference)

                Dim btr As BlockTableRecord = DirectCast(tr.GetObject(blkRef.BlockTableRecord, OpenMode.ForRead), BlockTableRecord)

 

                Dim attCol As AttributeCollection = blkRef.AttributeCollection

 

                For Each attId As ObjectId In attCol

                    Dim attRef As AttributeReference = DirectCast(tr.GetObject(attId, OpenMode.ForRead), AttributeReference)

                    Dim str As String = ((vbLf & "  Attribute Tag: " + attRef.Tag & vbLf & "    Attribute String: ") + attRef.TextString)

                    If attRef.Tag = "COLOR" Then

                        If grouparray.Contains(attRef.TextString) = False Then

                            grouparray.Add(attRef.TextString)

                        End If

                    End If

                Next

            Next

 

 

Many thanks,

HD

*Expert Elite*
norman.yuan
Posts: 1,045
Registered: ‎04-27-2009
Message 4 of 7 (636 Views)

Re: Getting Constant Attribute using VB.net

03-22-2012 07:24 AM in reply to: hakand

As Stephem has already pointed out, constant attribute is defined in BlockTableRecord (block definition). There is no AttributeReference created in Blockreference if an AttributeDefinition is defined as Constant.

 

You need to understand

 

1. AttributeReference is an entitiy created in BlockReference with AttributeDefinition as TEMPLATE, but does not have to be te same as he AttributeDefinition. In fact, you can add AttributeReference to a BlockReference without AttributeDefition.

 

2. Constant AttributeDefition defined in a BlockTableRecord acts the same as a Text entity in BlockTableRecord. That is, the Attribute will go with all other entities in the block definition into a BlockReference.

 

So, if you need to get value of a constant atribute, the code would like this (assume you seelcteda BlockReferenece' ObjectId, just off my head, not compiled/tested):

 

using (Transaction tran=theDatabase.TransactionManager.StartTransaction())
{
    BlockReference bRef=(BlockReference)tran.GetObject(blkrefId, OpenMode.ForRead);
    BlockTableRecord blk=(BlockTableRecord)tran.GetObject(bRef.BlockTableRecord, OpenMode.ForRead);

    foreach (ObjectId id in blk)
    {
        AttributeDefinition att=tran.GetObject(id,OpenMode.ForRead) As AttributeDefinition;

        if (att!=null)
        {
            if (att.Constant)
            {
                if (att.Tag.ToUpper()=="MY_TARGET_ATT")
                {
                    MessageBox.Show("The value I am looking for is " + att.TextString);
                    att.UpgradeOpen();
                    att.TextString="New Value;
                }
            }
        }
    }

    tran.Commit();
}

//since you changed constant attribute's value in block definition, all
//Blockreferences of this block in the drawing will also change. Do
//a Regen will show the effect
Editor.Regen();

 HTH.

Contributor
hakand
Posts: 14
Registered: ‎03-07-2012
Message 5 of 7 (630 Views)

Re: Getting Constant Attribute using VB.net

03-22-2012 09:40 PM in reply to: hakand

Thank you very much for the reply. That has helped me a lot in gauging a clear understanding.

 

I have implemented your suggestion into my code but there is still an issue.

 

I keep getting this error on creating the Attributedefinition:

 

Unable to cast object of type

'Autodesk.AutoCAD.DatabaseServices.Polyline' to type 'Autodesk.AutoCAD.DatabaseServices.Attributedefinition'

 

This happens to all types of blocks, whether it be polyline, solid3d etc.

 

What type should the object be for it to be changed successfully?

 

Here is my new code below, the 'For Each id As ObjectId In btr' loop has been added in as suggested.

What am I doing wrong here?

 

 

        Dim ed As Editor = Application.DocumentManager.MdiActiveDocument.Editor
        Dim doc As Document = Application.DocumentManager.MdiActiveDocument
        Dim db As Database = HostApplicationServices.WorkingDatabase
        Dim tr As Transaction = db.TransactionManager.StartTransaction()

        Try

            Dim filList As TypedValue() = New TypedValue(0) {New TypedValue(CInt(DxfCode.Start), "INSERT")}

            Dim filter As New SelectionFilter(filList)

            Dim opts As New PromptSelectionOptions()

            opts.MessageForAdding = "Select block references: "

            Dim res As PromptSelectionResult = ed.GetSelection(opts, filter)

            If res.Status <> PromptStatus.OK Then

                Return
            End If

            Dim selSet As SelectionSet = res.Valu
            Dim idArray As ObjectId() = selSet.GetObjectIds()

            For Each blkId As ObjectId In idArray

                Dim obj As DBObject = tr.GetObject(blkId, OpenMode.ForRead)
                 
                Dim blkRef As BlockReference = DirectCast(tr.GetObject(blkId, OpenMode.ForRead), BlockReference)
                Dim btr As BlockTableRecord = DirectCast(tr.GetObject(blkRef.BlockTableRecord, OpenMode.ForRead), BlockTableRecord)


                For Each id As ObjectId In btr

                    Dim ad As AttributeDefinition = DirectCast(tr.GetObject(id, OpenMode.ForRead), AttributeDefinition)

                    If ad IsNot Nothing Then

                        If ad.Constant = False Then

                            If ad.Tag.ToUpper = "CATEGORY" Then

                                grouparray.Add(ad.TextString)

                            End If

                        End If

                    End If
                Next

 

Again .. Many thanks for everyones time, it is much appreciated,

HD

*Expert Elite*
norman.yuan
Posts: 1,045
Registered: ‎04-27-2009
Message 6 of 7 (621 Views)

Re: Getting Constant Attribute using VB.net

03-23-2012 06:44 AM in reply to: hakand

The c# statement

 

[Type] something=...... as [Type]

 

is not the same as DirectCast() in VB, rather it is similar to TryCast(). You cannot DirectCast() whatever in a block definition into an AttributeDefinition, if it is not an AttributeDefinition.

 

So, simple change this line:

 

Dim ad As AttributeDefinition = DirectCast(tr.GetObject(id, OpenMode.ForRead), AttributeDefinition)

To:

 

Dim ad As AttributeDefinition = TryCast(tr.GetObject(id, OpenMode.ForRead), AttributeDefinition)

Contributor
hakand
Posts: 14
Registered: ‎03-07-2012
Message 7 of 7 (608 Views)

Re: Getting Constant Attribute using VB.net

03-25-2012 02:38 PM in reply to: norman.yuan

Thanks Norman, that did the trick!

 

Much appreciated with the time spent helping me with my issue.

Post to the Community

Have questions about Autodesk products? Ask the community.

New Post
Announcements
Are You Going To Be @ AU 2014? Feel free to drop by our AU topic post and share your plans, plug a class that you're teaching, or simply check out who else from the community might be in attendance. Ohh and don't forgot to stop by the Autodesk Help | Learn | Collaborate booths in the Exhibit Hall and meet our community team if you get a chance!