AutoCAD Map 3D Developer
Welcome to Autodesk’s AutoCAD Map 3D Developer Forums. Share your knowledge, ask questions, and explore popular AutoCAD Map 3D Developer topics.
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Problem accessing ObjectData...

14 REPLIES 14
SOLVED
Reply
Message 1 of 15
ckrath
6804 Views, 14 Replies

Problem accessing ObjectData...

I am developing a program to read Object Data in AutoCAD Map 3D 2009 using C#.Net. I use managedmapapi.dll for this.

 

My program will first read the object data, then verify it with some other data sources and then it will write the modified values  to the AutoCAD entity. To read the object data I am using OpenMode.OpenForRead.

 

Here my problem is..

 

Once I access the records in ODTables with read mode for reading Object Data, I am unable to access the records with write mode for writing. Program crashes on this line.

 

Am I missing some Object Releaser !!!

 

Please Help...

 

Thanks.

Chandan.

14 REPLIES 14
Message 2 of 15
norman.yuan
in reply to: ckrath

Why don't you just get the Records in OpenForWrite mode?

 

Or if the process is like: opening OD Reocrds (for read), then your code/user need to do something, then yourcode need to update the OD Records when needed. In this case, you'd better not hold Records object you created when opening for read. You should open the Records for read, read all data into a custom objects with entity's ObjectId as key/identifier; do something (such as comparingvalues from other data source); then if update is necessary, open the Records again for write and update it. psuedo code like this:

 

foreach (ObjectId entId in targetEntityIds)

{

    //The Records only lives for read

    //Do not hold it after reading OD data for later use

    using (Records rds=ODTable.GetObjectRecords(0,OpenMode.OpenForRead,false))

   {

        ''retrieve OD data into a custom class object

    }

}

 

''Do something with the retrieved data, such as comparing with external data

 

foreach (ObjectId entId in targetEntityIds)

{

    if (the entity'd OD Data need to be updated)

   {

       //Open the Records for write

       using (Records rds=GetObjectRecords(0,OpenMode.OpenForWrite,false))

       {

          ''Update OD Data for the entity

       }

    }

}

Message 3 of 15
ckrath
in reply to: norman.yuan

 

norman.yuan,
Please have a look at my code:
First I have to show the object data in a datagridview, for that I have used a data table. to populate the columns of the data table, I have used the following code which I wrote in a different class:
public static ArrayList columnNames(string tableName)
{
	ArrayList result = new ArrayList();
	Editor ed = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Editor;
	Database db = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Database;

	try
	{
		Tables tables = Autodesk.Gis.Map.HostMapApplicationServices.Application.ActiveProject.ODTables;
		Autodesk.Gis.Map.ObjectData.Table myTable = tables[tableName];
		FieldDefinitions tableDef = myTable.FieldDefinitions;
	        for(int i = 0; i < tableDef.Count; i++)
	         {
	           	FieldDefinition column = null;
	           	column = tableDef[i];
	           	result.Add(column.Name);
	         }
	}
	catch(Autodesk.Gis.Map.MapException Exp)
	{
		ed.WriteMessage(Exp.Message);
	}
	return result;
}

 

To read Object Data (written in another class):
public static string ReadODRecord(string tableName, string fieldName, ObjectId id)
{
    Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
    string fieldValue=null;
	Tables tables = HostMapApplicationServices.Application.ActiveProject.ODTables;
   	using (Records records = tables.GetObjectRecords(0, id, Autodesk.Gis.Map.Constants.OpenMode.OpenForWrite, false)) //program crashed here.
    {
        if (records.Count == 0)
        {
            ed.WriteMessage("\n There is no ObjectData record attached.");
            records.Dispose();
            return null;
        }
        foreach (Record record in records)
        {
            Autodesk.Gis.Map.ObjectData.Table table = tables[record.TableName];
            if (table.Name.CompareTo(tableName) == 0)
            {
                for (int i = 0; i < record.Count; i++)
                {
                    FieldDefinitions tableDef = table.FieldDefinitions;
                    FieldDefinition column = null;
                    column = tableDef[i];
                    string colName = column.Name;
                    if (colName.CompareTo(fieldName) == 0)
                    {
                        MapValue val = record[i];
                        fieldValue = val.StrValue;  
                        break;
                    }
                }
            }
        }
        return fieldValue; 
    }
}

 To add or update object data (written in another class):

 

 

public static void AddOrUpdOD(string TableName, ObjectId objectID, string columnName, string value)
{
	Autodesk.Gis.Map.ObjectData.Tables tables = Autodesk.Gis.Map.HostMapApplicationServices.Application.ActiveProject.ODTables;
	Editor ed = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Editor;
	using(Records rcs = tables.GetObjectRecords(0, objectID, Autodesk.Gis.Map.Constants.OpenMode.OpenForWrite, false))  //program crashed here.
	{
		if(rcs.Count == 0)
		{
			Autodesk.Gis.Map.ObjectData.Table table = tables[TableName];
			Record Rec = Record.Create();
			table.InitRecord(Rec);
			table.AddRecord(Rec,objectID);
		}
	}
	
	using(Records records = tables.GetObjectRecords(0, objectID,
Autodesk.Gis.Map.Constants.OpenMode.OpenForWrite, false))
	{
		if(records.Count == 0)
		{
			ed.WriteMessage("\nData attachment failed.");
			return;
		}
		
		foreach(Record Recd in records)
		{
			Autodesk.Gis.Map.ObjectData.Table tbl = tables[Recd.TableName];
			if(tbl.Name.CompareTo(TableName) == 0)
			{
				for(int i = 0; i < Recd.Count; i++)
				{
					FieldDefinitions tblDefs = tbl.FieldDefinitions;
					FieldDefinition column = null;
					column = tblDefs[i];
					if(column.Name.CompareTo(columnName) == 0)
					{
						Recd[i].Assign(value);
						records.UpdateRecord(Recd);
						break;
					}
				}
			}
		}
	}
}

 

 

Then, to populate the datatable I have used the following code:

 

 

void BtnViewClick(object sender, EventArgs e)
{
	Autodesk.AutoCAD.ApplicationServices.Document doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
	Autodesk.AutoCAD.DatabaseServices.Database db = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Database;
	Autodesk.AutoCAD.EditorInput.Editor ed = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Editor;
	
	try
	{
		Autodesk.AutoCAD.DatabaseServices.TypedValue[] val = {new Autodesk.AutoCAD.DatabaseServices.TypedValue((int)Autodesk.AutoCAD.DatabaseServices.DxfCode.Start, "LWPOLYLINE"), new Autodesk.AutoCAD.DatabaseServices.TypedValue((int)Autodesk.AutoCAD.DatabaseServices.DxfCode.LayerName, cmbLayer.Text)};
		Autodesk.AutoCAD.EditorInput.SelectionFilter sf = new Autodesk.AutoCAD.EditorInput.SelectionFilter(val);
		Autodesk.AutoCAD.EditorInput.PromptSelectionResult res = ed.SelectAll(sf);
		
		if(res.Status != Autodesk.AutoCAD.EditorInput.PromptStatus.OK) return;
		ArrayList featIds = new ArrayList();
		Autodesk.AutoCAD.EditorInput.SelectionSet selSet = res.Value;
		Autodesk.AutoCAD.DatabaseServices.ObjectId[] IdArray = selSet.GetObjectIds();
		
		System.Data.DataTable dt = new System.Data.DataTable(cmbLayer.Text);
		ArrayList columnNames;
		using(Autodesk.AutoCAD.DatabaseServices.TransactionManager tm = db.TransactionManager)
		{
			using(Autodesk.AutoCAD.DatabaseServices.Transaction txn = tm.StartTransaction())
			{
				columnNames = ODUtil.ObjectData.columnNames(cmbODTable.Text);
			}
		}
		if(columnNames.Count > 0)
		{
			dt.Columns.Add("ObjectID");
			for(int i = 0; i < columnNames.Count; i++)
			{
				dt.Columns.Add(columnNames[i].ToString());
			}
		}
		else
		{
			MessageBox.Show("Object Data Table is not accessible.");
			return;
		}
		foreach(Autodesk.AutoCAD.DatabaseServices.ObjectId oid in IdArray)
		{
			Autodesk.AutoCAD.DatabaseServices.Entity ent;
			using(Autodesk.AutoCAD.DatabaseServices.TransactionManager tm = db.TransactionManager)
			{
				using(Autodesk.AutoCAD.DatabaseServices.Transaction txn = tm.StartTransaction())
				{
					ent = (Autodesk.AutoCAD.DatabaseServices.Entity)txn.GetObject(oid, Autodesk.AutoCAD.DatabaseServices.OpenMode.ForRead, false);
				}
			}
			Autodesk.AutoCAD.DatabaseServices.Polyline pl = ent as Autodesk.AutoCAD.DatabaseServices.Polyline;
			if(pl.Closed)
			{
				System.Data.DataRow dr = dt.NewRow();
				dr[0] = pl.ObjectId.ToString();
				for(int i = 1; i < columnNames.Count + 1; i++)
				{
					using(Autodesk.AutoCAD.DatabaseServices.TransactionManager tm = db.TransactionManager)
					{
						using(Autodesk.AutoCAD.DatabaseServices.Transaction txn = tm.StartTransaction())
						{
							dr[i] = Convert.ToString(ODUtil.ObjectData.ReadODRecord("Parcels",columnNames[i-1].ToString(), pl.ObjectId));
						}
					}
				}
				dt.Rows.Add(dr);
			}
		}
		dt.DefaultView.Sort = dt.Columns[1].ColumnName + " ASC";
		dataGridView1.DataSource = dt.DefaultView;
	}
	catch(Autodesk.AutoCAD.Runtime.Exception Exp)
	{
		MessageBox.Show("ERROR:" + Environment.NewLine + Exp.Message + Exp.StackTrace);
	}
}

 

Program always crashes when ever i tried to open the OD records in write mode. In read mode its ok.

Is there something wrong with this code.

 

 

Thank you...

Chandan.

 

Tags (1)
Message 4 of 15
norman.yuan
in reply to: ckrath

I cannot spot something obviously wrong in the code. What exception you get? Here is the quote from Map ObjectARX ,NET Reference Document on the possible exception of calling Tables.GetObjectRecord() methods:

 

<QUOTE>

Remarks

Allocates an Records used to navigate through this object data table's records associated with the drawing specified by dwgId, and associates the Records with an object and initializes its open mode. Locks the specified source drawing for reading, if it is not already locked. Use Tables::GetObjectRecords to create an Records for traversing all the object data tables associated with the project. An exception of MapException will be thrown if the process failed, the error codes of exception are as follows: Map::Constants::ErrorCode::ErrorObjNotInitialized if the drawing is not active Map::Constants::ErrorCode::ErrorPermissionDenied if an error occurred when attempting to lock the specified drawing. Map::Constants::ErrorCode::ErrorWrongArgument if the object does not belong to the drawing that is associated with the iterator. Map::Constants::ErrorCode::ErrorPermissionDenied if openMode does not correspond to the mode of the AutoCAD object.

</QUOTE>

 

This description may help you to identify the cause of the crash.

 

Also, in my code, I always used Table.GetObjectRecords(), instead of Tables.GetObjectRecords(), and have not run into the crash you have had. So, why don't you try this, in case it may work for you:

 

Table tbl=.HostMapApplicationServices....ODTables[tblName];

using (Records reds=tbl.GetObjectRecords(...OpenMode.OpenForWrite))

{

 

}

Message 5 of 15
ckrath
in reply to: norman.yuan

Now I have changed the code as u have mentioned.

 

 

Tables tables = HostMapApplicationServices.Application.ActiveProject.ODTables;
Table table = tables[tableName];

using (Records records = table.GetObjectTableRecords(0, id, Autodesk.Gis.Map.Constants.OpenMode.OpenForWrite, false))
{
//codes....
}

 

 

still I am getting the same error. I have attached the jpg of exception.

 

 

Thanks.

Chandan.

Message 6 of 15
norman.yuan
in reply to: ckrath

I just wrote a quick test from scratch (all my previous Object Data dealing code was written many years ago, against Acad Map 2006, so I decide not re-use it for this test).

 

It works OK with my AcadMap2011. Note, there is 2 command methods: "ReadOD" and "UpdateOD". In the ReadOD, the records should have been retirieved with OpenMode.OpenForRead, but I tried both OpenForread and OpenForWrite and both worked OK, so I left it as OpenForWrite.

 

I also user Table.GetObjectRecords(), just to prove that it works for me.

 

The map utility class:

 

using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Text;

using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;

using Autodesk.AutoCAD.Geometry;
using Autodesk.Gis.Map;
using Autodesk.Gis.Map.Project;
using Autodesk.Gis.Map.ObjectData;
using Autodesk.Gis.Map.Utilities;

namespace MapODDataUpdate
{
    public class MapTool
    {
        private StringBuilder mError = new StringBuilder();
        private ProjectModel mMapProj = null;

        public MapTool(Document dwg)
        {
            mMapProj = HostMapApplicationServices.
                Application.Projects.GetProject(dwg);
        }

        public string ErrorMsg
        {
            get { return mError.ToString(); }
        }

        public string[] GetODTableNames()
        {
            List<string> lst = new List<string>();
            StringCollection ts = mMapProj.ODTables.GetTableNames();
            foreach (string t in ts)
            {
                lst.Add(t);
            }

            return lst.ToArray();
        }

        public bool ODTableExists(string tableName)
        {
            return mMapProj.ODTables.IsTableDefined(tableName);
        }

        public bool RetrieveODRecordFromEntity(
            string tableName, ObjectId entId, out Dictionary<string, object> data)
        {
            data = new Dictionary<string, object>();

            mError.Length = 0;

            if (!mMapProj.ODTables.IsTableDefined(tableName))
            {
                mError.Append("Object Data Table is not defined: " + tableName + ".");
                return false;
            }

            Autodesk.Gis.Map.ObjectData.Table tbl = mMapProj.ODTables[tableName];

            using (Records records = mMapProj.ODTables.GetObjectRecords(
                0, entId, Autodesk.Gis.Map.Constants.OpenMode.OpenForWrite, false))
            {
                if (records.Count == 0) return true;

                foreach (Record record in records)
                {
                    for (int i = 0; i < record.Count; i++)
                    {
                        //get field name
                        FieldDefinition field = tbl.FieldDefinitions[i];
                        string fieldName = field.Name;

                        MapValue val = record[i];
                        object fieldValue = null;

                        switch (val.Type)
                        {
                            case Autodesk.Gis.Map.Constants.DataType.Integer:
                                fieldValue = Convert.ToInt32(val.Int32Value);
                                break;
                            case Autodesk.Gis.Map.Constants.DataType.Character:
                                fieldValue = Convert.ToString(val.StrValue);
                                break;
                            case Autodesk.Gis.Map.Constants.DataType.Real:
                                fieldValue = Convert.ToDouble(val.DoubleValue);
                                break;
                            case Autodesk.Gis.Map.Constants.DataType.Point:
                                Point3d pt = val.Point;
                                fieldValue = string.Format("Point({0},{1},{2})", pt.X, pt.Y, pt.Z);
                                break;
                            default:
                                fieldValue = null;
                                break;
                        }

                        if (data.ContainsKey(fieldName))
                        {
                            if (data[fieldName] == null) data[fieldName] = fieldValue;
                        }
                        else
                        {
                            data.Add(fieldName, fieldValue);
                        }
                    }
                }
            }

            return true;
        }

        public bool UpdateODRecordToEntity(
            string tableName, ObjectId entId, Dictionary<string, object> data)
        {
            mError.Length = 0;

            if (!mMapProj.ODTables.IsTableDefined(tableName))
            {
                mError.Append("Object Data Table is not defined: " + tableName + ".");
                return false;
            }

            Autodesk.Gis.Map.ObjectData.Table tbl = mMapProj.ODTables[tableName];

            using (Records records = mMapProj.ODTables.GetObjectRecords(
                0, entId, Autodesk.Gis.Map.Constants.OpenMode.OpenForWrite, false))
            {
                if (records.Count == 0) return true;

                foreach (Record record in records)
                {
                    for (int i = 0; i < record.Count; i++)
                    {
                        //get field name
                        FieldDefinition field = tbl.FieldDefinitions[i];
                        string fieldName = field.Name;

                        if (data.ContainsKey(fieldName))
                        {
                            MapValue val = record[i];

                            switch (val.Type)
                            {
                                case Autodesk.Gis.Map.Constants.DataType.Integer:
                                    val.Assign(Convert.ToInt32(data[fieldName]));
                                    break;
                                case Autodesk.Gis.Map.Constants.DataType.Character:
                                    val.Assign(Convert.ToString(data[fieldName]));
                                    break;
                                case Autodesk.Gis.Map.Constants.DataType.Real:
                                    val.Assign(Convert.ToDouble(data[fieldName]));
                                    break;
                                default:
                                    //Do nothing
                                    //If the value is Point, do something...
                                    break;
                            }
                        }
                    }

                    records.UpdateRecord(record);
                }
            }

            return true;
        }
    }
}

 The command class:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Geometry;

[assembly: CommandClass(typeof(MapODDataUpdate.MyCommands))]

namespace MapODDataUpdate
{
    public class MyCommands
    {
        [CommandMethod("ReadOD")]
        public static void ReadODData()
        {
            Document dwg = Application.DocumentManager.MdiActiveDocument;
            Editor ed = dwg.Editor;

            PromptEntityOptions opt=new PromptEntityOptions("\nPick an entity: ");
            PromptEntityResult res=ed.GetEntity(opt);

            if (res.Status!=PromptStatus.OK) 
            {
                ed.WriteMessage("\n*Cancel*");
                return;
            }

            Dictionary<string, object> dic;

            MapTool map = new MapTool(dwg);
            if (!map.RetrieveODRecordFromEntity("Table1", res.ObjectId, out dic))
            {
                ed.WriteMessage("\nError: " + map.ErrorMsg);
                return;
            }

            foreach (KeyValuePair<string, object> item in dic)
            {
                ed.WriteMessage("\nFiled: {0} -> Value: {1}", item.Key, item.Value);
            }
        }

        [CommandMethod("UpdateOD")]
        public static void UpdateODData()
        {
            Document dwg = Application.DocumentManager.MdiActiveDocument;
            Editor ed = dwg.Editor;

            PromptEntityOptions opt = new PromptEntityOptions("\nPick an entity: ");
            PromptEntityResult res = ed.GetEntity(opt);

            if (res.Status != PromptStatus.OK)
            {
                ed.WriteMessage("\n*Cancel*");
                return;
            }

            PromptIntegerOptions optInt = 
                new PromptIntegerOptions("\nEnter an integer number: ");
            PromptIntegerResult resInt = ed.GetInteger(optInt);

            if (resInt.Status != PromptStatus.OK)
            {
                ed.WriteMessage("\n*Cancel*");
                return;
            }

            //Update a field in the ODtable, called "Field1", which has Integer type value
            Dictionary<string, object> dic = new Dictionary<string, object>();
            dic.Add("Field1", resInt.Value);

            MapTool map = new MapTool(dwg);
            if (!map.UpdateODRecordToEntity("Table1", res.ObjectId, dic))
            {
                ed.WriteMessage("\nError: " + map.ErrorMsg);
                return;
            }

            foreach (KeyValuePair<string, object> item in dic)
            {
                ed.WriteMessage("\nFiled: {0} -> Value: {1}", item.Key, item.Value);
            }
        }
    }
}

 So, the "UpdateOD" command world work as long as the OD Table has an Integer field called "Field1".

 

You may want to just create a test project and copy my code into it. Then create a test drawing, add an OD Table with a field called "Field1" as Integer type (plus other fields of your choice). Then verify the code runs OK or not.

 

Message 7 of 15
ckrath
in reply to: norman.yuan

Yes norman.yuan, your code is working fine.

 

I made a new command method, which shows only the object data using editor.writemessage. Here my code is working fine with write mode.

 

Now I have a strange question..

 

Is it mandatory to access the OD table records in write mode using command methods only?

In my project I am calling the readODRecord method from a win form window, where the datagridview is present.

I think, this is the reason which causes such a crash. while calling the readODRecord method, the active window is a winform, not the autocad window.

Message 8 of 15
ckrath
in reply to: ckrath

norman.yuan,

 

Problem solved.

 

I have changed the code to call the readODRecord through CommandMethod instead of calling it through button click event.

 

Thank you very much for your quick response and problem solving ideas, without which my project would not be successful.

 

Thanks.

Chandan.

Message 9 of 15
norman.yuan
in reply to: ckrath

How your form is shown? A modal dialog or modeless dialog, or Palette window? If it is modal dialog, do you start it with a command method with CommandFlags.Session? In all of this cases, you need lock the document if the GetObjectRecords() method is called with OpenMode.OpenForWrite and called from the form:

 

psuedo-code:

 

//Assume you click a buuton to have AutoCAD MAP

//search current drawing for OD Data

private void Button_Click(...)

{

    Document dwg=Autodesk.A....MdiDocument

    using { DocumentLock lk=dwg.LockDocument())

    {

        ObjctIdCollection ids=SelectEntities();

       foreach (ObjectId id in ids)

       { 

          using (Records rds=theTables.GetObjectRecords(0, id, OpenMode.OpenForWrite, false)

          {

            ...

          }

       }

   }

}

 

In order for your OD data utility tool to be more robust, you may want to have a Document reference in it and always use it to generate a Document lock arounf GetObjectRecords() call, regardless how the utility method is used (in command method, or in a form, modal or modeless).

 

Message 10 of 15
ckrath
in reply to: norman.yuan

My form is a modeless form. Using the document locking method, its working fine.

I think this is the perfect solution for this problem.

 

Thank you norman.yuan.

 

 

Thanks.

Chandan.

Message 11 of 15
hmcdowney
in reply to: ckrath

Seems as though this should be in the documentation. If you gentlemen have found it there, would you mind posting the page in the Developer docs? Thanks!

 

-jk

-jk
Message 12 of 15
norman.yuan
in reply to: hmcdowney

Are you asking why/when the LockDocument() should be used? The OP's issue is due to the fact he uses a modeless form and tries to modify drawing data from the modeless form, thus locking document is needed.

 

In the Autodesk .NET development guide onlie (http://docs.autodesk.com/ACD/2010/ENU/AutoCAD%20.NET%20Developer's%20Guide/index.html), go to "Control AutoCAD Environment"->"Lock and Unlock Document" for more details.

 

Message 13 of 15
hmcdowney
in reply to: norman.yuan

Now that you mention it, I think that is what I am asking. 🙂 I am having a large degree of difficulty updating (even attaching) an Object Data record from a WinForm in C# with Map 2011. (I created a separate post on the issue.) I will check out the reference and see if it sheds any light on my difficulty. (I have included the lock document code that you mentioned but I'm afraid that the issue is over my head and the "error message" from Autodesk is a little too explicit for my young ears (in other words, it's extremely vague).

 

Really appreciate you responding so quickly!

-jk
Message 14 of 15
hmcdowney
in reply to: hmcdowney

Ok, I see that the drawing may have to be locked here. I will attempt to correctly lock the document and see if this solves the problem.

 

Thanks so much!!

-jk
Message 15 of 15

I had a similar problem but instead I wanted to add OData en stumbled against some problems and unhelpfull exceptions. But I managed to get it working and I wanted to add my code here for completeness:

 

 

using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.Gis.Map.ObjectData;
using Autodesk.Gis.Map.Project;
using Autodesk.Gis.Map.Utilities;
using System;
using System.Collections.Generic;

namespace PlaceHolderNamespace
{
	public static class Odata
	{
		public static void AddODTableToEntity(
						ProjectModel mapProject,
						string tableName,
						ObjectId entId,
						Dictionary<string, string> data)
		{
			var tableNameWithoutSpaces = tableName.Replace(" ", "_");
			Tables tables = mapProject.ODTables;

			AddTable(tables, tableNameWithoutSpaces, data);
			using (var table = GetTable(tables, tableNameWithoutSpaces))
			{
				AddRecords(table, entId, data);
			}
		}

		private static void AddRecords(Autodesk.Gis.Map.ObjectData.Table table, ObjectId entId, Dictionary<string, string> data)
		{

			int index = 0;
			foreach (var item in data)
			{
				using (var record = Record.Create())
				{
					table.InitRecord(record);
					MapValue value = record[index];
					value.Assign(item.Value);
					table.AddRecord(record, entId);
					index++;
				}
			}
		}

		private static Autodesk.Gis.Map.ObjectData.Table GetTable(Tables tables, string tableName)
		{
			if (!tables.IsTableDefined(tableName))
			{
				throw new InvalidOperationException($"{tableName} does not exists");
			}

			return tables[tableName];
		}

		private static void AddTable(Tables tables, string tableName, Dictionary<string, string> data)
		{
			if (tables.IsTableDefined(tableName))
			{
				throw new InvalidOperationException($"{tableName} already exists");
			}

			FieldDefinitions fieldDefinitions = CreateFieldDefinitions(data);
			tables.Add(tableName, fieldDefinitions, tableName, false);
		}

		private static FieldDefinitions CreateFieldDefinitions(Dictionary<string, string> data)
		{
			var fieldDefinitions = FieldDefinitions.Create();
			int index = 0;
			foreach (var item in data)
			{
				fieldDefinitions.Add(item.Key, "", Autodesk.Gis.Map.Constants.DataType.Character, index);
				index++;
			}

			return fieldDefinitions;
		}
	}
}

 

 

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk Design & Make Report

”Boost