I would like to change property values in MEP with a vb.net program.
Although I found some information in the net, my program will not work.There are no Errors, but the value will not change.
I would be grateful for any advice.
Here is my code:
Public Shared Function SetPropValue (MepObj As AcadDb.DBObject, strPropSetName As String, PropertySetId As ObjectId, strPropName As String, strNewValue As String) As Boolean
Dim db As Database = Autodesk.AutoCAD.ApplicationServices.Core.Application.DocumentManager.MdiActiveDocument.Database
Dim PropSetIDSelected As ObjectId = ObjectId.Null
Try
PropSetIDSelected = AecPropDb.PropertyDataServices.GetPropertySet(MepObj, PropertySetId)
Catch generatedExceptionName As Autodesk.AutoCAD.Runtime.Exception
Return False
End Try
Dim tm As AcadDb.TransactionManager = db.TransactionManager
Using trans As Transaction = tm.StartOpenCloseTransaction
Try
Dim dbobj As AcadDb.DBObject = tm.GetObject(MepObj.Id, OpenMode.ForWrite, False, False)
Dim objPropSet As PropertySet = DirectCast(tm.GetObject(PropSetIDSelected, OpenMode.ForWrite, False, False), PropertySet)
If objPropSet IsNot Nothing Then
Dim objId As Integer
Try
objId = objPropSet.PropertyNameToId(strPropName)
Catch ex As Exception
MsgBox("Property '" & strPropName & "' not sound in PropertySet !")
Return False
End Try
Try
Dim propSetDefinition As PropertySetDefinition
Dim propSetDefId As ObjectId
' Create a Property Set Dictionary
Dim psDict As AecPropDb.DictionaryPropertySetDefinitions = New AecPropDb.DictionaryPropertySetDefinitions(db)
' Check to see if the dictionary contains the name of the property set we are looking for
If (psDict.Has(strPropSetName, trans)) Then
propSetDefId = psDict.GetAt(strPropSetName)
propSetDefinition = DirectCast(tm.GetObject(propSetDefId, OpenMode.ForWrite, False, False), PropertySetDefinition)
Dim propData = objPropSet.PropertySetData.Cast(Of PropertySetData)().FirstOrDefault(Function(d) d.Id = objId)
If propData IsNot Nothing Then
propData.SetData(strNewValue)
End If
End If
Catch ex As Exception
Return False
End Try
End If
Catch
Return False
End Try
trans.Commit()
End Using
' If the temp ObjectId is not null then we found the property set on the object
If Not PropSetIDSelected.IsNull Then
Return True
End If
' If we are at this point then the property set was not found on the object and we can return false.
Return False
End Function
A couple of observations after reading through it real quick. It was hard to read so please try to use code tags next time to get it formatted correctly.
1. If you are trying to set a non manual property definition it will not work. Only manual property definitions can have their value set. All others I believe will just get the value overwritten.
I have some code that will show how to change the value but will not have time until later today/evening to get it posted.
Yes, I only want to change manual property definitions.
Thanks in advance for your help
Hi Keith,
I'm still looking for a solution for my Problem, so I hope you will post your code examples as you told me.
Thanks in advance
Here is one that I found that sets a string value
internal static bool SetPropertyDefinitionValueDouble(Member member, ObjectId propertySetDefinitionId, string propDefName, double propDefValue) { ObjectIdCollection propertySetIds = PropertyDataServices.GetPropertySets(member); bool result = false; using (Application.DocumentManager.MdiActiveDocument.LockDocument()) using (Transaction tr = ActiveDatabase.TransactionManager.StartTransaction()) { foreach (ObjectId propertySetId in propertySetIds) { try { var propertySet = tr.GetObject(propertySetId, OpenMode.ForWrite, false, false) as PropertySet; if (propertySet != null) { int propertyDefinitionId = propertySet.PropertyNameToId(propDefName); if (propertySet.IsWriteEnabled) { propertySet.SetAt(propertyDefinitionId, propDefValue); result = true; } break; } } catch (Exception exception) { // Handle the error or throw it here. } } tr.Commit(); } return result; }
Here are two bonus methods that I found that would be of use to you. If i was to use them today I would rewrite them as an extension method.
internal static ObjectId GetPropertySetDefinitionIdByName(Database database, string propertySetDefinitionName) { ObjectId result = ObjectId.Null; using (Transaction tr = database.TransactionManager.StartTransaction()) { var definitions = new DictionaryPropertySetDefinitions(database); if (!definitions.Has(propertySetDefinitionName, tr)) { PropertySetCloningHelper.ImportStyle(database, propertySetDefinitionName); } result = definitions.GetAt(propertySetDefinitionName); transaction.Commit(); } return result; } internal static bool AddPropertySetToMember(Database database, Member member, string propertySetDefinitionName) { var propertySetDefinitionId = GetPropertySetDefinitionIdByName(database, propertySetDefinitionName); if ( !propertySetDefinitionId.IsNull) { PropertyDataServices.AddPropertySet(member, propertySetDefinitionId ); return true; } return false; }
Sorry Keith, but this will not work.
As I can see in the debugger the value of the property is changed to the new one,
but after commiting and finishing the program I found the old value still in the the properties of the selected object.
Do you have any idea why this could be so ?
Thanks a lot for your help and answers.