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.