.NET

Reply
Active Member
ccalvo12
Posts: 9
Registered: ‎04-19-2012
Message 1 of 6 (275 Views)

updates blocks with attributes of a given Layout

275 Views, 5 Replies
11-02-2012 08:27 AM

Please help at this point, every time I try to update blocks with attributes of a given layout, this only updates the last active layout. example:
I have three layouts: Layout1, Layout2 and Layout3
layout of the three blocks I would need to update the reference but I can Layout1 default that always takes the last active layout.

 

In the following paper space specific code, but as it would to tell a particular layout.

Private Sub UpdateAttributesInDatabase(ByVal db As Database, ByVal blockName As String, ByVal attbName As String, ByVal attbValue As String)

            Dim psId As ObjectId
            Dim tr As Transaction = db.TransactionManager.StartTransaction()
            Using tr

                Dim bt As BlockTable = DirectCast(tr.GetObject(db.BlockTableId, OpenMode.ForRead), BlockTable)
                psId = bt(BlockTableRecord.PaperSpace)
                tr.Commit()
            End Using
            UpdateAttributesInBlock(db, psId, blockName, attbName, attbValue)

        End Sub

 

Mentor
khoa.ho
Posts: 213
Registered: ‎09-15-2011
Message 2 of 6 (256 Views)

Re: updates blocks with attributes of a given Layout

11-02-2012 02:05 PM in reply to: ccalvo12

Hi,

 

You problem is not choosing the correct space to update the block reference with attributes. BlockTableRecord.PaperSpace point to the last active layout, you have to specify the layout that contains this block reference.

The following code will give you a hint to get your psId of given layout name to pass into UpdateAttributesInBlock():

public static ObjectId GetLayoutId(Database db, string layoutName)
{
    using (GetTransaction(db))
    {
        var layoutDict = (DBDictionary)db.LayoutDictionaryId.GetObject(OpenMode.ForRead);
        return layoutDict.GetAt(layoutName);
    }
}

-Khoa

Active Member
ccalvo12
Posts: 9
Registered: ‎04-19-2012
Message 3 of 6 (248 Views)

Re: updates blocks with attributes of a given Layout

11-02-2012 05:39 PM in reply to: khoa.ho

Hello.

The function that I share "GetLayoutId", i returns a "objectids" type Layout.

The function "UpdateAttributesInBlock" receives as a parameter a "objectids" but it is of type "BlockTableRecord". It is here where there is an error at the time of running the application: how to convert a "objectids" type Layout to a "objectids" type "BlockTableRecord".

 

Thanks for the help,

 

Salutations

 

Private Function UpdateAttributesInBlock(ByVal db As Database, ByVal btrId As ObjectId, ByVal blockName As String, ByVal attbName As String, ByVal attbValue As String) As Integer

            ' Will return the number of attributes modified
            Dim changedCount As Integer = 0
            Dim tr As Transaction = db.TransactionManager.StartTransaction()
            Using tr
                Dim btr As BlockTableRecord = DirectCast(tr.GetObject(btrId, OpenMode.ForRead), BlockTableRecord)

                ' Test each entity in the container...
                For Each entId As ObjectId In btr
                    Dim ent As Entity = TryCast(tr.GetObject(btrId, OpenMode.ForRead), Entity)
                    If ent IsNot Nothing Then
                        Dim br As BlockReference = TryCast(ent, BlockReference)
                        If br IsNot Nothing Then
                            Dim bd As BlockTableRecord = DirectCast(tr.GetObject(br.BlockTableRecord, OpenMode.ForRead), BlockTableRecord)

                            ' ... to see whether it's a block with
                            ' the name we're after
                            If bd.Name.ToUpper() = blockName Then
                                ' Check each of the attributes...
                                For Each arId As ObjectId In br.AttributeCollection
                                    Dim obj As DBObject = tr.GetObject(arId, OpenMode.ForRead)
                                    Dim ar As AttributeReference = TryCast(obj, AttributeReference)
                                    If ar IsNot Nothing Then
                                        ' ... to see whether it has

                                        ' the tag we're after

                                        If ar.Tag.ToUpper() = attbName Then
                                            ' If so, update the value
                                            ' and increment the counter
                                            ar.UpgradeOpen()
                                            ar.TextString = attbValue
                                            ar.DowngradeOpen()
                                            changedCount += 1
                                        End If
                                    End If
                                Next
                            End If

                            ' Recurse for nested blocks
                            changedCount += UpdateAttributesInBlock(db, br.BlockTableRecord, blockName, attbName, attbValue)
                        End If
                    End If
                Next
                tr.Commit()
            End Using
            Return changedCount
        End Function

 

Mentor
khoa.ho
Posts: 213
Registered: ‎09-15-2011
Message 4 of 6 (236 Views)

Re: updates blocks with attributes of a given Layout

11-02-2012 10:45 PM in reply to: ccalvo12

Hi,

I forgot to check the layoutId that used as a blockTableRecordId. They are different. One represents an identity of a layout, one represents an identity of a block table record.

A DWG database has one block table that has many block table records which are model space, paper spaces, block definitions and anonymous blocks. The block reference is an instance of a block table record.

A block table record can store many entities. Model space and Paper spaces are special block table records which store all drawing entities. But Model and Paper spaces do not have their derived block references as they are unique. While block definition is not unique, it has many instances in form as block references with different attribute values.

When we create a block definition in AutoCAD, we create a new block table record on database that stores everything to define this block.

So a block table record is an enumerator that has all its objects inside. Then we use a loop to iterate all objects (identified by unique ObjectId) of this block table record.

Therefore when updating attributes of a block reference, we should know which block table record that stores this block reference. If we have a layout, layout.BlockTableRecordId will return an ObjectId of the block table record of this layout.

The following code will return the spaceId (blockTableRecordId) of a given layout name, and you use the return spaceId to pass into your UpdateAttributesInBlock() method. The spaceId will defined which space to work, it can be Model space or any Paper space (with its layout).

public static ObjectId GetSpaceId(Database db, string layoutName)
{
    using (Transaction trans = db.TransactionManager.StartTransaction())
    {
        var layoutDict = (DBDictionary)trans.GetObject(db.LayoutDictionaryId, OpenMode.ForRead);
        ObjectId layoutId = layoutDict.GetAt(layoutName);
        var layout = (Layout)trans.GetObject(layoutId, OpenMode.ForRead);
        return layout.BlockTableRecordId;
    }
}

 -Khoa

Active Member
ccalvo12
Posts: 9
Registered: ‎04-19-2012
Message 5 of 6 (182 Views)

Re: updates blocks with attributes of a given Layout

11-05-2012 09:15 AM in reply to: ccalvo12

Hello,

thank you very much for the clarification, did not understand very well what in the documentation he explained to me about this topic.

The function works correctly.

Thank you very much.

Greetings

Mentor
khoa.ho
Posts: 213
Registered: ‎09-15-2011
Message 6 of 6 (172 Views)

Re: updates blocks with attributes of a given Layout

11-05-2012 10:53 AM in reply to: ccalvo12

Happy to help. Please remember to Accept Solution to help later readers.

 

-Khoa

Announcements
Are you familiar with the Autodesk Expert Elites? The Expert Elite program is made up of customers that help other customers by sharing knowledge and exemplifying an engaging style of collaboration. To learn more, please visit our Expert Elite website.
Need installation help?

Start with some of our most frequented solutions or visit the Installation and Licensing Forum to get help installing your software.