.NET

Reply
Active Contributor
Posts: 38
Registered: ‎03-22-2005
Message 1 of 8 (275 Views)

Insert Block with Attributes Error

275 Views, 7 Replies
11-26-2012 11:08 AM

I have the following code that Inserts a Block with Attributes by using an empty database and

ReadDwgFile. But I seem to be missing something because it has caused memory errors that lead to Exception Errors in Autocad, which then bombs out. Is there something in addition to the db.CloseInput(true) and db.Dispose() that I need to fully release the unseen instance of Autocad?

 

Thanks in advance,

Brian

 

Code:

 

<Autodesk.AutoCAD.Runtime.

CommandMethod("InsertDetailCallOut", CommandFlags.Session)> _

 

PublicSharedSub InsertDetailCallOut(ByVal BlockPath AsString, ByVal thePoint AsPoint3d, ByVal BlockName AsString, ByVal dblscale AsDouble, _

 

ByVal Detail_Number AsInteger, ByVal Detail_Name AsString, ByVal Detail_Qty AsInteger, _

 

ByVal Detail_Material AsString, ByVal Detail_Stock AsString, ByVal Detail_Notes AsString)

 

Dim acDoc As Autodesk.AutoCAD.ApplicationServices.Document = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument

 

Dim fname AsString= BlockPath

 

Dim idBTR AsObjectIdHostApplicationServices.Current.FindFile(fname, acDoc.Database, FindFileHint.Default)

 

Using docloc AsDocumentLock= acDoc.LockDocument

 

TryDim trans AsTransaction= acDoc.TransactionManager.StartTransaction

 

TryDim bt AsBlockTable = CType(trans.GetObject(acDoc.Database.BlockTableId, OpenMode.ForRead), BlockTable)

 

Dim db AsNewDatabase(False, False)

db.ReadDwgFile(fname, System.IO.

FileShare.Read, True, "")

idBTR = acDoc.Database.Insert(BlockName, db,

False)

 

Dim btr AsBlockTableRecord = CType(trans.GetObject(bt(BlockTableRecord.ModelSpace), OpenMode.ForWrite), BlockTableRecord)

 

Dim bref AsBlockReference = NewBlockReference(thePoint, idBTR)

 

Dim theScale AsScale3d = NewScale3d(dblscale, dblscale, dblscale)

bref.ScaleFactors = theScale

bref.Layer =

"StockList"Try

btr.AppendEntity(bref)

trans.TransactionManager.AddNewlyCreatedDBObject(bref,

True)

 

FinallyEndTryDim RefBTR AsBlockTableRecord = trans.GetObject(bref.BlockTableRecord, OpenMode.ForRead)

 

Dim attEnt AsEntityForEach attID AsObjectIdInRefBTR

attEnt = trans.GetObject(attID,

OpenMode.ForRead)

 

IfTypeOf attEnt IsAttributeDefinitionThenDim attDef AsAttributeDefinition= attEnt

 

Dim attRef AsAttributeReference = NewAttributeReference()

attRef.SetAttributeFromBlock(attDef, bref.BlockTransform)

Dim attRefID AsObjectId

attRefID = bref.AttributeCollection.AppendAttribute(attRef)

SelectCaseattDef.Tag

 

Case"DET-NAME"

attRef.TextString = Detail_Name

Case"DET-NO"

attRef.TextString = Trim(Str(Detail_Number))

Case"DET-QTY"

attRef.TextString =

"(" & Trim(Str(Detail_Qty)) & ") - REQ'D. / HEATER"Case"DET-MAT"

attRef.TextString = Detail_Material

Case"DET-STK"

attRef.TextString = Detail_Stock

Case"DET-NOTES"

attRef.TextString = Detail_Notes

EndSelect

trans.AddNewlyCreatedDBObject(attRef,

True)

 

EndIfNext

trans.Commit()

db.CloseInput(

True)

db.Dispose()

FinallyEndTryFinallyEndTry

acDoc.Editor.UpdateScreen()

EndUsingEndSub

Active Contributor
Posts: 38
Registered: ‎03-22-2005
Message 2 of 8 (267 Views)

Re: Insert Block with Attributes Error

11-26-2012 11:42 AM in reply to: brianaubert

In addition I forgot to mention:

 

I use this routine multiple times in the same drawing. It appears that after about 10 calls to it that problems start.

But not always. There are times the program will finish properly. Weird.

Valued Mentor
Posts: 372
Registered: ‎04-11-2010
Message 3 of 8 (250 Views)

Re: Insert Block with Attributes Error

11-26-2012 06:06 PM in reply to: brianaubert

Hi,

 

Try disposing the attref after adding it to the db.

 

Gaston Nunez

 

 

*Expert Elite*
Hallex
Posts: 1,554
Registered: ‎10-08-2008
Message 4 of 8 (236 Views)

Re: Insert Block with Attributes Error

11-27-2012 01:10 AM in reply to: brianaubert

I see nothing wrong with your code

just chaged few lines in there

See how it will works

 

        ' changed on short command "idc"
        <CommandMethod("InsertDetailCallOut", "idc", CommandFlags.Session)> _
        Public Shared Sub testInsertCallout()
            Dim fname As String = "c:\test\myfile.dwg"
            ' check if file exist
            If Not File.Exists(fname) Then
                Exit Sub
            End If
            '' you have also to check if layer "StockList" existbefore
            '---------------------------------------------
            '' you have also to check if block "YourBlockName" exist before
            '---------------------------------------------
            Dim p As Point3d = New Point3d(90.5, 90.1, 0) 'dummy point
            InsertDetailCallOut(fname, p, "YourBlockName", 0.5, 777, "Detail Name =", 100, "Detail Material =", "Detail_Stock= ", "Detail_Notes= ")


        End Sub

        Public Shared Sub InsertDetailCallOut(ByVal BlockPath As String, ByVal thePoint As Point3d, ByVal BlockName As String, ByVal dblscale As Double, _
ByVal Detail_Number As Integer, ByVal Detail_Name As String, ByVal Detail_Qty As Integer, _
ByVal Detail_Material As String, ByVal Detail_Stock As String, ByVal Detail_Notes As String)

            Dim acDoc As Autodesk.AutoCAD.ApplicationServices.Document = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument

            Dim fname As String = BlockPath

            Dim idBTR As ObjectId
 
            Try

                Using docloc As DocumentLock = acDoc.LockDocument

                    Using trans As Transaction = acDoc.TransactionManager.StartTransaction

                        Dim bt As BlockTable = CType(trans.GetObject(acDoc.Database.BlockTableId, OpenMode.ForRead), BlockTable)

                        ' you have before to check if layer "Stocklist" exist

                        Dim db As New Database(False, False)

                        Using db

                            db.ReadDwgFile(fname, System.IO.FileShare.Read, True, "")

                            idBTR = acDoc.Database.Insert(BlockName, db, False)

                            Dim btr As BlockTableRecord = CType(trans.GetObject(bt(BlockTableRecord.ModelSpace), OpenMode.ForWrite), BlockTableRecord)

                            Dim bref As BlockReference = New BlockReference(thePoint, idBTR)

                            Dim theScale As Scale3d = New Scale3d(dblscale, dblscale, dblscale)

                            bref.ScaleFactors = theScale

                            bref.Layer = "StockList"

                            btr.AppendEntity(bref)

                            trans.TransactionManager.AddNewlyCreatedDBObject(bref, True)

                            Dim RefBTR As BlockTableRecord = trans.GetObject(bref.BlockTableRecord, OpenMode.ForRead)

                            Dim attEnt As Entity

                            For Each attID As ObjectId In RefBTR

                                attEnt = trans.GetObject(attID, OpenMode.ForRead)

                                If TypeOf attEnt Is AttributeDefinition Then

                                    Dim attDef As AttributeDefinition = attEnt

                                    Dim attRef As AttributeReference = New AttributeReference()

                                    attRef.SetAttributeFromBlock(attDef, bref.BlockTransform)

                                    Dim attRefID As ObjectId

                                    attRefID = bref.AttributeCollection.AppendAttribute(attRef)

                                    Select Case attDef.Tag()

                                        Case "DET-NAME"

                                            attRef.TextString = Detail_Name

                                        Case "DET-NO"

                                            attRef.TextString = Trim(Str(Detail_Number))

                                        Case "DET-QTY"

                                            attRef.TextString = "(" & Trim(Str(Detail_Qty)) & ") - REQ'D. / HEATER"
                                        Case "DET-MAT"

                                            attRef.TextString = Detail_Material

                                        Case "DET-STK"

                                            attRef.TextString = Detail_Stock

                                        Case "DET-NOTES"

                                            attRef.TextString = Detail_Notes

                                    End Select

                                    attRef.AdjustAlignment(acDoc.Database)

                                    trans.AddNewlyCreatedDBObject(attRef, True)

                                End If

                            Next

                        End Using

                        trans.Commit()

                    End Using

                    acDoc.Editor.UpdateScreen()

                End Using

            Catch ex As System.Exception

                MsgBox(ex.Message)

            Finally

            End Try

        End Sub

 

_____________________________________
C6309D9E0751D165D0934D0621DFF27919
Active Contributor
Posts: 38
Registered: ‎03-22-2005
Message 5 of 8 (218 Views)

Re: Insert Block with Attributes Error

11-27-2012 12:07 PM in reply to: brianaubert

Thank you for both of your replies.

 

I've added attRef.Dispose() as Gasty suggested.

 

I also made the changes suggested by Hallex.

 

I still get the Unhandled exception error.

It's telling me that:

"Attempted to read or write protected memory. This is often an

indication that other memory is corrupt."

 

This application is still in development. So I'm the only one using it.

I have run it about 10 times in a row to complettion of the program with no error.

Then other times it will error half way through.

 

If I bypass the InsertCallOut sub, I have no problems with the program.

 

Any other suggestions?

 

Could this be an Autocad bug?

 

Thanks,

Brian

*Expert Elite*
Hallex
Posts: 1,554
Registered: ‎10-08-2008
Message 6 of 8 (200 Views)

Re: Insert Block with Attributes Error

11-28-2012 08:33 AM in reply to: brianaubert

I did't find this problem with my code

I've added 1000 blocks using my routine

like this

        <CommandMethod("InsertDetailCallOut", "idc", CommandFlags.Session)> _
        Public Shared Sub testInsertCallout()
            Dim fname As String = "c:\test\myfile.dwg"
            ' check if file exist
            If Not File.Exists(fname) Then
                Exit Sub
            End If
            '' you have also to check if layer "StockList" existbefore
            '---------------------------------------------
            '' you have also to check if block "YourBlockName" exist before
            '---------------------------------------------
            Dim p As Point3d = Point3d.Origin 'dummy point
            ' add 1000 block for quick test
            For i As Integer = 0 To 999
                InsertDetailCallOut(fname, New Point3d(p.X + (i + 1) * 10, p.Y + (i + 1) * 10, 0), "YourBlockName", 0.5, 777, "Detail Name =", 100, "Detail Material =", "Detail_Stock= ", "Detail_Notes= ")
            Next
            ' time expired about 1.3 minutes on my machine
        End Sub

 

_____________________________________
C6309D9E0751D165D0934D0621DFF27919
Active Contributor
Posts: 38
Registered: ‎03-22-2005
Message 7 of 8 (190 Views)

Re: Insert Block with Attributes Error

11-28-2012 11:39 AM in reply to: brianaubert
        HostApplicationServices.Current.FindFile(fname, acDoc.Database, FindFileHint.Default)
        Try
          Using docloc As DocumentLock = acDoc.LockDocument
            Using trans As Transaction = acDoc.TransactionManager.StartTransaction
              Dim bt As BlockTable = CType(trans.GetObject(acDoc.Database.BlockTableId, OpenMode.ForRead), BlockTable)
              Dim db As New Database(False, False)
              Using db
                db.ReadDwgFile(fname, System.IO.FileShare.Read, True, "")


                idBTR = acDoc.Database.Insert(BlockName & ".dwg", db, False)
	<< Fails on the line Above >>

                Dim btr As BlockTableRecord = CType(trans.GetObject(bt(BlockTableRecord.ModelSpace), OpenMode.ForWrite), BlockTableRecord)
                Dim bref As BlockReference = New BlockReference(thePoint, idBTR)
                Dim theScale As Scale3d = New Scale3d(dblscale, dblscale, dblscale)

 Update to the problem.

 

I've changed my code to build an array of data for the placement and information for the detail call outs.

Then after all the details have been drawn I run through the array list to insert the details call outs.

 

There are 14 items in the array and it fails on the second pass each time, at the line above.

 

Any thoughts?

 

Brian

 

 

 

 

 

 

 

   

Active Contributor
Posts: 38
Registered: ‎03-22-2005
Message 8 of 8 (184 Views)

Re: Insert Block with Attributes Error

11-28-2012 12:44 PM in reply to: brianaubert

Ok, after further testing, I now believe the problem is an error in my code in another routine.

 

I think I might be going past the bounds of a collection which is causing this problem.

:smileyembarrassed:

 

I'll update after more debugging.

Brian

You are not logged in.

Log into access your profile, ask and answer questions, share ideas and more. Haven't signed up yet? Register

Announcements
Welcome to the new Autodesk Community!
If this is your first visit, click here to get started and make the most of the Community. Let us know what you think of the new experience in the Community Feedback Forum.

Need installation help?

Start with some of our most frequented solutions to get help installing your software.

Ask the Community