Editing table text programmatically

Editing table text programmatically

Anonymous
Not applicable
3,391 Views
9 Replies
Message 1 of 10

Editing table text programmatically

Anonymous
Not applicable

After editing table text with a custom VB.NET program, once exited from the program, if I want to roll back to the original text using the AutoCAD Undo button, the drawing must be regenerated to have the previous text displayed properly.

 

Following is the sequence of the operations

 

1. Create a table entitled "MyTable"

2. NETLOAD (myprogram)

3. Launch myprogram

4. Myprogram edits table text in order to change table title from "MyTable" to "Components Table"

5. Exit myprogram

6. Press the AutoCAD native Undo button in order to bring back the table title to it's original value (MyTable)

7. The table title still remains "Components Table"

8. To have the table title displayed properly "MyTable" I have to regenerate the drawing with the Regen native AutoCAD function

 

The other objects like single line text for example do not need to regenerate the drawing, simply pressing Undo and the text is rolled back properly.

 

Why the table text need to regenerate the drawing?

 

Thankyou to all

 

Luigi Ballotta

 

 

0 Likes
Accepted solutions (1)
3,392 Views
9 Replies
Replies (9)
Message 2 of 10

augusto.goncalves
Alumni
Alumni
Can you provide more details on your program? Step #3 & #4

What do you mean by "exit myprogram"?
Regards,



Augusto Goncalves
Twitter @augustomaia
Autodesk Developer Network
0 Likes
Message 3 of 10

Anonymous
Not applicable

Hi Augusto, 

 

Step #3

Launch myprogram simply typing a custom command as it could be "mycmd";

 

Step #4

Using acLockCurrDoc As DocumentLock = acDoc.LockDocument()
Using acTrans As Transaction = acCurDb.TransactionManager.StartTransaction()

 

'As texts in tables are MText objects, MyObjectID is the ObjectID of the MText object embedded in a table object

Dim MultiLineText As MText = acTrans.GetObject(MyObjectID, OpenMode.ForWrite, False, True)

 

'Current MultiLineText.Contents is "MyTable" and I wanto to change it in "Components Table" so: 

MultiLineText.Contents = "Components Table"

 

acTrans.Commit()
acDoc.Editor.Regen()

 

End Using

End Using

 

After this, the text of the table is changed to "Components Table" which is correct, but if I want to roll back the edit with the AutoCAD native Undo, I also have to type "_regen", to make sure that the text of the table is restored to his original content (MyTable). Sure the text is already restored to its original content pressing Undo, but the correct content is shown only after typing "_regen".

 

Exit myprogram simply closing the form of MyProgram.

 

thankyou,

 

regards

0 Likes
Message 4 of 10

max.senft
Enthusiast
Enthusiast
Accepted solution

Hi there,

 

I'd rather use the Table Class given by the AutoCAD .NET API. Which means you can access each cell of the table by its index:

 

myTable.Cells(0, 0).Value = "Some String Value"

At least in my small test I just wrote, AutoCAD was able to correctly update the table when using the Undo-Button. PLUS: If I set the Content property of the MText object directly, the table won't auto-adjust if the new value is longer/shorter.

 

You don't have to struggle with all that "graphical representation" of your table if you use the Table class!

 

Regards

Max

Message 5 of 10

Anonymous
Not applicable

thanks for the tip, I'll try this way as soon as I have some time.Smiley Wink

Thankyou

 

Luigi

0 Likes
Message 6 of 10

kgallagherCGHDN
Advocate
Advocate

this is awesome but how do i actually get into the table

 

0 Likes
Message 7 of 10

max.senft
Enthusiast
Enthusiast

Uhm, like any other object. Here's a sample snippet:

 

 

ObjectId selObjId; // This variable must be set via manual user selection, for example

var doc = Application.DocumentManager.MdiActiveDocument;
using (var tr = doc.TransactionManager.StartTransaction())
{
    var selObj = tr.GetObject(selObjId, OpenMode.ForWrite);
    if (selObj is Table)
    {
        var myTable = (Table)selObj;
        myTable.Cells[0, 0].Value = "Table! " + DateTime.Now.ToString();
    }
}

 

  

0 Likes
Message 8 of 10

kgallagherCGHDN
Advocate
Advocate

so this must be a manual select, i need to run against 1200 files

0 Likes
Message 9 of 10

max.senft
Enthusiast
Enthusiast

Hi,

 

I didn't say it has to be a manual selection. Going through the object dictionary programmatically is possible as well, of course.

 

Maybe this helps as a start?

 

var doc = Application.DocumentManager.MdiActiveDocument;
var db = doc.Database;

using (var tr = doc.TransactionManager.StartTransaction())
{
    BlockTable bt = db.BlockTableId.GetObject(OpenMode.ForRead) as BlockTable;
    BlockTableRecord ms = bt[BlockTableRecord.ModelSpace].GetObject(OpenMode.ForWrite) as BlockTableRecord;
                    
    foreach (ObjectId curObj in block)
    {
        Entity curEnt = tr.GetObject(curObj, OpenMode.ForRead) as Entity;
        if (curEnt == null)
        {
            continue;
        }
        
        if (curEnt is Table)
        {
            var tmpTable = (Table)curEnt;
            
            // Do something with the table object
        }
    }
}

 

Max

0 Likes
Message 10 of 10

kgallagherCGHDN
Advocate
Advocate

Thanks i figured it out you were very helpful