Author Topic: Update attribute value  (Read 2350 times)

0 Members and 1 Guest are viewing this topic.

krkec

  • Guest
Update attribute value
« on: March 21, 2012, 03:28:33 AM »
I am trying to insert block  and update attribute value.
 I catch error witch is: "Object reference not set  to en instance of object."
Problem is with this part of code:
Code: [Select]
Using myTrans2 As Transaction = myBlockID.Database.TransactionManager.StartTransaction
                                Dim myBRef As BlockReference = CType(myBlockID.GetObject(OpenMode.ForRead), BlockReference)
                                Dim myAttCollection As AttributeCollection = myBRef.AttributeCollection
                                For Each myAttRefID As ObjectId In myAttCollection
                                    Dim myAttRef As AttributeReference = CType(myAttRefID.GetObject(OpenMode.ForWrite), AttributeReference)
                                    If myAttRef.Tag.Equals("vis", StringComparison.OrdinalIgnoreCase) = _
                    True Then
                                        myAttRef.TextString = iznos
                                        Exit For
                                    End If
                                Next
                                myTrans2.Commit()
                            End Using

What am I doing wrong???

mgreven

  • Guest
Re: Update attribute value
« Reply #1 on: March 21, 2012, 04:35:55 AM »
It has to do with the Ctype i think.

Here is a working sample to change a attribute value:

 Sub UpdateAttributeValue(ByVal BlockID As ObjectId, ByVal AttributeTag As String, ByVal AttributeValue As String)
   Using myTrans As Transaction = BlockID.Database.TransactionManager.StartTransaction
     Dim myBRef As BlockReference = BlockID.GetObject(OpenMode.ForRead)
     Dim myAttCollection As AttributeCollection = myBRef.AttributeCollection
     For Each myAttRefID As ObjectId In myAttCollection
       Dim myAttRef As AttributeReference = myAttRefID.GetObject(OpenMode.ForWrite)
       If myAttRef.Tag.Equals(AttributeTag, StringComparison.OrdinalIgnoreCase) = True Then
         myAttRef.TextString = AttributeValue
         Exit For
       End If
     Next
     myTrans.Commit()
   End Using
 End Sub



krkec

  • Guest
Re: Update attribute value
« Reply #2 on: March 21, 2012, 04:52:45 AM »
I am still getting same error.

Here is my whole code:

Code: [Select]
Imports Autodesk.AutoCAD.Runtime
Imports Autodesk.AutoCAD
Imports Autodesk.AutoCAD.DatabaseServices
Imports Autodesk.AutoCAD.EditorInput
Imports Autodesk.AutoCAD.Geometry
Imports Autodesk.AutoCAD.ApplicationServices
Imports Autodesk.AutoCAD.ApplicationServices.Application
Imports Autodesk.AutoCAD.LayerManager
Imports Autodesk.AutoCAD.Windows
Imports System.Windows.Forms





Public Class Visko

    Private ishodiste As New Point3d
    Private fkote As Double
    Private ftext As Double
    Private kota As String
    Dim WithEvents myKPSO As New PromptSelectionOptions
    Dim skote As Double
    Dim frez As Double

    Function AddToModelSpace(ByVal DBIn As Database, ByVal EntityIn As Entity) _
As ObjectId
        Using myTrans As Transaction = DBIn.TransactionManager.StartTransaction
            Dim myBT As BlockTable = CType(DBIn.BlockTableId.GetObject(OpenMode.ForRead), BlockTable)
            'Dim myModelSpace As BlockTableRecord = myBT(BlockTableRecord.ModelSpace).GetObject(OpenMode.ForWrite)
            'myModelSpace.AppendEntity(EntityIn)
            Dim myBTR As BlockTableRecord = _
CType(myBT.Database.CurrentSpaceId.GetObject(OpenMode.ForWrite), BlockTableRecord)
            myBTR.AppendEntity(EntityIn)
            myTrans.AddNewlyCreatedDBObject(EntityIn, True)
            myTrans.Commit()
            Return EntityIn.ObjectId
        End Using
    End Function




    Public Function AddEntity(ByVal DatabaseIn As Database, _
ByVal EntityToAdd As Entity, ByVal BlockName As String) As ObjectId
        Using myTrans As Transaction = DatabaseIn.TransactionManager.StartTransaction
            Dim myBlockTable As BlockTable = _
CType(DatabaseIn.BlockTableId.GetObject(OpenMode.ForWrite), BlockTable)
            Dim myBlockTableRecord As BlockTableRecord = Nothing
            If myBlockTable.Has(BlockName) = True Then
                myBlockTableRecord = CType(myBlockTable(BlockName).GetObject(OpenMode.ForWrite), BlockTableRecord)
            Else
                myBlockTableRecord = New BlockTableRecord()
                myBlockTableRecord.Name = BlockName
                myBlockTable.Add(myBlockTableRecord)
                myTrans.AddNewlyCreatedDBObject(myBlockTableRecord, True)
            End If
            myBlockTableRecord.AppendEntity(EntityToAdd)
            myTrans.AddNewlyCreatedDBObject(EntityToAdd, True)
            myTrans.Commit()
            Return EntityToAdd.Id
        End Using
    End Function


    Public Function AddEntities(ByVal DatabaseIn As Database, _
ByVal EntitiesToAdd As DBObjectCollection, ByVal BlockName As String) _
As ObjectIdCollection
        Dim retIDColl As New ObjectIdCollection
        Using myTrans As Transaction = DatabaseIn.TransactionManager.StartTransaction
            Dim myBlockTable As BlockTable = _
CType(DatabaseIn.BlockTableId.GetObject(OpenMode.ForWrite), BlockTable)
            Dim myBlockTableRecord As BlockTableRecord = Nothing
            If myBlockTable.Has(BlockName) = True Then
                myBlockTableRecord = CType(myBlockTable(BlockName).GetObject(OpenMode.ForWrite), BlockTableRecord)
            Else
                myBlockTableRecord = New BlockTableRecord()
                myBlockTableRecord.Name = BlockName
                myBlockTable.Add(myBlockTableRecord)
                myTrans.AddNewlyCreatedDBObject(myBlockTableRecord, True)
            End If
            For Each myDBObject As DBObject In EntitiesToAdd
                myBlockTableRecord.AppendEntity(CType(myDBObject, Entity))
                myTrans.AddNewlyCreatedDBObject(myDBObject, True)
                retIDColl.Add(myDBObject.Id)
            Next
            myTrans.Commit()
            Return retIDColl
        End Using
    End Function

    Public Function BlockExists(ByRef oDb As Database, _
                                    ByRef oTrans As Transaction, _
                                    ByVal strName As String) As Boolean
        ' Create a layer object
        Dim oBlock As BlockTableRecord
        ' Set our return value to nothing
        Dim retValue0 As Boolean = True
        Try
            ' Open up the layer table (for reading)
            Dim oBlockTable As BlockTable = CType(oTrans.GetObject(oDb.BlockTableId, _
                                                                  OpenMode.ForRead, _
                                                                 False),  _
                                      BlockTable)
            ' Loop through each object in the layer table
            For Each objId As ObjectId In oBlockTable
                ' Get the layertablerecord object for the current id
                oBlock = CType(oTrans.GetObject(objId, _
                                                OpenMode.ForWrite),  _
                              BlockTableRecord)
                ' Compare the layer name to the strName variable and
                ' make sure we're not checking erased layers
                If oBlock.Name.ToUpper.Equals(strName.ToUpper) And _
                       Not oBlock.IsErased Then
                    ' Found the layer
                    retValue0 = False
                    Exit For
                End If
            Next
        Catch ex As System.Exception
            MsgBox(ex.Message, MsgBoxStyle.Exclamation, "Error in LayerExists")
        End Try
        Return retValue0
    End Function


    Public Function InsertBlock(ByVal DatabaseIn As Database, _
ByVal BTRToAddTo As String, _
ByVal InsPt As Geometry.Point3d, _
ByVal BlockName As String, _
ByVal XScale As Double, _
ByVal YScale As Double, _
ByVal ZScale As Double) As DatabaseServices.ObjectId
        Using myTrans As Transaction = DatabaseIn.TransactionManager.StartTransaction
            Dim myBlockTable As BlockTable = _
CType(DatabaseIn.BlockTableId.GetObject(OpenMode.ForRead), BlockTable)
            'If the suppplied Block Name is not
            'in the specified Database, get out gracefully.
            If myBlockTable.Has(BlockName) = False Then
                Return Nothing
            End If
            'If the specified BlockTableRecord does not exist,
            'get out gracefully
            If myBlockTable.Has(BTRToAddTo) = False Then
                Return Nothing
            End If
            Dim myBlockDef As BlockTableRecord = _
CType(myBlockTable(BlockName).GetObject(OpenMode.ForRead), BlockTableRecord)
            Dim myBlockTableRecord As BlockTableRecord = _
CType(myBlockTable(BTRToAddTo).GetObject(OpenMode.ForWrite), BlockTableRecord)
            'Create a new BlockReference
            Dim myBlockRef As New BlockReference(InsPt, myBlockDef.Id)
            'Set the scale factors
            myBlockRef.ScaleFactors = New Geometry.Scale3d(XScale, YScale, ZScale)
            'Add the new BlockReference to the specified BlockTableRecord
            myBlockTableRecord.AppendEntity(myBlockRef)
            'Add the BlockReference to the BlockTableRecord.
            myTrans.AddNewlyCreatedDBObject(myBlockRef, True)
            Dim myAttColl As DatabaseServices.AttributeCollection = _
myBlockRef.AttributeCollection
            'Find Attributes and add them to the AttributeCollection
            'of the BlockReference
            For Each myEntID As ObjectId In myBlockDef
                Dim myEnt As Entity = CType(myEntID.GetObject(OpenMode.ForRead), Entity)
                If TypeOf myEnt Is DatabaseServices.AttributeDefinition Then
                    Dim myAttDef As DatabaseServices.AttributeDefinition = CType(myEnt, AttributeDefinition)
                    Dim myAttRef As New DatabaseServices.AttributeReference
                    myAttRef.SetAttributeFromBlock(myAttDef, myBlockRef.BlockTransform)
                    myAttColl.AppendAttribute(myAttRef)
                    myTrans.AddNewlyCreatedDBObject(myAttRef, True)
                End If
            Next
            myTrans.Commit()
            Return myBlockRef.Id
        End Using
    End Function


    Private Sub Form2_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        ComboBox1.SelectedItem = 1
        TextBox1.Text = CStr(1)
        TextBox2.Text = CStr(1)
        kota = "viskograd"

    End Sub



    Private Sub TextBox1_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TextBox1.TextChanged
        fkote = CDbl(TextBox1.Text)
    End Sub

    Private Sub TextBox2_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TextBox2.TextChanged
        ftext = CDbl(TextBox2.Text)
    End Sub

    Private Sub ComboBox1_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ComboBox1.SelectedIndexChanged
        If ComboBox1.SelectedIndex = 0 Then
            ' PictureBox1.Image = grad.gif
            kota = "viskograd"
        ElseIf ComboBox1.SelectedIndex = 1 Then
            ' PictureBox1.Image = arh.gif
            kota = "viskoarh"
        Else
            ' PictureBox1.Image = grad.gif
            kota = "viskograd"
        End If


    End Sub

    Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
        Try
            'stvaranje bloka
            Dim myEd As Editor = DocumentManager.MdiActiveDocument.Editor
            Dim acDoc As Document = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument
            Using myDB1 As Database = HostApplicationServices.WorkingDatabase
                Using myTrans As Transaction = myDB1.TransactionManager.StartTransaction
                    Dim pt1 As New Point3d(3.5, 3.5, 0)
                    Dim pt2 As New Point3d(-3.5, 3.5, 0)
                    Dim pt3 As New Point3d(0, 3.5, 0)
                    Dim pt4 As New Point3d(0, 7, 0)
                    Dim pt5 As New Point3d(10, 3.5, 0)

                    If BlockExists(myDB1, myTrans, "viskograd") Then
                        Dim myDBObjects1 As New DBObjectCollection
                        myEd.WriteMessage(vbLf & "istinito")
                        myDBObjects1.Add(New Line(Point3d.Origin, pt1))
                        myDBObjects1.Add(New Line(Point3d.Origin, pt2))
                        myDBObjects1.Add(New Line(pt1, pt2))
                        Dim myAttDef As New AttributeDefinition(pt3, _
                "%%c00,0", "Vis", "vis", Nothing)
                        myAttDef.Height = 3
                        myAttDef.Justify = AttachmentPoint.BottomCenter
                        myAttDef.AlignmentPoint = pt3
                        myDBObjects1.Add(myAttDef)

                        AddEntities(HostApplicationServices.WorkingDatabase, _
                myDBObjects1, "viskograd")
                    End If
                    If BlockExists(myDB1, myTrans, "viskoarh") Then
                        myEd.WriteMessage(vbLf & "istinito")
                        Dim myDBObjects As New DBObjectCollection
                        myDBObjects.Add(New Line(Point3d.Origin, pt4))
                        myDBObjects.Add(New Line(Point3d.Origin, pt2))
                        myDBObjects.Add(New Line(pt5, pt2))
                        Dim myAttDef1 As New AttributeDefinition(pt3, _
                "%%c00,0", "Vis", "vis", Nothing)
                        myAttDef1.Height = 3
                        myAttDef1.Justify = AttachmentPoint.BottomLeft
                        myAttDef1.AlignmentPoint = pt3
                        myDBObjects.Add(myAttDef1)
                        AddEntities(HostApplicationServices.WorkingDatabase, _
                myDBObjects, "viskoarh")
                    End If
                End Using

                'stvaranje bloka

                Dim myPPR As PromptPointResult
                myPPR = myEd.GetPoint("Odaberi ishodište:")
                Dim t0 As Point3d = myPPR.Value
                Dim kontrol As Integer

                While kontrol <> 1
                    Dim pKeyOpts As PromptKeywordOptions = New PromptKeywordOptions("")
                    pKeyOpts.Message = vbLf & "Enter an option "
                    pKeyOpts.Keywords.Add("Leader")
                    pKeyOpts.Keywords.Add("Izlaz")
                    pKeyOpts.Keywords.Add("Ucrtaj")
                    pKeyOpts.AllowNone = True
                    Dim pKeyRes As PromptResult = acDoc.Editor.GetKeywords(pKeyOpts)
                    ' Autodesk.AutoCAD.ApplicationServices.Application.ShowAlertDialog("Entered keyword: " & _
                    '                  pKeyRes.StringResult)
                    Dim rezultat As String = pKeyRes.StringResult
                    Select Case rezultat
                        Case "Leader"
                            Dim myPPR1 As PromptPointResult
                            Dim myPPR2 As PromptPointResult
                            Dim t1 As New Point3d
                            Dim t2 As New Point3d
                            myPPR1 = myEd.GetPoint("Odaberi točku:")
                            t1 = myPPR1.Value
                            myPPR2 = myEd.GetPoint("Odaberi točku insertiranja:")
                            t2 = myPPR2.Value

                            If t1.X < t2.X Then
                                Dim t3 As New Point3d(t2.X - 3.5 * skote, t2.Y, t2.Z)
                                Dim myLine As New Line(t1, t3)
                            Else
                                Dim t4 As New Point3d(t2.X + 3.5 * skote, t2.Y, t2.Z)
                                Dim myLine As New Line(t1, t4)
                            End If

                            Dim myBlockID As ObjectId = InsertBlock( _
        HostApplicationServices.WorkingDatabase, _
        BlockTableRecord.ModelSpace, _
        t2, _
        kota, _
        1, 1, 1)
                            Dim iznos As String
                            If t1.Y - t0.Y = 0 Then
                                iznos = "%%p 0.00"
                            Else

                                iznos = CStr((Math.Round(t1.Y - t0.Y, 2))).ToString
                                myEd.WriteMessage(vbLf & iznos)
                            End If
                            'UpdateAttributeValue(myBlockID, "vis", iznos)

                            Using myTrans As Transaction = myBlockID.Database.TransactionManager.StartTransaction
                                Dim myBRef As BlockReference = myBlockID.GetObject(OpenMode.ForRead)
                                Dim myAttCollection As AttributeCollection = myBRef.AttributeCollection
                                For Each myAttRefID As ObjectId In myAttCollection
                                    Dim myAttRef As AttributeReference = myAttRefID.GetObject(OpenMode.ForWrite)
                                    If myAttRef.Tag.Equals("vis", StringComparison.OrdinalIgnoreCase) = _
                    True Then
                                        myAttRef.TextString = iznos
                                        Exit For
                                    End If
                                Next
                                myTrans.Commit()
                            End Using






                        Case "Izlaz"
                            kontrol = 1
                        Case "Ucrtaj"
                            Dim myPPR1 As PromptPointResult

                            myPPR1 = myEd.GetPoint("Odaberi točku:")
                            Dim t1 As Point3d = myPPR1.Value
                            Dim myBlockID As ObjectId = InsertBlock( _
        HostApplicationServices.WorkingDatabase, _
        BlockTableRecord.ModelSpace, _
        t1, _
        kota, _
        1, 1, 1)
                            Dim iznos As String
                            If t1.Y - t0.Y = 0 Then
                                iznos = "%%p 0.00"
                            Else
                                iznos = CStr((Math.Round(t1.Y - t0.Y, 2))).ToString
                                myEd.WriteMessage(vbLf & iznos)
                            End If
                            'UpdateAttributeValue(myBlockID, "vis", iznos)

                            Using myTrans As Transaction = myBlockID.Database.TransactionManager.StartTransaction
                                Dim myBRef As BlockReference = myBlockID.GetObject(OpenMode.ForRead)
                                Dim myAttCollection As AttributeCollection = myBRef.AttributeCollection
                                For Each myAttRefID As ObjectId In myAttCollection
                                    Dim myAttRef As AttributeReference = myAttRefID.GetObject(OpenMode.ForWrite)
                                    If myAttRef.Tag.Equals("vis", StringComparison.OrdinalIgnoreCase) = _
                    True Then
                                        myAttRef.TextString = iznos
                                        Exit For
                                    End If
                                Next
                                myTrans.Commit()
                            End Using
                    End Select

                End While
            End Using
        Catch ex As System.Exception
            ' MsgBox("Greska se pojavila" & vbCr & ex.Message & ex.InnerException.ToString & ex.Source)
            MsgBox("Greska se pojavila" & vbCr & ex.Message)
        Finally
        End Try
    End Sub
End Class

mgreven

  • Guest
Re: Update attribute value
« Reply #3 on: March 21, 2012, 05:18:00 AM »
The problem in my opinion is that u use:

Dim myBRef As BlockReference = CType(myBlockID.GetObject(OpenMode.ForRead), BlockReference)


Where the sample uses:
Dim myBRef As BlockReference = BlockID.GetObject(OpenMode.ForRead)


The CType does not belong there.
                                             

kaefer

  • Guest
Re: Update attribute value
« Reply #4 on: March 21, 2012, 06:24:27 AM »
Code - Visual Basic: [Select]
  1. Dim myBRef As BlockReference = CType(myBlockID.GetObject(OpenMode.ForRead), BlockReference)
  2. Dim myBRef As BlockReference = BlockID.GetObject(OpenMode.ForRead)
The CType does not belong there.

Sorry, all your CType do belong here. Try a strongly typed language (e.g. C#) for a change, or simulate the experience with:

Code - Visual Basic: [Select]
  1. Option Strict On
  2. Option Explicit On

Edit: Even better would have been DirectCast.
« Last Edit: March 21, 2012, 07:22:45 AM by kaefer »