- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report
Anyone reading this with interest will know that this is a pretty lonely path! ACA and .NET....total size of global audience..maybe three of us ![]()
ACA is, of course, a fanatastic tool for urban design - blows the socks off Archicad (GDL anyone?), Revit (building sized projects only thanks!) and Autocad ( no location tool grip ).
But, if anyone has a few ideas about working with Styles and Property Sets, then feel free to chip in.
Question is, looking at the code below..which is kinda of stripped out from various sources..but shows the key ideas...is this really the way to access data on a propertysetdef? What I want the psetdef name and value on a certain style only...which, as we all know, is trickier than if VBA.
So to just get hold of the name of the psetdef, you need to go via ObjectIDCollection to fetch the Psets, then AecPropDB.Propertyset to fetch the the Psetdefs one by one, then use PropertyNameToId put the Property Definition into another variable, then use GetValueandUnitAt to put that variable into an ArrayList, then use a ValueUnitPair to pull that data into another variable, then create another final objectID (Val) which by means of val.GetType, and Val.ToString - I guess you could load those two values onto an array with two dimensions.
All I want to do is look in every single AECspace called Building in the drawing and pull off the an ID number from it and the area of the space. Seems all a little convaluted.
If anyone has a suggestion, then by all means!
Dim pname As String = "Gross_floor_area"
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) 'open up the general block table
Dim btr As BlockTableRecord = tm.GetObject(bt(BlockTableRecord.ModelSpace), OpenMode.ForRead, False) 'get every single object in the modelspace
Dim id As ObjectId
For Each id In btr
dbobj = tm.GetObject(id, OpenMode.ForRead, False, False)
'test obj for type
'Open each entity in turn using its ObjectId - only allows for AEC.database entity objects
'Dim ent As AecDb.Entity = trans.GetObject(id, Autodesk.AutoCAD.DatabaseServices.OpenMode.ForRead)
If TypeOf dbobj Is Space Then
Dim Sspace As Space = tm.GetObject(dbobj.ObjectId, OpenMode.ForRead)
Dim Sel_Space_Style As SpaceStyle = tm.GetObject(Sspace.StyleId, OpenMode.ForRead)
Select Case Sel_Space_Style.Name
Case "Building"
Dim GFA_array As System.Collections.ArrayList = GetValuesFromPropertySetByName("Gross_Floor_Area", dbobj)
Case "Block"
End Select
Dim values As System.Collections.ArrayList = GetValuesFromPropertySetByName(pname, dbobj) 'using an array list to store the psetdefs that come back from the function
Dim value_unit As AecPropDb.PropertyValueUnitPair
For Each value_unit In values
ed.WriteMessage(vbCrLf + "Property with name = " + pname + " Entity ObjectId = " + id.ToString())
'ed.WriteMessage(vbCrLf + "Unit Type = " + value_unit.UnitType.InternalName + ", IsImperial = " + value_unit.UnitType.IsImperial.ToString() + ", Type = " + value_unit.UnitType.Type.ToString())
Dim val As Object = value_unit.Value
If Not val Is Nothing Then
ed.WriteMessage(vbCrLf + "DataType = " + val.GetType().ToString())
ed.WriteMessage(vbCrLf + "Value = " + val.ToString())
End If
Next
End If
Next
trans.Commit()
trans.Dispose()
End Sub
#End Region
#End Region
#Region "ImplementationMethods"
#Region "GetValuesFromPropertySetByName"
' <summary>
' Returns 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 find the property on. </param>
' <returns> An array of the values </returns>
Public Function GetValuesFromPropertySetByName(ByVal pname As String, ByVal dbobj As AcadDb.DBObject) As System.Collections.ArrayList
Dim setIds As ObjectIdCollection = AecPropDb.PropertyDataServices.GetPropertySets(dbobj) 'use the objectidcollection- **setIds** is the pset collection!!
Dim values As System.Collections.ArrayList = New System.Collections.ArrayList() 'values is only used to pick up the psetdef name and values then returns it since its a public function
If setIds.Count = 0 Then
Return values ' just return the empty collection...since there are no propertysets attached to this aecspace object
End If
Dim db As Database = HostApplicationServices.WorkingDatabase 'why are we starting up a transaction just now, I don't know...can't this be done further out?
Dim tm As AcadDb.TransactionManager = db.TransactionManager
Dim psId As ObjectId 'use this to pin down the pset with the correct psetdef in it
For Each psId In setIds 'remember that setIds is the collection of psets
Dim pset As AecPropDb.PropertySet = tm.GetObject(psId, OpenMode.ForRead, False, False) 'you must open each pset for read as you grab it
'****bingo - pset if your object, now you can manipulate it***
Dim pid As Integer 'pid will take the id number only for the psetdef
Try 'this part hunts for pname in the propertyset - setids at this point is all you need if you just want to hunt for stylenames
pid = pset.PropertyNameToId(pname) 'propertyname refers to a psetdef no a pset
values.Add(pset.GetValueAndUnitAt(pid)) 'picks off the GFA and the value of it by integer ie PID. GetValueandUnit is a very special ACA function
'*********Dim Psetvalue As Integer = pset.PropertySetDefinitionName(pname)
Catch e As Autodesk.AutoCAD.Runtime.Exception
' most likely eKeyNotfound. in other words, the property set did not have the pname in it
End Try
Next
Return values
End Function
Solved! Go to Solution.