.Net, C-Sharp:
I've got configuration data that I'd like to save in a DataTable, but when I load the data into a DataCellCollection, append that to a DataTable, then check the number of cells in the appended row, it looks like the row loses all the cells that it had.
Partial code:
namespace GIS_DuctTape { using System; using System.Collections.Generic; using System.Diagnostics; using Autodesk.AutoCAD.DatabaseServices; public class DuctTapeConfig { //... public DataTable MakeTable() { Debug.WriteLine("DuctTapeConfig#MakeTable() - start"); DataTable table = new DataTable(); table.AppendColumn(CellType.CharPtr, "SourceFile"); table.AppendColumn(CellType.CharPtr, "Feature"); table.AppendColumn(CellType.CharPtr, "AttributeFields"); table.AppendColumn(CellType.CharPtr, "Layer"); foreach(FeatureInfo fi in FeaturesList) { DataCellCollection row = fi.AsDataTableRow; Debug.WriteLine(" input row has " + row.Count + " cells." ); table.AppendRow(row, false); Debug.WriteLine(" table row " + (table.NumRows - 1) + " has " + table.GetRowAt(table.NumRows - 1).Count + " cells." ); } Debug.Flush(); return table; } //... } }
Log file output:
DuctTapeConfig#MakeTable() - start input row has 4 cells. table row 0 has 0 cells.
Any idea what's wrong?
No ideas from anyone?
Just to try to eliminate some things, I've re-written the code:
public void CommitSettings() { Debug.WriteLine("DuctTapeConfig#CommitSettings()"); if (AmChanged) { Debug.Assert(FeaturesList.Count > 0, " Empty features list."); Database db = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Database; OpenCloseTransaction myT = db.TransactionManager.StartOpenCloseTransaction(); DataTable table = null; try { DBDictionary NamedObjsDict = (DBDictionary)myT.GetObject(db.NamedObjectsDictionaryId, OpenMode.ForWrite); if (NamedObjsDict.Contains(DuctTapeEntry)) { table = (DataTable)myT.GetObject(NamedObjsDict.GetAt(DuctTapeEntry), OpenMode.ForWrite); Debug.WriteLine(" found table: column count is " + table.NumColumns); if (table.NumColumns < 4) { NamedObjsDict.Remove(DuctTapeEntry); Debug.WriteLine(" Removed table from Named Objects Dictionary"); } else { while (table.NumRows > 0) table.RemoveRowAt(0); } } else { table = new DataTable(); table.AppendColumn(CellType.CharPtr, "SourceFile"); table.AppendColumn(CellType.CharPtr, "Feature"); table.AppendColumn(CellType.CharPtr, "AttributeFields"); table.AppendColumn(CellType.CharPtr, "Layer"); NamedObjsDict.SetAt(DuctTapeEntry, table); myT.AddNewlyCreatedDBObject(table, true/*add*/); Debug.Assert((table.NumColumns == 4), "New data table is corrupted"); } Debug.Assert(table.IsWriteEnabled, "Data table is not write enabled"); foreach(FeatureInfo fi in FeaturesList) { DataCellCollection row = fi.AsDataTableRow; int nRowAdded = -1; Debug.WriteLine(" Before append, row has " + row.Count + " cells." ); table.AppendRow(row, true); nRowAdded = table.NumRows - 1; row = table.GetRowAt(nRowAdded); Debug.WriteLine(" After append, row has " + row.Count + " cells."); } } finally { myT.Commit(); myT.Dispose(); if (table != null) table.Dispose(); Debug.Flush(); } } }
Log file results:
DuctTapeConfig#CommitSettings() found table: column count is 4 Before append, row has 4 cells. After append, row has 0 cells.
I have never worked wit DataTable before
Just at the quick glance
Use Try..Catch to handle errors easily
Try something like this
public void CommitSettings() { Document doc=Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument; Database db = doc.Database; Editor ed=doc.Editor; using (Transaction myT = db.TransactionManager.StartTransaction()) { DataTable table = null; try { //Your rest code here myT.Commit(); // myT.Dispose(); } catch (System.Exception ex) { ed.WriteMessage("\nReason of Error: {0}\nTrace: {1}",ex.Message,ex.StackTrace); } finally { for (int r = 0; r < table.NumRows; r++) { string strrow = ""; for (int c = 0; c < table.NumColumns; c++) { DataCell cl = table.GetCellAt(r, c); strrow = strrow + "\t" + cl.Value.ToString(); } ed.WriteMessage("\n\t==>{0}", strrow); } if (table != null) table.Dispose(); } } }
After your code will be finished check your table
by typing this expression in the command line:
(entget (cdr (last (entget (cdr (assoc 330 (dictnext (namedobjdict) "DuctTapeEntryStringHere")))))))
just change DuctypeEntry string in this expresion
Thanks for the response. I added the catch(System.Exception err){ } block as suggested, compiled and ran the app. As written, the code does not throw an exception, seemingly.
I used the Lisp code suggested, and confirmed that the table was inserted properly into the Named Objects Dictionary.
From other testing, the table itself is added properly, and it has the row that was added - but the row doesn't have any cells in it.
Most perplexing.
I just added dummy values this way it's working on my end
for (int i = 0; i < 9; i++) { //DataCellCollection row = fi.AsDataTableRow; DataCellCollection row = new DataCellCollection(); for (int a = 0; a < 4; a++) { DataCell cl = new DataCell(); //= new Cell(); cl.SetString("Row" + (i + 1).ToString()+"Col" + (a + 1).ToString()); row.Add(cl); } int nRowAdded = -1; // Debug.WriteLine(" Before append, row has " + row.Count + " cells."); table.AppendRow(row, false); nRowAdded = table.NumRows - 1; row = table.GetRowAt(nRowAdded); //Debug.WriteLine(" After append, row has " + row.Count + " cells."); }
Remove all ugly Debugs from there 🙂
Hello Hallex,
Have you worked with DataTable since?
I just tried working with DataTable today and I experienced the exact behaviour.
Row being added but the DataCellCollection (Cells) that were added to it do not persist.
Which AutoCAD version were you using? I'm using 2010 with no service pack. I think I'll try, at some point with another version. I could really make use of a data table but there are ways around this.
May I say congratulations on your retirement? 🙂
AutoCAD is fun as long as there are problems to solve 😄
Have a good year!
Can't find what you're looking for? Ask the community or share your knowledge.