ok, well I did it. It seems that, in lay-mans terms, there's been a bit of a storm in the timber yard - and, well, the whole way of thinking about property sets and property set definitions has been re-thought on the journey from VBA to .NET . That said, the future is bright - albeit full of transactions and blocktables, just takes a long time for guys like me to get their head around it.
So here's some pretty butch code that finds a single definition, on a single property set, on a AecDbSpace. If you have the same named definition on another property set, it wont touch it, or if you have the same named definition on another object - like a AECPolygon, it won't touch it.
Pat on the back.
#Region "Namespaces"
Imports System
Imports Autodesk.AutoCAD.ApplicationServices
Imports Autodesk.AutoCAD.DatabaseServices
Imports Autodesk.AutoCAD.EditorInput
Imports Autodesk.AutoCAD.Runtime
Imports Autodesk.Aec.DatabaseServices
Imports Autodesk.Aec.PropertyData.DatabaseServices
Imports DBTransactionManager = Autodesk.AutoCAD.DatabaseServices.TransactionManager
Imports AcadDb = Autodesk.AutoCAD.DatabaseServices
Imports AecDb = Autodesk.Aec.DatabaseServices
Imports AecPropDb = Autodesk.Aec.PropertyData.DatabaseServices
Imports ObjectId = Autodesk.AutoCAD.DatabaseServices.ObjectId
Imports ObjectIdCollection = Autodesk.AutoCAD.DatabaseServices.ObjectIdCollection
Imports AecDbSrvcs = Autodesk.Aec.DatabaseServices
Imports ArchDbSrvcs = Autodesk.Aec.Arch.DatabaseServices
#End Region
Public Class Renumber
#Region "Command_Renumber"
' <summary>
' Command implementation for SetPropertyDataByName.
' </summary>
<Autodesk.AutoCAD.Runtime.CommandMethod("AecPropertySampleMgd", "koe", Autodesk.AutoCAD.Runtime.CommandFlags.Modal)> _
Public Sub Command_SetPropertyDataByName()
Dim ed As Editor = Application.DocumentManager.MdiActiveDocument.Editor
Dim psetname As String = "Block_properties"
Dim pname As String = "Block_ID"
Dim NewValue As Integer = 112233
Dim db As Database = HostApplicationServices.WorkingDatabase
Dim tm As AcadDb.TransactionManager = db.TransactionManager
Dim dbobj As AcadDb.DBObject
Dim trans As Transaction = tm.StartTransaction()
Dim bt As BlockTable = tm.GetObject(db.BlockTableId, OpenMode.ForRead, False)
Dim btr As BlockTableRecord = tm.GetObject(bt(BlockTableRecord.ModelSpace), OpenMode.ForRead, False)
Dim id As ObjectId
For Each id In btr
If id.ObjectClass.Name = "AecDbSpace" Then
dbobj = tm.GetObject(id, OpenMode.ForRead, False, False)
Dim spobj As ArchDbSrvcs.Space = tm.GetObject(id, OpenMode.ForRead, False, False)
Dim spceStyle As ArchDbSrvcs.SpaceStyle = tm.GetObject(spobj.StyleId, OpenMode.ForRead, False, False)
If spceStyle.Name = "Block" Then
'Dim values As System.Collections.ArrayList = GetValueFromPropertySetByName(psetname, pname, dbobj)
'Dim value_unit As AecPropDb.PropertyValueUnitPair
'For Each value_unit In values
' Dim currentValue As Object = value_unit.Value
' If Not currentValue Is Nothing Then
' If (currentValue.GetType() Is GetType(Double)) Then
Dim trans2 As Transaction = tm.StartTransaction()
dbobj.UpgradeOpen()
Dim WasChanged As Boolean = SetValueFromPropertySetByName(psetname, pname, dbobj, NewValue)
If WasChanged Then
ed.WriteMessage(vbCrLf + "Succesfully changed value for objectId = " + id.ToString())
ed.WriteMessage(vbCrLf + " New Value = " + NewValue.ToString())
Else
ed.WriteMessage(vbCrLf + "Failed to change value for objectId = " + id.ToString())
End If
trans2.Commit()
trans2.Dispose()
' End If
'End If
End If
End If
Next
'Next
trans.Commit()
trans.Dispose()
End Sub
#End Region
#Region "SetValueFromPropertySetByName"
' <summary>
' Sets the values (PropertyValueUnitPair) of a property by name on a given object.
' </summary>
' <param name="pname">The property name to find on the object.</param>
' <param name="dbobj">The object to set the property on. </param>
' <param name="value">The value to set. </param>
' <returns> true if succesful, or false otherwise. </returns>
Public Function SetValueFromPropertySetByName(ByVal psetname As String, ByVal pname As String, ByVal dbobj As AcadDb.DBObject, ByVal NewValue As Object) As Boolean
Dim findany As Boolean = False
Dim setIds As ObjectIdCollection = AecPropDb.PropertyDataServices.GetPropertySets(dbobj)
Dim db As Database = HostApplicationServices.WorkingDatabase
Dim tm As AcadDb.TransactionManager = db.TransactionManager
Dim trans As Transaction = tm.StartTransaction()
Dim psId As ObjectId
For Each psId In setIds 'setids is all property sets
Dim pset As AecPropDb.PropertySet = tm.GetObject(psId, OpenMode.ForWrite, False, False) ' As AecPropDb.PropertySet
If pset.PropertySetDefinitionName = psetname Then
Dim pid As Integer 'have to create this object to place the PropertyNameToId somewhere
pid = pset.PropertyNameToId(pname) 'propertynametoid gives the id for the psetdef
If (pset.IsWriteEnabled) Then
pset.SetAt(pid, NewValue)
End If
findany = True
'esential findany changes the value of the function
End If
Next
trans.Commit()
trans.Dispose()
Return findany
End Function
#End Region
End Class