TheSwamp
Code Red => .NET => Topic started by: Joel Roderick on March 14, 2006, 06:35:15 PM
-
Haven't posted here in a while, and I am new to .net...
I am trying to add a row to an existing table. I am trying to not use the com interop (my crutch).
I am not sure if I am using transactions properly because I keep crashing AutoCAD when I try to open the object for write. If I open the object for read, it doesn't crash. Any help is much appreciated...
Here is what I have so far:
Dim editor As Editor = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Editor
Dim pOptions As PromptEntityOptions = New PromptEntityOptions("Select a table: ")
Dim pResults As PromptEntityResult = editor.GetEntity(pOptions)
Dim tbl As Table
Dim trans As Transaction
trans = HostApplicationServices.WorkingDatabase().TransactionManager.StartTransaction()
tbl = trans.GetObject(pResults.ObjectId, OpenMode.ForWrite) '<---- ****crashes here****
tbl.InsertRows(1, 1.0, 1)
trans.Commit()
trans.Dispose()
-
It may be a casting thing, do you cast in vb?(maybe pResults.ObjectId as Table or similar??)
IOW, it's trying to turn an Object into a Table without seeing if it fits.
This is only a guess and maybe something to work with 'till someone has a better idea.
hth.
-
or possibly something like
Table tbl = (Table)trans.GetObject(pResults.ObjectId, OpenMode.ForWrite);
aside;
Great to see you here Joel. We are still in our infancy as a group, and possibly won't be able to solve all issues.
Hope you Enjoy the site.
-
In addition, you may need to lock the document depending on your command type flags or the mode your command runs in (like modelss or inside events).
The document must always be locked before modification of entities.
-
Thanks Draftek!
Looks like locking the document worked. Now that I am passed that hurdle, let's see what other damage I can do!
Here is the updated code:
Dim editor As Editor = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Editor
Dim pOptions As PromptEntityOptions = New PromptEntityOptions("Select a table: ")
Dim pResults As PromptEntityResult = editor.GetEntity(pOptions)
Dim tbl As Table
Dim trans As Transaction
trans = HostApplicationServices.WorkingDatabase().TransactionManager.StartTransaction()
editor.Document.LockDocument()
tbl = trans.GetObject(pResults.ObjectId, OpenMode.ForWrite)
tbl.InsertRows(1, 1.0, 1)
trans.Commit()
trans.Dispose()
-
Nothing related, but maybe useful and not mine [no net yet]
<CommandMethod("MyTable")> _
Public Shared Sub MyTableCmd()
Dim mTable As Table
Dim rowt As RowType
Dim bt As BlockTable
Dim btr As BlockTableRecord
Try
Dim db As Database = HostApplicationServices.WorkingDatabase
Dim objId As ObjectId = db.BlockTableId
bt = objId.Open(OpenMode.ForRead)
objId = bt.Item(btr.ModelSpace)
btr = objId.Open(OpenMode.ForWrite)
mTable = New Table()
btr.AppendEntity(mTable)
btr.Close()
bt.Close()
mTable.InsertColumns(0, 12, 1)
mTable.InsertColumns(1, 40, 1)
mTable.InsertColumns(2, 40, 1)
mTable.InsertColumns(3, 40, 1)
mTable.InsertColumns(4, 16, 1)
mTable.InsertColumns(5, 30, 1)
mTable.InsertRows(0, 8, 10)
mTable.SetTextHeight(3, rowt.DataRow)
mTable.SetTextString(0, 0, "TEST")
mTable.SetTextString(0, 1, "TEST")
mTable.SetTextString(0, 2, "TEST")
mTable.SetTextString(0, 3, "TEST")
mTable.SetTextString(0, 4, "TEST")
mTable.SetTextString(0, 5, "TEST")
mTable.SetTextString(1, 0, "TEST")
mTable.SetTextString(1, 1, "TEST")
mTable.SetTextString(1, 2, "TEST")
mTable.SetTextString(1, 3, "TEST")
mTable.SetTextString(1, 4, "TEST")
mTable.Position = New Point3d(180, 80, 0)
mTable.Close()
Catch
Finally
End Try
End Sub
-
Joel, This works for me ..
public class Class1
{
public void
TableTest()
{
Database db = HostApplicationServices.WorkingDatabase;
Editor ed = AcadApp.DocumentManager.MdiActiveDocument.Editor;
// restrict selection to Table only
PromptEntityOptions entOpt = new PromptEntityOptions("\nSelect Table: ");
entOpt.SetRejectMessage("\nOnly Tables may be selected.");
entOpt.AddAllowedClass(typeof(Table), true);
//Start the selection ...
PromptEntityResult entRes = ed.GetEntity(entOpt);
//If a Table was successfully selected, proceed
if (entRes.Status != PromptStatus.OK) {
return;
}
try {
using (Transaction trans = db.TransactionManager.StartTransaction()) {
Table tbl = (Table)trans.GetObject(entRes.ObjectId, OpenMode.ForWrite, true);
tbl.InsertRows(1, 1.0, 1);
trans.Commit();
ed.WriteMessage("\nPosition : " + tbl.Position.ToString());
ed.WriteMessage("\nNumber of Columns : " + tbl.NumColumns.ToString());
ed.WriteMessage("\nNumber of Rows : " + tbl.NumRows.ToString());
ed.WriteMessage("\nWidth : " + tbl.Width.ToString());
ed.WriteMessage("\nHeight : " + tbl.Height.ToString());
}
} catch (Autodesk.AutoCAD.Runtime.Exception acEx) {
ed.WriteMessage("\nError: " + acEx.Message);
return;
}
}
}
Command: Test0316
Select Table:
Nothing Selected.
Select Table:
Only Tables may be selected.
Select Table:
Position : (1107.35495576984,2.99726696006678,0)
Number of Columns : 5
Number of Rows : 9
Width : 317.5
Height : 83
-
Just a note :
If I try this ;
Table tbl = trans.GetObject(entRes.ObjectId, OpenMode.ForWrite, true);
instead of this ;
Table tbl = (Table)trans.GetObject(entRes.ObjectId, OpenMode.ForWrite, true);
I get this compile error, as I expected.
Error 1
Cannot implicitly convert type 'Autodesk.AutoCAD.DatabaseServices.DBObject' to 'Autodesk.AutoCAD.DatabaseServices.Table'.
An explicit conversion exists (are you missing a cast?)
:\VisualStudio2005\Projects\KDUB\theSwamp\TestTable\TestTable\Class1.cs 105 33 TestTable
-
Luis, Kerry,
Thanks for the replies. It actually helped me to understand more about how .net handles things vs VB/A.
I noticed that the code that Luis posted doesn't use a transaction. I am still a little confused as to the advantages of a transaction when you just want to do something simple. Maybe I should start another topic...
-
Luis, Kerry,
Thanks for the replies. It actually helped me to understand more about how .net handles things vs VB/A.
I noticed that the code that Luis posted doesn't use a transaction. I am still a little confused as to the advantages of a transaction when you just want to do something simple. Maybe I should start another topic...
Hi Joel;
The reason is that when you use transactions, you do not have to close the objects, is the same way as using smart pointers...
:-)
But, I do not write code in C# yet... only ARX [right now I am trying to write this in ObjectARX]
-
Hi Joel,
-
Thanks Kerry,
I must have read that document a dozen times and never saw that section...
-
Hi Kerry;
In your TableTest() function, when you add the row(s), are they shown automatically on the selected Table?, or you have to grip the table and stretched and after that, the new row(s) are shown?
Thanks.
-
Showing automagically.
-
Showing automagically.
Thanks, I did the test on arx, but have not found the method to do that magic.... part :-(
It will add the row, but I have to select after that [grip] the Table to show the new added row.
-
Thanks Mick, it does not work... I open a new topic on the arx forum, and removed the function from here.
-
Luis,
You may want to add this:
pSomeTablePointer->generateLayout();
Kerry, this:
Table tbl = (Table)trans.GetObject(entRes.ObjectId, OpenMode.ForWrite, true);
is probably better written like this (how I do it now):
Table tbl = trans.GetObject(entRes.ObjectId, OpenMode.ForWrite, true) as Table;
The reason..............no exception will be thrown if the direct cast fails, which it can do.
All you should do then is check tbl != null.
Just an observation.
Cheers,
Glenn.
-
....... Table tbl = (Table)trans.GetObject(entRes.ObjectId, OpenMode.ForWrite, true);
is probably better written like this (how I do it now):
Table tbl = trans.GetObject(entRes.ObjectId, OpenMode.ForWrite, true) as Table;
The reason..............no exception will be thrown if the direct cast fails, which it can do.
All you should do then is check tbl != null.
Just an observation.
Cheers,
Glenn.
interesting .. very elegant !
thanks Glenn.
-
LE,
Isn't there an udpate method? Maybe regen the drawing?
-
LE,
Isn't there an udpate method? Maybe regen the drawing?
Hi Joel;
Have a look into here:
http://www.theswamp.org/index.php?topic=9125.0
The code is now working... it is in ObjectARX
Luis Esquivel
-
Let it be said that tables s*%k hard!
Well, it's ok now I've worked them out (for my needs anyhow) but what an effort! There is very little info on the implementation of these things with code.
Anyway, for those interested here's what works for me.
Table mTable = tr.GetObject(entRes.ObjectId,OpenMode.ForWrite)as Table;
int j = 1;
string item = "n/a";
foreach(DataRow dr in dt.Rows)
{
if(dr["itemno"].ToString() == "tbc")
{
item = j.ToString();
j++;
}
else
{
item = dr["itemno"].ToString();
}
mTable.InsertRows(2,1.0,1);
ed.WriteMessage("\n" + item + " " + dr["qty"]);
mTable.SetTextString(2, 0, item );
mTable.SetTextString(2, 1, dr["qty"].ToString());
mTable.SetTextString(2, 2, dr["material"].ToString());
mTable.SetTextString(2, 3, dr["length"].ToString());
mTable.SetTextString(2, 4, dr["mass"].ToString());
}
Note I have a title and header rows in my table style. And the output -