Extract Item types attached to models with VBA

Hi

I'm trying to extract item type property values from my active file's models trough VBA.

I've edited the item type property value I'm trying to extract so it's different in all models, but I seem to often end up with the same value for all models, although I sometimes get some of the different values printed correctly. What could I be doing wrong?

Sub FindItemsFromModelReference3()

    Dim oItemLibs As ItemTypeLibraries
    Dim oItemLib As ItemTypeLibrary
    Dim oItem As ItemType
    Dim oItemPropHandler As ItemTypePropertyHandler
    Dim tests As String
    Dim oItems As Items
    Dim Success As Boolean
    Dim mdl As ModelReference
    
    For Each mdl In ActiveDesignFile.Models
        Debug.Print mdl.Name
    Set oItems = mdl.Items
    oItems.Refresh ("Ritningsinfo")
    Do
        Set oItemPropHandler = oItems.Find("Ritningsinfo", "Stämpel", oItemPropHandler)
        If oItemPropHandler Is Nothing Then
        Exit Do
        Else
        Debug.Print oItemPropHandler.GetPropertyValue("Rad 2")
        End If
    Loop
    Next
End Sub

I'm running Openbuildings designer connect edition update 5. 

Regards, 

Robert

  • Can you provide a simple DGN file so that we can test your sample code?

     
    Regards, Jon Summers
    LA Solutions

  • I'll attach a file here. I played around with this yesterday after I wrote this post, and after a while it actually worked, it showed me the correct values of all the item types. 

    I tried again this morning, and it's back to where I was yesterday.

    ritdef.dgn

  • it showed me the correct values of all the item types

    I wrote some similar code, but get inconsistent results.  Sometimes it gets the values, sometimes it doesn't, and sometimes it crashes MicroStation.

    GetItemTypesFromModels-modMain.zip

     
    Regards, Jon Summers
    LA Solutions

  • Hi Robert,

    I spent some time playing with own code and your design file and it seems there is a bug (in fact there are many bugs in VBA ItemTypes API). Not sure, but maybe it relates also to problem with names with spaces, discussed here in relation to normal PropertyHandler.

    My code is quite defensive to ensure everything is checked (I even add model activation to ensure everything is initialized properly), but it shows that ItemTypePropertyHandler does not work (at least for"Rad 2" with spaces), but when PropertyHandler internal access string is used, results are correct:

    Option Explicit
    
    Const ItemTypeLibraryName As String = "Ritningsinfo"
    Const ItemTypeName As String = "Stämpel"
    Const testItemName As String = "Rad 2"
    Const testAccessString As String = "Rad__x0020__2"
    
    Public Sub StartMacro()
    
        MessageCenter.AddMessage "----- model iteration -----", vbNullString, msdMessageCenterPriorityNone, False
        
        Dim model As ModelReference
        
        For Each model In ActiveDesignFile.Models
            model.Activate
            ProcessModel ActiveModelReference
        Next
    
    End Sub
    
    Private Sub ProcessModel(model As ModelReference)
    
        MessageCenter.AddMessage "Model processed: " & model.Name, vbNullString, msdMessageCenterPriorityInfo, False
    
        Dim itemLibraries As New ItemTypeLibraries
        Dim itemLibrary As ItemTypeLibrary
        
        Set itemLibrary = itemLibraries.FindByName(ItemTypeLibraryName)
        
        If itemLibrary Is Nothing Then
            MessageCenter.AddMessage "ItemType library " & ItemTypeLibraryName & " was not found", vbNullString, msdMessageCenterPriorityError, False
            Exit Sub
        End If
        
        Dim item As ItemType
        Set item = GetItemOrNothing(itemLibrary, ItemTypeName)
        
        If item Is Nothing Then
            MessageCenter.AddMessage "ItemType " & ItemTypeName & " was not found", vbNullString, msdMessageCenterPriorityError, False
            Exit Sub
        End If
        
        Dim propertyCount As Long
        propertyCount = item.GetPropertyCount
        
        model.Items.Refresh ItemTypeLibraryName
        
        ' Using ItemTypePropertyHandler does not work
        
        Dim itPropertyHandler As ItemTypePropertyHandler
        Set itPropertyHandler = model.Items.Find(ItemTypeLibraryName, ItemTypeName, itPropertyHandler)
        
        If itPropertyHandler Is Nothing Then
            MessageCenter.AddMessage "ItemType " & ItemTypeName & " is not attached to a model", vbNullString, msdMessageCenterPriorityError, False
            Exit Sub
        End If
        
        Dim itemValue As Variant
        itemValue = itPropertyHandler.GetPropertyValue(testItemName)
        MessageCenter.AddMessage "Item property " & testItemName & " : " & itemValue, vbNullString, msdMessageCenterPriorityInfo, False
        
        ' Using PropertyHandler works
        Dim ph As PropertyHandler
        Set ph = CreatePropertyHandler(model)
        
        Dim propertyValue As Variant
        ph.SelectByAccessString (testAccessString)
        propertyValue = ph.GetValue
        
        MessageCenter.AddMessage "Property value (" & testAccessString & ") : " & propertyValue, vbNullString, msdMessageCenterPriorityInfo, False
    
    End Sub
    
    Private Function GetItemOrNothing(library As ItemTypeLibrary, itemName As String) As ItemType
        On Error GoTo ItemNotFoundErrorHandler
            Set GetItemOrNothing = library.GetItemTypeByName(itemName)
            Exit Function
        On Error GoTo 0
            
    ItemNotFoundErrorHandler:
        Set GetItemOrNothing = Nothing
        Exit Function
    End Function
    
    

     can you please check the code and log the defect?

    BTW ItemType.GetPropertyById seems also not work.

    ... I am surprised how many bugs in VBA API exists, it looks like there is not any testing implemented. Because of that, I am curious how examples in VBA documentation can be written when API does not work.

    With regards,

      Jan

  • it shows that ItemTypePropertyHandler does not work (at least for"Rad 2" with spaces), but when PropertyHandler internal access string is used, results are correct
    Const testAccessString As String = "Rad__x0020__2"

    Good detective work! While C++ and C# developers are provided with methods to get an EC or Item Type internal name (access string), VBA developers should be insulated from those details.

    I am surprised how many bugs in VBA API exists, it looks like there is not any testing implemented

    I suspect that the developers have no experience of the freedom that VBA provides.  Consequently, they fail to anticipate that sort of problem:  Internally, the C++ code that VBA wraps should translate from user name (Rad 2) to internal name (Rad__x0020__2).

     
    Regards, Jon Summers
    LA Solutions

  • Good detective work!

    Thanks :-)

    Unfortunately a cost is several hours of "it would be simple ... it should work ... why it does not work" testing and the result is that specialized API is crappy, but fortunately good old PropertyHandler works (but access strings are weird for VBA developers often).

    I suspect that the developers have no experience of the freedom that VBA provides.

    My feeling is that nobody test APIs, because there are no resources and budge to do it. I agree it's boring and time consuming effort where results are not visible (and despite of there is profession / specialization "API tester", it's typically aimed more to web API). But so many bugs found in all APIs look to me more like "we hope it works".

    Have a nice weekend,

      Jan

  • Hi. Thank you very much for looking in to this. I'm quite knew to VBA and programing over all, so don't really follow all of the above, but it's to bad there's lots of bugs.