TheSwamp
Code Red => .NET => Topic started by: Helsinki_Dave on April 29, 2011, 09:06:19 AM
-
Hi, I'm working with ACA and vb.net, could anyone clarify the Object Browser info given below.
Public Shared Function GetClassification(ByVal entity As Autodesk.Aec.DatabaseServices.Entity, ByVal classificationDefinitionId As Autodesk.AutoCAD.DatabaseServices.ObjectId) As Autodesk.AutoCAD.DatabaseServices.ObjectId
Member of: Autodesk.Aec.DatabaseServices.ClassificationDefinition
Summary:
Get an entity's classification for a specific classification definition.
Parameters:
entity: The entity.
classificationDefinitionId: The classification definition.
Return Values:
Returns an entity's classification for a specific classification definition.
Exceptions:
Autodesk.AutoCAD.Runtime.Exception: Autodesk.AutoCAD.Runtime.Exception.
I think that what this is saying here is that I need to isolate an entity (which the classifcation is attached to - which is my case is a AecDbSpace. Then I need to add to this isolate the Object ID for the classfication that I'm want to read.
What I'm not sure about is if I have the AecDbSpace ObjectID, how do I turn this into an entity or are they in effect, the same kind of thing. Currently my code is not reading any classfications in the count property (spobj.Classifications.Count) when I just use a straight objectID - where there should be four classfications available on these AecDbSpace objects.
The mere fact that Intellisense gave me the option of writing spobj.Classifications suggests to me that MSExpress considers spobj to be an Entity - so maybe I have got this right - which then would mean that I'm using the wrong Entity to create a collection of classifications from.
Thanks in advance!
#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_Blocks
#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 = 0
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 c_classf As ClassificationCollection = spobj.Classifications
'Dim Clasf_Entity As Autodesk.Aec.DatabaseServices.Entity = CType(tm.GetObject(dbobj, OpenMode.ForRead, True), Autodesk.Aec.DatabaseServices.Entity)
'Dim target_clasf As Autodesk.Aec.DatabaseServices.ClassificationDefinition = ClassificationDefinition.GetClassification(Clasf_Entity)
'GetClassification(ByVal entity As Autodesk.Aec.DatabaseServices.Entity, ByVal classificationDefinitionId As Autodesk.AutoCAD.DatabaseServices.ObjectId) As Autodesk.AutoCAD.DatabaseServices.ObjectId
If c_classf.Count <> 0 Then
Dim classf_category As String = c_classf(0).ToString
End If
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())
NewValue = NewValue + 1
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 "GetValueFromPropertySetByName"
' <summary>
' Returns the value (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 GetValueFromPropertySetByName(ByVal psetname As String, ByVal pname As String, ByVal dbobj As AcadDb.DBObject) As ArrayList
Dim setIds As ObjectIdCollection = AecPropDb.PropertyDataServices.GetPropertySets(dbobj) 'this is almost like a count in that it is counting the number of psets attached to dbobj
Dim values As System.Collections.ArrayList = New System.Collections.ArrayList() 'this sets up the collector that is returned by the function
If setIds.Count = 0 Then
Return values
End If
'at this point, where setIds.count <> 0, then we know that we have property set attached
Dim db As Database = HostApplicationServices.WorkingDatabase
Dim tm As AcadDb.TransactionManager = db.TransactionManager
Dim psId As ObjectId
Dim local_psetName As String
'this is searching every property set looking for a single category - no need!! It may only cycle through 3 psets
For Each psId In setIds
'opens the propertyset found at psid in setid (where setid is the collection of psets on the dbobj) - so this is cycle one
Dim pset As AecPropDb.PropertySet = tm.GetObject(psId, OpenMode.ForRead, False, False) 'As AecPropDb.PropertySet
local_psetName = pset.PropertyIdToName(0)
Try
local_psetName = psetname 'this needs to true or else it goes to the catch
Dim psetdef_id As Integer
Try
'clever this - there is no cycling since pset is a collection and you can hunt down a name directly
'here it hunts down the pname
psetdef_id = pset.PropertyNameToId(pname)
'values is an arraylist since it holds any text or integer date - otherwise the function would have trouble returning a value
values.Add(pset.GetValueAndUnitAt(psetdef_id))
Catch e As Autodesk.AutoCAD.Runtime.Exception
' most likely eKeyNotfound.
End Try
Catch e As Autodesk.AutoCAD.Runtime.Exception
' most likely eKeyNotfound.
End Try
Next
Return values
End Function
#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) 'note the SetAt...this is vital where all factors are in place ie <pset> <pid> and <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
-
. . .
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)
. . .
I'm not a VB.NET guy so take this for what it's worth.
One thing I see is that you are using TransactionManger (tm) to get your object.
You should be using the running Transaction (trans) instead.
-
Not quit sure what you are asking but a Space 'is a' Autodesk.Aec.DatabaseServices.Entity.
It derives(Inheritance) from a Entity.
Have you ever wondered how GetObject returns a DBObject but is used for so many objects?
-
Not sure what you after but here is a way to list all the space classifications
<CommandMethod("Classifications")> _
Public Sub Classifications()
Dim doc As Document = Application.DocumentManager.MdiActiveDocument
Dim db As Database = doc.Database
Dim ed As Editor = doc.Editor
Using trx As Transaction = db.TransactionManager.StartTransaction()
Dim classDefDictionary As New DictionaryClassificationDefinition(db)
Dim objectIds As Autodesk.AutoCAD.DatabaseServices.ObjectIdCollection = classDefDictionary.Records
For Each objId As ObjectId In objectIds
Dim classDef As ClassificationDefinition = trx.GetObject(objId, OpenMode.ForRead)
If classDef.AppliesToFilter.Contains("AecDbSpace") Then
ed.WriteMessage(vbCrLf & classDef.Name)
GetClassifications(classDef.ClassificationTree)
End If
Next
trx.Commit()
End Using
End Sub
Public Sub GetClassifications(ByRef classTree As ClassificationTree)
Dim doc As Document = Application.DocumentManager.MdiActiveDocument
Dim db As Database = doc.Database
Dim ed As Editor = doc.Editor
Using trx As Transaction = db.TransactionManager.StartTransaction()
If classTree Is Nothing Then
Exit Sub
End If
If Not classTree.Id.IsNull Then
Dim clasfction As Classification = trx.GetObject(classTree.Id, OpenMode.ForRead)
ed.WriteMessage("---" & vbCrLf & clasfction.Name)
End If
If classTree.Children.Count > 0 Then
For Each cTree As ClassificationTree In classTree.Children
GetClassifications(cTree)
Next
End If
trx.Commit()
End Using
End Sub
-
Sorry guys,
Hi Jeff,
sorry for off-topic
Can you test on your machine:
use StartOpenCloseTransaction instead of StarTransaction
and remove for this object 'using' and 'commit'
(for my own interest)
Oleg
edit kdub: change textColor
-
Thanks a million for the reply Jeff. (ja hauska nähdä Fixo!)
You've clearly found your way around the ACA API! I didn't manage to find any examples about Classfications in AU or the like, so its great to see one in action. It works fine!
My main gist is to find the classfication of a AecDbSpace object. The name of the classfication is Category. If the Category is "Block", then I move on to further code. This can't be done in VBA as Classifications were not exposed, and as you can see in the attached file, we got around this by pulling the classification value into a Property Set definition then reading it from there. This creates other problems further down the chain.
I had hoped it would be as easy as something like this:
Dim spobj As ArchDbSrvcs.Space = tm.GetObject(id, OpenMode.ForRead, False, False)
Dim c_classf As ClassificationCollection = spobj.Classifications
onto which I could use something like GetClassification function and then read it. But the above code returns a big fat zero in the count property..even though there are a number of classfications.
-
Sorry guys,
Hi Jeff,
sorry for off-topic
Can you test on your machine:
use StartOpenCloseTransaction instead of StarTransaction
and remove for this object 'using' and 'commit'
(for my own interest)
Oleg
edit kdub: change textColor
The transaction should be passed in instead creating 157 transaction, but will test and see what happens
-
Thanks a million for the reply Jeff. (ja hauska nähdä Fixo!)
You've clearly found your way around the ACA API! I didn't manage to find any examples about Classfications in AU or the like, so its great to see one in action. It works fine!
My main gist is to find the classfication of a AecDbSpace object. The name of the classfication is Category. If the Category is "Block", then I move on to further code. This can't be done in VBA as Classifications were not exposed, and as you can see in the attached file, we got around this by pulling the classification value into a Property Set definition then reading it from there. This creates other problems further down the chain.
I had hoped it would be as easy as something like this:
Dim spobj As ArchDbSrvcs.Space = tm.GetObject(id, OpenMode.ForRead, False, False)
Dim c_classf As ClassificationCollection = spobj.Classifications
onto which I could use something like GetClassification function and then read it. But the above code returns a big fat zero in the count property..even though there are a number of classfications.
I had a little help
-
I had a little help
..aha, a Beetles fan.
I'll post back here when I've found a solution to the reading Classifications on a single entity. Thanks again for your help.
-
Sorry guys,
Hi Jeff,
sorry for off-topic
Can you test on your machine:
use StartOpenCloseTransaction instead of StarTransaction
and remove for this object 'using' and 'commit'
(for my own interest)
Oleg
edit kdub: change textColor
The transaction should be passed in instead creating 157 transaction, but will test and see what happens
Thanks Jeff,
that make a sense
Oleg
-
My main gist is to find the classfication of a AecDbSpace object. The name of the classfication is Category. If the Category is "Block", then I move on to further code. This can't be done in VBA as Classifications were not exposed, and as you can see in the attached file, we got around this by pulling the classification value into a Property Set definition then reading it from there.
Disregarding my very limited experience in ACA automation, this looks fine to me.
This creates other problems further down the chain.
How? To use the classification as a tag in an annotation object would require that very procedure too.
I had hoped it would be as easy as something like this:
Dim spobj As ArchDbSrvcs.Space = tm.GetObject(id, OpenMode.ForRead, False, False)
Dim c_classf As ClassificationCollection = spobj.Classifications
It is, but only for values explicitly supplied; not for defaults by style.
If I get the thrust of your code and your sample drawing correctly, there are 7 spaces that meet your criteria, and, incidentally, one of them has a space style named "Block". You want them renumbered. My approach ain't pretty and is probably written in a sinister language, but here goes:
open Autodesk.AutoCAD.DatabaseServices
open Autodesk.AutoCAD.Runtime
open Autodesk.AutoCAD.Geometry
open Autodesk.AutoCAD.ApplicationServices
open Autodesk.AutoCAD.EditorInput
open Autodesk.Aec.DatabaseServices
open Autodesk.Aec.Arch.DatabaseServices
open Autodesk.Aec.PropertyData.DatabaseServices
[<CommandMethod "koe">]
let koeCmd() =
let doc = Application.DocumentManager.MdiActiveDocument
let db = doc.Database
let ed = doc.Editor
use tr = db.TransactionManager.StartTransaction()
let blkPSetName = "Block_properties"
let blkPName = "Block_ID"
let catPSetName = "Object_category"
let catPName = "Category"
let pSetDefs = new DictionaryPropertySetDefinitions(db)
let tryGetAt pSetName =
if pSetDefs.Has(pSetName, tr) then pSetDefs.GetAt pSetName
else ObjectId.Null
let blkPSetDefId = tryGetAt blkPSetName
let catPSetDefId = tryGetAt catPSetName
if blkPSetDefId.IsNull || catPSetDefId.IsNull then
ed.WriteMessage(
"\nEither PropertySetDefinition {0} or PropertySetDefinition {1} missing from drawing. ",
blkPSetName, catPSetName )
else
let bt = tr.GetObject(db.BlockTableId, OpenMode.ForRead, false) :?> BlockTable
let btr = tr.GetObject(bt.[BlockTableRecord.ModelSpace], OpenMode.ForRead, false) :?> BlockTableRecord
let mutable newValue = 0
for oid in btr do
if oid.ObjectClass.Name = "AecDbSpace" then
let spc = tr.GetObject(oid, OpenMode.ForRead, false, false) :?> Space
let tryGetPSetId pSetDefId =
try PropertyDataServices. GetPropertySet(spc, pSetDefId) with _ -> ObjectId.Null
let blkPSetId = tryGetPSetId blkPSetDefId
let catPSetId = tryGetPSetId catPSetDefId
if blkPSetId.IsNull || catPSetId.IsNull then
ed.WriteMessage(
"\n{0} has no Property Set {1} or {2}. ",
spc.Name, blkPSetName, catPSetName )
else
let blkPSet = tr.GetObject(blkPSetId, OpenMode.ForWrite, false, false) :?> PropertySet
let catPSet = tr.GetObject(catPSetId, OpenMode.ForRead, false, false) :?> PropertySet
let blkPId = blkPSet.PropertyNameToId blkPName
let catPId = catPSet.PropertyNameToId catPName
let cat = catPSet.GetAt catPId :?> string
if cat <> "Block" then
ed.WriteMessage("\n{0} has Category {1}. ", spc.Name, cat)
else
blkPSet.SetAt(blkPId, newValue)
ed.WriteMessage(
"\nSuccesfully changed value for {0}, new value = {1} ",
spc.Name, newValue )
newValue <- newValue + 1
tr.Commit()
-
Thanks for the posting kaefer , brilliant actually. I'll plug this is and see if any lights come on.
-
My only comment would be - if your going to process that much stuff, you might consider not using a transaction at all. Performance might become an issue.
-
How? To use the classification as a tag in an annotation object would require that very procedure too.
Just thought I should get back to a few of these questions, just in case you thought I'ld gone to sleep.
ACA has this problem when inserting AecDbSpaces via a customised toolbar - in that it automatically attaches every single property set that it can find that is relevant to 'Spaces. This means that you then need a bit of VBA that determines the type of object it is (ie, building, city block, surface etc) as well as checking that every 'Space has the right PropertySet attached (ie if during editing somebody accidentily removed a property set attached ByObject)
That last point is the problem, to check if you have the right PropertySet attached, you need to know what kind of object it is, and to know what kind of object it is, you need to know the Classification ("Category") - BUT, VBA can't read classifications, nor can it read PropertySets that are attached ByStyle. So there's not an immediate automatic answer. You can't just read the stylename since as you build up the options of Classifications (inside site area or not, use of building etc) the stylename becomes irrelevant.
We get around this by first attaching a kind of 'what am i' property set, then using that to direct what the correct PropertySet should be. To blocks go Block _Properties propertyset and to Buildings go Building_Propoerties property set.
I noticed that Kaefers code is in F#. I'll give it a crack to bring it back to VB but it's looking ugly.
-
Not sure what you after but here is a way to list all the space classifications
I can see that I'm all at sea with this...my question wasn't clear. Apologies for this - I'm not looking to waste anyones time.
Is there a way to find the value of a single classficiation on a single entity (in the file above, an Enity could be a Building or a Cityblock. It appears that I can use the Function that I list below..but I'm struggling. I'll try to use Jeff's kindly donated code to grab a classificationDefinitionId as it appears in the db. Maybe that will work. Thanks in advance for your thoughts.
Public Shared Function GetClassification(ByVal entity As Autodesk.Aec.DatabaseServices.Entity, ByVal classificationDefinitionId As Autodesk.AutoCAD.DatabaseServices.ObjectId) As Autodesk.AutoCAD.DatabaseServices.ObjectId
Member of: Autodesk.Aec.DatabaseServices.ClassificationDefinition
Summary:
Get an entity's classification for a specific classification definition.
Parameters:
entity: The entity.
classificationDefinitionId: The classification definition.
Return Values:
Returns an entity's classification for a specific classification definition.
-
Well, I went back to some code that Jeff put out some place; I thought it might clarify the problem in my head and with you guys.
I believe that what is below will get a single Classification on a single Entity (thanks Jeff) but what I can't understand is how to pull a value off this. I can get as far as finding the ObjectID of exactly one classification on exactly one entity. Very cool.
But now it is not clear to me how to find the assigned value of the Classification. This value is assigned within ACA by the user. As you know, there is no such thing as ObjectID.Value
To be concise - how can I can determine what Category each AecDbSpace has. I can get each AecDbSpace's 'Category', but I can't see where I can read what the actual Category is (eg Building, Block etc)
'many thanks to Jeff H
Imports System
Imports Autodesk.AutoCAD.Runtime
Imports Autodesk.AutoCAD.ApplicationServices
Imports Autodesk.AutoCAD.DatabaseServices
Imports Autodesk.AutoCAD.Geometry
Imports Autodesk.AutoCAD.EditorInput
Imports ObjectId = Autodesk.AutoCAD.DatabaseServices.ObjectId
Imports AecDbSrvcs = Autodesk.Aec.DatabaseServices
Imports ArchDbSrvcs = Autodesk.Aec.Arch.DatabaseServices
Imports Autodesk.Aec.PropertyData.DatabaseServices
Imports Autodesk.Aec.DatabaseServices
<Assembly: CommandClass(GetType(MEPExamplesVB.MyCommands))>
Namespace MEPExamplesVB
Public Class MyCommands
<CommandMethod("GetSpaceDataVB")> _
Public Sub GetSpaceDataVB()
Dim doc As Document = Application.DocumentManager.MdiActiveDocument
Dim db As Database = doc.Database
Dim ed As Editor = doc.Editor
Using trx As Transaction = db.TransactionManager.StartTransaction()
Dim mdlSpace As BlockTableRecord = SymbolUtilityServices.GetBlockModelSpaceId(db).GetObject(OpenMode.ForRead)
For Each objId As ObjectId In mdlSpace
If objId.ObjectClass.Name = "AecDbSpace" Then
Dim spce As ArchDbSrvcs.Space = trx.GetObject(objId, OpenMode.ForRead)
Dim Ret_TClass As ObjectId = GetClassifID("Category")
Dim RetrClassID As ObjectId = Autodesk.Aec.DatabaseServices.ClassificationDefinition.GetClassification(spce, Ret_TClass)
'I dont what to do from here. I need to find the value of this Classficiation.
Dim spceStyle As ArchDbSrvcs.SpaceStyle = trx.GetObject(spce.StyleId, OpenMode.ForRead)
'ed.WriteMessage(String.Format("{0}This Space Name: {1} Area: {2} and is on Stlye?: {3}", _
'vbCrLf, spce.Name, spce.Area, spceStyle.Name))
Dim spc_ownerID As ObjectId = spce.OwnerId
If spc_ownerID.ObjectClass.Name = "AecDbSpace" Then
Dim plg As AecDbSrvcs.Polygon = trx.GetObject(spc_ownerID, OpenMode.ForRead)
End If
End If
Next
End Using
End Sub
#Region "GetClassficationId"
'we need to
'takes the AecDbSpace object <id>
'takes the ClassficiationName <TargClasName>
'returns the objectid for the targeted classification
Public Function GetClassifID(ByVal TargClasName As String) As ObjectId
Dim doc As Document = Application.DocumentManager.MdiActiveDocument
Dim db As Database = doc.Database
Dim TargetClassID As ObjectId
Dim ed As Editor = doc.Editor
Using trx As Transaction = db.TransactionManager.StartTransaction()
Dim classDefDictionary As New DictionaryClassificationDefinition(db)
Dim objectIds As Autodesk.AutoCAD.DatabaseServices.ObjectIdCollection = classDefDictionary.Records
For Each objId As ObjectId In objectIds
Dim classDef As ClassificationDefinition = trx.GetObject(objId, OpenMode.ForRead)
If classDef.AppliesToFilter.Contains("AecDbSpace") Then
'ed.WriteMessage(vbCrLf & classDef.Name)
If classDef.Name = TargClasName Then
TargetClassID = classDef.ObjectId
'GetClassifications(classDef.ClassificationTree)
End If
End If
Next
trx.Commit()
End Using
Return TargetClassID
End Function
#End Region
End Class
End Namespace
-
This is probably not the best way I was just looking at it with AECMgd and the function you were trying to use.
Since the classifications are set with style it seems there will be a easy way to grab it using the style.
Here is what this does it searches the DictionaryClassificationDefinition for "Category" and once found assigns the ObjectID to a variable that will be used as ClassificationDefinition ID.
Then it iterates through model space and if it is a space object it gets the classification using GetClassification() with the space object and ClassificationDefinition ObjectId as its arguments
<CommandMethod("GetClassificationWithDefinition")> _
Public Sub GetClassificationWithDefinition()
Dim doc As Document = Application.DocumentManager.MdiActiveDocument
Dim db As Database = doc.Database
Dim ed As Editor = doc.Editor
Dim classficationDefId As ObjectId
Using trx As Transaction = db.TransactionManager.StartTransaction()
Dim classDefDictionary As New DictionaryClassificationDefinition(db)
Dim objectIds As Autodesk.AutoCAD.DatabaseServices.ObjectIdCollection = classDefDictionary.Records
For Each objId As ObjectId In objectIds
Dim classDef As ClassificationDefinition = trx.GetObject(objId, OpenMode.ForRead)
If classDef.Name = "Category" Then
classficationDefId = classDef.ObjectId
Exit For
End If
Next
Dim mdlSpace As BlockTableRecord = SymbolUtilityServices.GetBlockModelSpaceId(db).GetObject(OpenMode.ForRead)
For Each objId As ObjectId In mdlSpace
If objId.ObjectClass.Name = "AecDbSpace" Then
Dim spce As ArchDbSrvcs.Space = trx.GetObject(objId, OpenMode.ForRead)
Dim cls As Classification = trx.GetObject(ClassificationDefinition.GetClassification(spce, classficationDefId), OpenMode.ForRead)
ed.WriteMessage(String.Format("{0}This Classification is: {1} ", vbCrLf, cls.Name))
End If
Next
trx.Commit()
End Using
End Sub
Output from your drawing
This Classification is: Block
This Classification is: Block
This Classification is: Block
This Classification is: Block
This Classification is: Block
This Classification is: Block
This Classification is: Building
This Classification is: Building
This Classification is: Building
This Classification is: Building
This Classification is: Building
This Classification is: Building
This Classification is: Building
This Classification is: Building
This Classification is: Building
This Classification is: Building
This Classification is: Building
This Classification is: Building
This Classification is: Building
This Classification is: Building
This Classification is: Building
This Classification is: Building
This Classification is: Building
This Classification is: Building
This Classification is: Building
This Classification is: Building
This Classification is: Building
This Classification is: Building
This Classification is: Block
This Classification is: Block
-
Gents,
It works.
with many thanks to mohnston, kaefer and special thanks to Jeff H