Table not updating information

Table not updating information

Anonymous
Not applicable
1,384 Views
7 Replies
Message 1 of 8

Table not updating information

Anonymous
Not applicable

Hey all,

 

I have been playing with tables in AutoCAD lately and have had mixed results. I can create a table from scratch using code and edit the table. However editing an existing table is a different story. The table will not update at the end with the new information or formatting. The code i have is as follows:

 

Dim doc As Document = Application.DocumentManager.MdiActiveDocument
        Dim db As Database = doc.Database
        Dim ed As Editor = doc.Editor

        Try
            Dim selectionres As PromptSelectionResult
            selectionres = ed.SelectImplied
            If (selectionres.Status = PromptStatus.Error) Then
                Dim selectionopt As PromptSelectionOptions
                selectionopt = New PromptSelectionOptions
                selectionopt.MessageForAdding = vbCr + "Select Table to Edit "
                selectionres = ed.GetSelection(selectionopt)
            Else
            End If

            If selectionres.Status = PromptStatus.OK Then
                Dim tr As Transaction = doc.TransactionManager.StartTransaction()

                Using tr
                    Dim ids As New ObjectIdCollection(selectionres.Value.GetObjectIds)
                    
                    Dim bt As BlockTable = tr.GetObject(doc.Database.BlockTableId, OpenMode.ForRead)
                    Dim btr As BlockTableRecord = tr.GetObject(bt(BlockTableRecord.ModelSpace), OpenMode.ForWrite)

                    For Each id As Object In ids
                        Dim tb As Table = id.GetObject(OpenMode.ForWrite)

                        Dim numrows As Integer
                        Dim numcol As Integer

                        numrows = tb.Rows.Count
                        numcol = tb.Columns.Count

                        ed.WriteMessage("table name: " + tb.Name.ToString + " Num Columns: " + numcol.ToString + " Num Rows: " + numrows.ToString)

                        ' Use a nested loop to add and format each cell

                        For i As Integer = 1 To numrows

                            For j As Integer = 1 To numcol

                                If tb.Cells(i, 1).Value = "1/1" Then

                                    'tb.Cells(i, j).Borders.Bottom.IsVisible = False
                                    tb.Rows(i).Borders.Top.IsVisible = False
                                ElseIf tb.Cells(i, 1).Value = "1/2" Then

                                    tb.Cells(i, 1).TextString = "new"

                                Else
                                End If

                                tb.Cells(i, j).Alignment = CellAlignment.MiddleLeft

                            Next
                        Next

                        tb.GenerateLayout()

                        btr.AppendEntity(tb)

                        'tr.AddNewlyCreatedDBObject(tb, True)

                        tr.Commit()

                    Next

                End Using
            End If

        Catch ex As Exception

        End Try

 

The code seems pretty basic and hence i can't figure out what i'm missing. The plan is to get the table edit to work, then add more to the code that will edit the existing table.

 

any push in the right direction would be appreciated.

0 Likes
1,385 Views
7 Replies
Replies (7)
Message 2 of 8

Paulio
Advocate
Advocate

You're committing your transaction inside your for/next loop so when it does the loop the second time the transaction will no longer be any good and it'll error to your catch. As the catch is empty it'll just end without showing any error.

 

Try moving your commit to outside the for/next and see if that makes any difference.

0 Likes
Message 3 of 8

Anonymous
Not applicable

I have not noticed the commit inside the for/next loop, however after moving the tr.commit out of the loop it did not fix the problem. I also added some code to catch the exception and when I did the following was shown in the AutoCAD command line after running the application:

 

eAlreadyInDb
   at Autodesk.AutoCAD.DatabaseServices.BlockTableRecord.AppendEntity(Entity
entity)

 

I'm guessing by the code above that the entity already exists, but that is kind of the point of the exercise I would have thought.

 

Any thoughts?

0 Likes
Message 4 of 8

Paulio
Advocate
Advocate

Sorry. Didn't notice that. You don't need to 'appendentity' or do the 'trans.AddNewlyCreatedDbObject' because you're modifying an existing entity. You only need to do that if you're creating a new object (hence the term 'AddNewlyCreatedDbObject'). Just committing the transaction after modifying it will save the changes.

 

BTW, it's probably better to get the object using the transaction rather than getting it using the GetObject method of the ObjectID.

i.e.

tb = trans.GetObject(id, OpenMode.ForWrite)

 rather than

tb = id.GetObject(OpenMode.ForWrite)

I think I'm right in saying (and hopefully someone will correct me if not) but if you open objects the way you're doing,  then you are responsible for also closing them, which if you don't, could mean you leave objects in open for write status and give you more grief. Using the transaction will handle all that for you.

0 Likes
Message 5 of 8

Anonymous
Not applicable

@Paulio wrote:

 

BTW, it's probably better to get the object using the transaction rather than getting it using the GetObject method of the ObjectID.

i.e.

tb = trans.GetObject(id, OpenMode.ForWrite)

 rather than

tb = id.GetObject(OpenMode.ForWrite)

I think I'm right in saying (and hopefully someone will correct me if not) but if you open objects the way you're doing,  then you are responsible for also closing them, which if you don't, could mean you leave objects in open for write status and give you more grief. Using the transaction will handle all that for you.


 

 

ObjectId.GetObject() uses the top Transaction, so there's no problem there.

 

IOW, these are equiavalent:

 

   TransactionManager.TopTransaction.GetObject( id....)

 

   id.GetObject(...)

  

ObjectId.Open() is the method that opens DBObjects directly without using transactions,

and is where you must call Dispose() on the DBObject, or AutoCAD crashes.

It's actually a bit easier to use id.GetObject() since you don't have to lug around

a Transaction to every place in your code where you open objects. I use it almost

exclusively now, rather than using the Transaction's GetObject(), and find it helps

to simplify a lot of code.

 

0 Likes
Message 6 of 8

Paulio
Advocate
Advocate

So if I've understood correctly:

 

If I have a sub that starts a transaction then call a function passing an objectid I can use the .GetObject on the ID and that effectively uses the transaction in the calling sub. (?)

 

Sorry. Just noticed you said 'without transactions'. Does that mean I only need a transaction if I want to save any changes?

0 Likes
Message 7 of 8

Anonymous
Not applicable

ObjectId.GetObject() always uses the Top transaction, and throws

an exception if there are no active transaction.

 

The 'top' transaction is the one that was most recently started,

regardless of what code started it.

 

The only way to open objects is directly via ObjectId.Open(), or via

a Transaction. You can use either but should always use transactions

unless there is a good reason to avoid them (there are a few, obscure

reasons, like for example, using transactions at certain times disables

the user's ability to REDO an UNDO).

 

 

0 Likes
Message 8 of 8

Paulio
Advocate
Advocate

Thanks Tony, that's useful info.

0 Likes