I am not sure what is wrong without having your actual drawing to test/debug the code. However, the code has a minor bug, which seems not related to the error you get: when comparing PropertySet's name with given PropertySetDefinition's name, we should use "PropertySetDefinitionName" property, instead of "Name". That is:
if line:
If (propSet.Name.ToUpper() = propertySetName.ToUpper()) Then
should be
If (propSet.PropertySetDefinitionName.ToUpper() = propertySetName.ToUpper() Then
... ...
I put together some code to retrieve/set an entity with PropertySet data in this scenario: a propertyset is defined in the drawing, called "Test Property Set", which has 2 Properties: Name (string) and Count (integer). Code is as following:
using System.Collections.Generic;
using CadDb = Autodesk.AutoCAD.DatabaseServices;
using PsDb = Autodesk.Aec.PropertyData.DatabaseServices;
using Autodesk.Aec.PropertyData.DatabaseServices;
using Autodesk.AutoCAD.DatabaseServices;
namespace EntityPropertySetData
{
public class PropertySetDataUtil
{
public static void SetPropertySetDataToEntity(
CadDb.ObjectId entId, string propertysetName, Dictionary<string, object> values)
{
using (var tran = entId.Database.TransactionManager.StartTransaction())
{
var ent = tran.GetObject(entId, CadDb.OpenMode.ForRead);
var pset = GetPropertySetFromEntity(propertysetName, ent, tran, true);
UpdatePropertySetData(pset, values);
tran.Commit();
}
}
public static Dictionary<string, object> GetPropertySetDataFromEntity(
CadDb.ObjectId entId, string propertysetName)
{
var dic = new Dictionary<string, object>();
using (var tran = entId.Database.TransactionManager.StartTransaction())
{
var ent = tran.GetObject(entId, OpenMode.ForRead);
var pset = GetPropertySetFromEntity(propertysetName, ent, tran, false);
if (pset!=null)
{
foreach (PsDb.PropertySetData data in pset.PropertySetData)
{
var propId = data.Id;
var propName = pset.PropertyIdToName(propId);
// Get property value
object val = data.GetData();
// or
val = pset.GetAt(propId);
dic.Add(propName, val);
}
}
tran.Commit();
}
return dic;
}
private static PropertySet GetPropertySetFromEntity(
string propertysetName, DBObject ent, Transaction tran, bool create = true)
{
PropertySet ps = GetPropertySetFromExistings(ent, propertysetName, tran);
if (ps==null && create)
{
var psDefId = GetPropertySetDefinitionId(ent.Database, propertysetName);
if (!psDefId.IsNull)
{
if (!ent.IsWriteEnabled) ent.UpgradeOpen();
PropertyDataServices.AddPropertySet(ent, psDefId);
ps = GetPropertySetFromExistings(ent, propertysetName, tran);
}
}
return ps;
}
private static PropertySet GetPropertySetFromExistings(
DBObject ent, string propertysetName, Transaction tran)
{
PropertySet pset = null;
try
{
var psIds = PropertyDataServices.GetPropertySets(ent);
foreach (CadDb.ObjectId id in psIds)
{
var ps = (PropertySet)tran.GetObject(id, OpenMode.ForRead);
if (ps.PropertySetDefinitionName.ToUpper() == propertysetName.ToUpper())
{
pset = ps;
break;
}
}
}
catch { }
return pset;
}
private static CadDb.ObjectId GetPropertySetDefinitionId(
Database db, string propertysetName)
{
using (var propDic = new PsDb.DictionaryPropertySetDefinitions(db))
{
foreach (string name in propDic.NamesInUse)
{
if (name.ToUpper() == propertysetName.ToUpper())
return propDic.GetAt(name);
}
}
return ObjectId.Null;
}
private static void UpdatePropertySetData(
PropertySet pset, Dictionary<string, object> values)
{
if (!pset.IsWriteEnabled) pset.UpgradeOpen();
foreach (var item in values)
{
var propName = item.Key;
var val = item.Value;
UpdateProperty(pset, propName, val);
}
}
private static void UpdateProperty(
PropertySet pset, string propName, object propValue)
{
int propId = -1;
try
{
propId = pset.PropertyNameToId(propName);
}
catch { }
if (propId >= 0)
{
pset.SetAt(propId, propValue);
}
}
}
}
using System.Collections.Generic;
using System.Text;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Runtime;
using CadApp = Autodesk.AutoCAD.ApplicationServices.Application;
[assembly: CommandClass(typeof(EntityPropertySetData.MyCommands))]
namespace EntityPropertySetData
{
public class MyCommands
{
private const string PROPERTY_SET_NAME = "Test Property Set";
private const string PROPERTY_NAME_1 = "Name";
private const string PROPERTY_NAME_2 = "Count";
[CommandMethod("GetPsData")]
public static void GetPropertySetData()
{
var doc = CadApp.DocumentManager.MdiActiveDocument;
var ed = doc.Editor;
var entId = SelectEntity(ed);
if (!entId.IsNull)
{
var dic = PropertySetDataUtil.GetPropertySetDataFromEntity(
entId, PROPERTY_SET_NAME);
if (dic.Count>0)
{
var msg = new StringBuilder();
foreach (var item in dic)
{
msg.Append($"\nProperty Name: {item.Key}\t" +
$"Property Value: {item.Value.ToString()}");
}
ed.WriteMessage(msg.ToString());
}
else
{
ed.WriteMessage(
"\nNo property data found with selected entity!");
}
}
ed.WriteMessage("\n");
}
[CommandMethod("SetPsData")]
public static void SetPropertySetData()
{
var doc = CadApp.DocumentManager.MdiActiveDocument;
var ed = doc.Editor;
var entId = SelectEntity(ed);
if (!entId.IsNull)
{
var values = new Dictionary<string, object>();
values.Add(PROPERTY_NAME_1, "ABCDEFG");
values.Add(PROPERTY_NAME_2, 202);
PropertySetDataUtil.SetPropertySetDataToEntity(
entId, PROPERTY_SET_NAME, values);
}
}
private static ObjectId SelectEntity(Editor ed)
{
var res = ed.GetEntity("\nSelect entity:");
if (res.Status == PromptStatus.OK)
return res.ObjectId;
else
return ObjectId.Null;
}
}
}
See the video clip bellow on how the code works, as expected: