Does anyone know how to read classifications attached to objects using VB.NET or VBA?
I have an entire MEP project with lots and lots of MEP-objects. A classification definition that applies to the MEP objects exist in each drawing and every objects have a certain classification code.
What I need to do is to attach one specific propertyset to each MEP object. That is the easy part ... However which propertyset to attach depends on the classification code attached to the object. That is the tricky part!
The attached image refers to a wall object, but the issue is the same with MEP objects.
... hope that someone can help with this.
Regards
Jan Grenov
Solved! Go to Solution.
Solved by jan. Go to Solution.
Solved by Keith.Brown. Go to Solution.
This is the method that I use to return a classification from an object. This is part of a larger class so some of the variables are properties of the class.
Sorry, i don't code in VB.Net anymore. You can convert from C# using one of the many converters available online.
code = C#
public Classification GetClassificationOnGeo(Geo geo) { try { using (var transaction = _database.TransactionManager.TopTransaction) { if (transaction == null) { throw new Autodesk.AutoCAD.Runtime.Exception(ErrorStatus.NoActiveTransactions); } var dictionaryClassificationDefinition = new DictionaryClassificationDefinition(_database); ObjectIdCollection objectIds = dictionaryClassificationDefinition.Records; foreach (ObjectId objId in objectIds) { using ( var classificationDefinition = transaction.GetObject(objId, OpenMode.ForRead) as ClassificationDefinition) { if (classificationDefinition != null) { if (classificationDefinition.Name.Equals(_styleName, StringComparison.OrdinalIgnoreCase)) { ObjectId classificationDefinitionId = classificationDefinition.ObjectId; using ( var classification = transaction.GetObject( ClassificationDefinition.GetClassification(geo, classificationDefinitionId), OpenMode.ForRead) as Classification) { if (classification != null) { return classification; } } } } } } } return null; } catch (Exception) { return null; } }
You can modify that method to be more generic and returning the name of the classification by doing something like this:
public string GetClassificationOnGeo(Database database, Geo geo, string styleName) { try { using (var transaction = database.TransactionManager.TopTransaction) { if (transaction == null) { throw new Autodesk.AutoCAD.Runtime.Exception(ErrorStatus.NoActiveTransactions); } var dictionaryClassificationDefinition = new DictionaryClassificationDefinition(database); ObjectIdCollection objectIds = dictionaryClassificationDefinition.Records; foreach (ObjectId objId in objectIds) { using ( var classificationDefinition = transaction.GetObject(objId, OpenMode.ForRead) as ClassificationDefinition) { if (classificationDefinition != null) { if (classificationDefinition.Name.Equals(styleName, StringComparison.OrdinalIgnoreCase)) { ObjectId classificationDefinitionId = classificationDefinition.ObjectId; using ( var classification = transaction.GetObject( ClassificationDefinition.GetClassification(geo, classificationDefinitionId), OpenMode.ForRead) as Classification) { if (classification != null) {
transaction.commit(); return classification.name; } } } } } } } return string.Empty; } catch (Exception) { return string.Empty; } }
There was an error in the first block of code that I posted.
I had wrapped transaction to get the classification of the object inside a using statement. When I returned the classification it went out of scope and then became null. the using statement should be removed and let the calling function deal with the disposal of the classification.
The new code becomes:
public Classification GetClassificationOnGeo(Geo geo) { try { using (var transaction = _database.TransactionManager.TopTransaction) { if (transaction == null) { throw new Autodesk.AutoCAD.Runtime.Exception(ErrorStatus.NoActiveTransactions); } var dictionaryClassificationDefinition = new DictionaryClassificationDefinition(_database); ObjectIdCollection objectIds = dictionaryClassificationDefinition.Records; foreach (ObjectId objId in objectIds) { using ( var classificationDefinition = transaction.GetObject(objId, OpenMode.ForRead) as ClassificationDefinition) { if (classificationDefinition != null) { if (classificationDefinition.Name.Equals(_styleName, StringComparison.OrdinalIgnoreCase)) { ObjectId classificationDefinitionId = classificationDefinition.ObjectId; var classification = transaction.GetObject( ClassificationDefinition.GetClassification( geo,classificationDefinitionId ), OpenMode.ForRead ) as Classification); if (classification != null) { return classification; } } } } } } return null; } catch (Exception) { return null; } }
Thanks Keith
I am having no trouble with reading C# so that will do just fine.
I will try out your code and let you know how it goes.
🙂
Hi Keith
It worked just fine 🙂 Thanks a lot. This really was a great help!
Here is my code as it looks in VB.NET:
Public Function GetClassificationOnGeo(Geo As Geo) As Classification
Dim db As Database = Geo.Database
Try
Using tr As Transaction = db.TransactionManager.TopTransaction
If tr IsNothingThen
ThrowNew Autodesk.AutoCAD.Runtime.Exception(Autodesk.AutoCAD.Runtime.ErrorStatus.NoActiveTransactions)
EndIf
Dim dictClsDef AsNew DictionaryClassificationDefinition(db)
Dim objectIds As ObjectIdCollection = dictClsDef.Records
ForEach objId As ObjectId In objectIds
Using clsDef As ClassificationDefinition = tr.GetObject(objId, OpenMode.ForRead)
If clsDef IsNotNothingThen
If clsDef.Name.Equals("AAU_SfbClassification", StringComparison.OrdinalIgnoreCase) Then
Dim classificationDefinitionId As ObjectId = clsDef.ObjectId
Dim clf As Classification = tr.GetObject(ClassificationDefinition.GetClassification(Geo, classificationDefinitionId), OpenMode.ForRead)
If clf IsNotNothingThen
Return clf
EndIf
EndIf
EndIf
End Using
Next
End Using
Catch ex As System.Exception
Return Nothing
End Try
'If the function reaches this point ...
Return Nothing
End Function
Regards
Jan Grenov
Hi!
I'm trying to compile a c# with "new DictionaryClassificationDefinition(db)", but, I have this error message:
"No se puede encontrar el tipo o el nombre de espacio de nombre 'DictionaryClassificationDefinition'.
Can you tell me the "using directives" to build it?