I'm looking for a way to enumerate the list of properties defined in an Item Type using VBA. The following code works correctly but requires me to hard-code the property name rather than extract it from the item type definition:
Sub UpdateCellItemType() Dim oItemLibs As ItemTypeLibraries Dim oItemLib As ItemTypelibrary Dim oItem As ItemType Dim oItemPropHandler As ItemTypePropertyHandler Dim cellEl As CellElement Dim oScanCriteria As ElementScanCriteria Dim oScanEnumerator As ElementEnumerator ' get item type definition Set oItemLibs = New ItemTypeLibraries Set oItemLib = oItemLibs.FindByName("Upgraded Tag Sets") Set oItem = oItemLib.GetItemTypeByName("0-TTL-A1-NTA") ' init scanner Set oScanCriteria = New ElementScanCriteria oScanCriteria.ExcludeAllTypes oScanCriteria.IncludeType msdElementTypeCellHeader ' process cells Set oScanEnumerator = ActiveModelReference.Scan(oScanCriteria) Do While oScanEnumerator.MoveNext Set cellEl = oScanEnumerator.Current ' get cell itemType instance Set oItemPropHandler = oItem.FindItem(cellEl) ' update itemtype property If Not (oItemPropHandler Is Nothing) Then oItemPropHandler.SetPropertyValue "Prop Name", "Prop Value" End If Loop ' update all fields CadInputQueue.SendKeyin "FIELD UPDATE ALL" End Sub
Hi Benzi,
Benzi Papo said:I'm looking for a way to enumerate the list of properties defined in an Item Type using VBA.
I think you have to, for every element:
It is not very intuitive (moreover, implementation in VBA makes the process more complex than it is in other APIs), but it is simpler than it looks ;-)
Unfortunately, I am not aware of example (e.g. in MicroStation VBA documentation), illustrating this process.
With regards,
Jan
Bentley Accredited Developer: iTwin Platform - AssociateLabyrinth Technology | dev.notes() | cad.point
Thanks Jan. It would be a great enhancement to allow the Item Type Import/Export command to process ALL item instances in the design file.
At this time the Import/Export can process only item type instances in the active model using the ElementId field. So updating multiple models is inefficient and time consuming. This is especially critical when updating title cells in multiple sheet models.
To resolve this limitation I've expanded the above VBA code and created a macro that uses an INI file to update item type properties. The item type definition is extracted using the Item Type Export command. The macro can update multiple item instances in multiple models:
Benzi Papo said:It would be a great enhancement to allow the Item Type Import/Export command to process ALL item instances in the design file
What is it that you want to achieve that you can't do using a Report?
Regards, Jon Summers LA Solutions
Benzi Papo said:It would be a great enhancement to allow the Item Type Import/Export command to process ALL item instances in the design file.
I think you should discuss it in normal MicroStation forum, and optionally to create a new Idea.
Regards,
Reports are great when you want to extract information from a design file. Engineers may need to input information and add it to design elements. This is important as projects are becoming more BIM oriented. For example, some of our road projects may have dozens of sheet models, each with it's own title cell.
Each title cell will need slightly different information in some of the item type properties. This will depend on the state of the project ( preliminary, detailed, cross sections etc. ). It is time-consuming and inefficient to manually update several dozen title cells using the Item Type editor or the Item Type import/export feature.
Benzi Papo said:but requires me to hard-code the property name rather than extract it from the item type definition:
The following code does not require to know anything about attached ItemType and ItemType properties in advance.
It is proof of concept and I treat it as dirty, badly structured, but it works find and I guess it not hard to understand it. The element is obtained using its ID only for development and testing purpose.
Dim el As Element Set el = ActiveModelReference.GetElementByID(DLongFromLong(12652)) Dim itemProps As Items Set itemProps = el.Items Dim itemTypePropHandler As ItemTypePropertyHandler Do Set itemTypePropHandler = itemProps.Find("*", "*", itemTypePropHandler) If itemTypePropHandler Is Nothing Then Exit Do Dim itemTypeLibraryName As String itemTypeLibraryName = itemTypePropHandler.LibraryName Dim itemTypeLib As ItemTypeLibrary Set itemTypeLib = ActiveDesignFile.ItemTypeLibraries.FindByName(itemTypeLibraryName) Dim itemTypeName As String itemTypeName = itemTypePropHandler.itemTypeName Dim itemTypeDef As ItemType Set itemTypeDef = itemTypeLib.GetItemTypeByName(itemTypeName) Dim propertyDef As ItemTypeProperty Do Set propertyDef = itemTypeDef.Find("*", propertyDef) If propertyDef Is Nothing Then Exit Do Dim propVal As Variant propVal = itemTypePropHandler.GetPropertyValue(propertyDef.PropertyName) Debug.Print "Library: " & itemTypeLibraryName & ", ItemType: " & itemTypeName & ", property " & propertyDef.PropertyName & " = " & CStr(propVal) Loop Loop
Answer Verified By: Benzi Papo
So indeed this was the missing piece. Thanks for the code snippet and also the ElementID suggestion which helps with code testing.
you are welcomed :-)
The code illustrates what I wrote in my first reaction: For an element, it checks what ItemType(s) is attached. Using this information, ItemType definition is read and it is the way how to obtain a list of all ItemType properties. And using the property name, it is possible to ask element data for the property value.