Remove Individual Annotation Groups

I'm working in ORD 2021 R1. Wondering if there is any way to remove individual annotation groups from the cross sections? I originally annotated all drawing models with EAV and have ultimately decided I wanted to remove it. We can add individual annotation groups to all drawing models but I don't see a way to remove individual groups, only remove all groups at once. Does anyone have a workaround for this?

Parents
  • Hi Matt,

    There is a way to do this via VBA. As every Annotation Group placement instance has a unique Named Group, you can use vba to get the Named Group from a selected element and delete all elements that are part of the same one. You could then get it to iterate through all Drawing models to delete other instances of it.

    Unfortunately no native tools for this...yet.

    Regards,

    Mark


    OpenRoads Designer 2022 R3 (10.12)  |  Microstation 2023  |  ProjectWise CE 3.4

  • The VBA code below should do what you need. To run:

    1. Select an element that was placed in the Annotation group instance you want to remove
    2. Run the macro below
    3. It will delete all elements that belonged to the same Annotation group instance in all Drawing models of the active Designfile

    Sub deleteAnnoAll()
    
        Dim oScanEnumerator As ElementEnumerator, oScanEnumerator0 As ElementEnumerator, ph As PropertyHandler
        Dim oGroupName As String, ph0 As PropertyHandler, oElement As Element, oSelected As Element, oModel As ModelReference
    
        If ActiveModelReference.Type = msdModelTypeDrawing Then
        
            For Each oModel In ActiveDesignFile.Models
                If oModel.Type = msdModelTypeDrawing Then
                    countDrawings = countDrawings + 1
                End If
            Next
            
            If ActiveModelReference.AnyElementsSelected = False Then
                CadInputQueue.SendCommand "beep"
                ShowMessage "ERROR - No elements selected", , msdMessageCenterPriorityError, True
                GoTo finish
            Else
            
                Set oScanEnumerator0 = ActiveModelReference.GetSelectedElements
                oScanEnumerator0.MoveNext
                Set oSelected = oScanEnumerator0.Current
                
                If oSelected.ModelReference.IsAttachment = False And oSelected.ModelReference.Name = ActiveModelReference.Name Then
                    Set ph0 = CreatePropertyHandler(oSelected)
                    If ph0.SelectByAccessString("Groups[0].Description") = True Then
                        oSearch = InStr(ph0.GetDisplayString, "\")
                        oGroupName = Left(ph0.GetDisplayString, oSearch)
                        
                        If ph0.GetDisplayString = "" Then
                            CadInputQueue.SendCommand "beep"
                            ShowMessage "ERROR - Selected element is not Civil Annotation", , msdMessageCenterPriorityError, True
                            GoTo finish
                        End If
                    Else
                        CadInputQueue.SendCommand "beep"
                        ShowMessage "ERROR - Selected element is not Civil Annotation", , msdMessageCenterPriorityError, True
                        GoTo finish
                    End If
     
                Else
                    CadInputQueue.SendCommand "beep"
                    ShowMessage "ERROR - Only elements in active model can be used for this tool", , msdMessageCenterPriorityError, True
                    GoTo finish
                End If
                
                
                ' Save current model name
                'currMod = ActiveModelReference.Name
            
                Dim oScanCriteria As New ElementScanCriteria
            
                ' Cycle through models and delete matching annotation group elements
                For Each oModel In ActiveDesignFile.Models
                
                    If oModel.Type = msdModelTypeDrawing Then
                        totmodels = totmodels + 1
                        
                        count1 = 0
                        
                        oScanCriteria.IncludeOnlyVisible
                        oScanCriteria.ExcludeNonGraphical
                        
                        Set oScanEnumerator = oModel.Scan(oScanCriteria)
                        oRun = 1
                        
                        'oModel.Activate
                        ShowTempMessage msdStatusBarAreaMiddle, "Processing Drawing model " + CStr(totmodels) + " of " + CStr(countDrawings) + "..."
                        
                        Do While oScanEnumerator.MoveNext
                            Set oElement = oScanEnumerator.Current
                            countTot = countTot + 1
                            If oElement.IsGraphical = True And oElement.ModelReference.Name = oModel.Name And oElement.ModelReference.IsAttachment = False Then
                                Set ph = CreatePropertyHandler(oElement)
                                If ph.SelectByAccessString("Groups[0].Description") = True Then
                                    oSearch = ""
                                    oSearch = InStr(ph.GetDisplayString, "\")
                                    oNew = Left(ph.GetDisplayString, oSearch)
                                                             
                                    If StrComp(oNew, oGroupName, vbBinaryCompare) = 0 Then
                                        oModel.RemoveElement oElement
                                        count = count + 1
                                        count1 = count + 1
                                    End If
                                    
                                End If
                            End If
                        Loop
                    
                        If count1 > 0 Then
                            countMod = countMod + 1
                        End If
                        
                    End If
                    
                    Set oElement = Nothing
                    Set oModel = Nothing
                    Set oScanEnumerator = Nothing
                    
                Next
                
                
                ' Return to original model
                'ActiveDesignFile.Models(currMod).Activate
                
            
                CadInputQueue.SendCommand "beep"
                If count > 0 Then
                    ShowMessage CStr(count) + " total annotation element(s)  deleted from " + CStr(countMod) + " Drawing models." & vbNewLine & vbNewLine + "Removed Annotation Group: " + vbNewLine + Left(ph0.GetDisplayString, oSearch - 1), , msdMessageCenterPriorityInfo, True
                Else
                    ShowMessage "No associated Civil Annotation found in any Drawing models", , msdMessageCenterPriorityWarning, True
                End If
        
            End If
                        
        Else
        
            CadInputQueue.SendCommand "beep"
            ShowMessage "ERROR - Tool can only be run in a Drawing model", , msdMessageCenterPriorityError, True
        End If
        
        GoTo finish
        
    skip:
    
    
    finish:
    
        CommandState.StartDefaultCommand
        Exit Sub
    
    End Sub

    Regards,

    Mark


    OpenRoads Designer 2022 R3 (10.12)  |  Microstation 2023  |  ProjectWise CE 3.4

Reply
  • The VBA code below should do what you need. To run:

    1. Select an element that was placed in the Annotation group instance you want to remove
    2. Run the macro below
    3. It will delete all elements that belonged to the same Annotation group instance in all Drawing models of the active Designfile

    Sub deleteAnnoAll()
    
        Dim oScanEnumerator As ElementEnumerator, oScanEnumerator0 As ElementEnumerator, ph As PropertyHandler
        Dim oGroupName As String, ph0 As PropertyHandler, oElement As Element, oSelected As Element, oModel As ModelReference
    
        If ActiveModelReference.Type = msdModelTypeDrawing Then
        
            For Each oModel In ActiveDesignFile.Models
                If oModel.Type = msdModelTypeDrawing Then
                    countDrawings = countDrawings + 1
                End If
            Next
            
            If ActiveModelReference.AnyElementsSelected = False Then
                CadInputQueue.SendCommand "beep"
                ShowMessage "ERROR - No elements selected", , msdMessageCenterPriorityError, True
                GoTo finish
            Else
            
                Set oScanEnumerator0 = ActiveModelReference.GetSelectedElements
                oScanEnumerator0.MoveNext
                Set oSelected = oScanEnumerator0.Current
                
                If oSelected.ModelReference.IsAttachment = False And oSelected.ModelReference.Name = ActiveModelReference.Name Then
                    Set ph0 = CreatePropertyHandler(oSelected)
                    If ph0.SelectByAccessString("Groups[0].Description") = True Then
                        oSearch = InStr(ph0.GetDisplayString, "\")
                        oGroupName = Left(ph0.GetDisplayString, oSearch)
                        
                        If ph0.GetDisplayString = "" Then
                            CadInputQueue.SendCommand "beep"
                            ShowMessage "ERROR - Selected element is not Civil Annotation", , msdMessageCenterPriorityError, True
                            GoTo finish
                        End If
                    Else
                        CadInputQueue.SendCommand "beep"
                        ShowMessage "ERROR - Selected element is not Civil Annotation", , msdMessageCenterPriorityError, True
                        GoTo finish
                    End If
     
                Else
                    CadInputQueue.SendCommand "beep"
                    ShowMessage "ERROR - Only elements in active model can be used for this tool", , msdMessageCenterPriorityError, True
                    GoTo finish
                End If
                
                
                ' Save current model name
                'currMod = ActiveModelReference.Name
            
                Dim oScanCriteria As New ElementScanCriteria
            
                ' Cycle through models and delete matching annotation group elements
                For Each oModel In ActiveDesignFile.Models
                
                    If oModel.Type = msdModelTypeDrawing Then
                        totmodels = totmodels + 1
                        
                        count1 = 0
                        
                        oScanCriteria.IncludeOnlyVisible
                        oScanCriteria.ExcludeNonGraphical
                        
                        Set oScanEnumerator = oModel.Scan(oScanCriteria)
                        oRun = 1
                        
                        'oModel.Activate
                        ShowTempMessage msdStatusBarAreaMiddle, "Processing Drawing model " + CStr(totmodels) + " of " + CStr(countDrawings) + "..."
                        
                        Do While oScanEnumerator.MoveNext
                            Set oElement = oScanEnumerator.Current
                            countTot = countTot + 1
                            If oElement.IsGraphical = True And oElement.ModelReference.Name = oModel.Name And oElement.ModelReference.IsAttachment = False Then
                                Set ph = CreatePropertyHandler(oElement)
                                If ph.SelectByAccessString("Groups[0].Description") = True Then
                                    oSearch = ""
                                    oSearch = InStr(ph.GetDisplayString, "\")
                                    oNew = Left(ph.GetDisplayString, oSearch)
                                                             
                                    If StrComp(oNew, oGroupName, vbBinaryCompare) = 0 Then
                                        oModel.RemoveElement oElement
                                        count = count + 1
                                        count1 = count + 1
                                    End If
                                    
                                End If
                            End If
                        Loop
                    
                        If count1 > 0 Then
                            countMod = countMod + 1
                        End If
                        
                    End If
                    
                    Set oElement = Nothing
                    Set oModel = Nothing
                    Set oScanEnumerator = Nothing
                    
                Next
                
                
                ' Return to original model
                'ActiveDesignFile.Models(currMod).Activate
                
            
                CadInputQueue.SendCommand "beep"
                If count > 0 Then
                    ShowMessage CStr(count) + " total annotation element(s)  deleted from " + CStr(countMod) + " Drawing models." & vbNewLine & vbNewLine + "Removed Annotation Group: " + vbNewLine + Left(ph0.GetDisplayString, oSearch - 1), , msdMessageCenterPriorityInfo, True
                Else
                    ShowMessage "No associated Civil Annotation found in any Drawing models", , msdMessageCenterPriorityWarning, True
                End If
        
            End If
                        
        Else
        
            CadInputQueue.SendCommand "beep"
            ShowMessage "ERROR - Tool can only be run in a Drawing model", , msdMessageCenterPriorityError, True
        End If
        
        GoTo finish
        
    skip:
    
    
    finish:
    
        CommandState.StartDefaultCommand
        Exit Sub
    
    End Sub

    Regards,

    Mark


    OpenRoads Designer 2022 R3 (10.12)  |  Microstation 2023  |  ProjectWise CE 3.4

Children
  • Hi Mark,

    First of all, thanks for sharing this solution! I'm looking at making use of this to remove some annotation groups. However, my issue is that all of my drawing models are in separate DGNs, so I'm going to try to run this with a batch process. This means I won't be able to select the annotations to be deleted with a mouse click...

    How might I modify the code to target a certain annotation group (e.g. "Design Annotations\XS Edge of Pavement\e6dc4e75-6ea0-4131-91f4-f27c47592154", but replace the last part of the string with wildcard?) so that the process of selecting an element from a group is bypassed? Can this be done?

    Thanks very much,

    Andrew

  • Hi Andrew,

    No dramas at all, this should be possible by changing the oGroup variable to this value and then have the if statement on line 80 check the left characters of oNew match for the number of characters in oGroup. You'll just need to remove parts of the code that check for data from a selected element.

    I'll see if I can post what that would look like first chance tomorrow or so.

    Regards,

    Mark


    OpenRoads Designer 2022 R3 (10.12)  |  Microstation 2023  |  ProjectWise CE 3.4

  • Mark,

    I'm relatively green at MicroStation VBA (and VBA in general), but after some self-study, I was able to understand most of what's going on here. I made some changes, and it worked great.

    For now, I have to hard code the name of the annotation group. As I learn more VBA, I might try to set something up that lets the user pick from a list of annotation groups that exist in the cross-section container DGN. Guessing I would have to nest the batch process inside the procedure somewhere after the user picks the annotation group to remove.  

    Sub deleteAnnoEOP()
    
        Dim oScanEnumerator As ElementEnumerator, oScanEnumerator0 As ElementEnumerator, ph As PropertyHandler
        Dim oGroupName As String, ph0 As PropertyHandler, oElement As Element, oSelected As Element, oModel As ModelReference
    
        If ActiveModelReference.Type = msdModelTypeDrawing Then
        
            For Each oModel In ActiveDesignFile.Models
                If oModel.Type = msdModelTypeDrawing Then
                    countDrawings = countDrawings + 1
                End If
            Next
            
            
            
                'Set oScanEnumerator0 = ActiveModelReference.GetSelectedElements
                'oScanEnumerator0.MoveNext
                'Set oSelected = oScanEnumerator0.Current
                
                'If oSelected.ModelReference.IsAttachment = False And oSelected.ModelReference.Name = ActiveModelReference.Name Then
                    'Set ph0 = CreatePropertyHandler(oSelected)
                   ' If ph0.SelectByAccessString("Groups[0].Description") = True Then
                        'oSearch = InStr(ph0.GetDisplayString, "\")
                        oGroupName = "Design Annotations\XS Edge of Pavement\"
                        
                        'If ph0.GetDisplayString = "" Then
                           ' CadInputQueue.SendCommand "beep"
                            'ShowMessage "ERROR - Selected element is not Civil Annotation", , msdMessageCenterPriorityError, True
                           ' GoTo finish
                        'End If
                    'Else
                        'CadInputQueue.SendCommand "beep"
                       ' ShowMessage "ERROR - Selected element is not Civil Annotation", , msdMessageCenterPriorityError, True
                        'GoTo finish
                   ' End If
     
                'Else
                    'CadInputQueue.SendCommand "beep"
                    'ShowMessage "ERROR - Only elements in active model can be used for this tool", , msdMessageCenterPriorityError, True
                    'GoTo finish
                'End If
                
                
                ' Save current model name
                'currMod = ActiveModelReference.Name
            
                Dim oScanCriteria As New ElementScanCriteria
            
                ' Cycle through models and delete matching annotation group elements
                For Each oModel In ActiveDesignFile.Models
                
                    If oModel.Type = msdModelTypeDrawing Then
                        totmodels = totmodels + 1
                        
                        count1 = 0
                        
                        oScanCriteria.IncludeOnlyVisible
                        oScanCriteria.ExcludeNonGraphical
                        
                        Set oScanEnumerator = oModel.Scan(oScanCriteria)
                        oRun = 1
                        
                        'oModel.Activate
                        ShowTempMessage msdStatusBarAreaMiddle, "Processing Drawing model " + CStr(totmodels) + " of " + CStr(countDrawings) + "..."
                        
                        Do While oScanEnumerator.MoveNext
                            Set oElement = oScanEnumerator.Current
                            countTot = countTot + 1
                            If oElement.IsGraphical = True And oElement.ModelReference.Name = oModel.Name And oElement.ModelReference.IsAttachment = False Then
                                Set ph = CreatePropertyHandler(oElement)
                                If ph.SelectByAccessString("Groups[0].Description") = True Then
                                    oSearch = ""
                                    oSearch = InStrRev(ph.GetDisplayString, "\")
                                    oNew = Left(ph.GetDisplayString, oSearch)
                                                             
                                    If StrComp(oNew, oGroupName, vbBinaryCompare) = 0 Then
                                        oModel.RemoveElement oElement
                                        Count = Count + 1
                                        count1 = Count + 1
                                    End If
                                    
                                End If
                            End If
                        Loop
                    
                        If count1 > 0 Then
                            countMod = countMod + 1
                        End If
                        
                    End If
                    
                    Set oElement = Nothing
                    Set oModel = Nothing
                    Set oScanEnumerator = Nothing
                    
                Next
                
                
                ' Return to original model
                'ActiveDesignFile.Models(currMod).Activate
                
            
                
        
            
                        
        Else
        
            CadInputQueue.SendCommand "beep"
            ShowMessage "ERROR - Tool can only be run in a Drawing model", , msdMessageCenterPriorityError, True
        End If
        
        GoTo finish
        
    skip:
    
    
    finish:
    
        CommandState.StartDefaultCommand
        Exit Sub
    
    End Sub
    
    Cheers,

    Andrew

  • This is great, Mark. Thanks for this. It saves a huge amount of time, as now it takes just a couple seconds to run through 20 or so models. I made a few changes that I think I'll capture here:

    * I revised some variable names to make them more explicit as to their purpose.

    * I added declaration lines because I use Option Explicit.

    * I changed ShowMessage to MsgBox because VBA was telling me the function wasn't working, but I changed nothing else about those lines.

    * I added a loop to cycle through all of the user's initial selection set rather than just the first one. (This is a less important improvement because the alternative is that the user would simply run the script multiple times according to the selection set.)

    At the top I mentioned this thread's URL for reference.

    Sub deleteAnnoInAllModelsOfSameFile()
        'substantially identical to the script that Mark Shamoun offered here: _
            https://communities.bentley.com/products/road___site_design/f/geopak-inroads-mx-openroads-forum/228930/remove-individual-annotation-groups/709368 _
            but with some variable names changed and a loop introduced to cycle through all of the user's selection set instead of just the first element's group
        Dim oScanEnumerator As ElementEnumerator, eeInitialSelection As ElementEnumerator, ph As PropertyHandler
        Dim oGroupName As String, ph0 As PropertyHandler, oElement As Element, oSelected As Element, oModel As ModelReference
        
        Dim count_drawing_models As Long
        Dim oSearch As String, oNew As String
        Dim totModels As Long
        Dim count_within_Model As Long, count_total_deleted As Long, count_annotation_elements As Long
        Dim count_Model_affected As Long
        Dim oRun As Long
        
        
        If ActiveModelReference.Type = msdModelTypeDrawing Then
        
            For Each oModel In ActiveDesignFile.Models
                If oModel.Type = msdModelTypeDrawing Then
                    count_drawing_models = count_drawing_models + 1
                End If
            Next
            
            If ActiveModelReference.AnyElementsSelected = False Then
                CadInputQueue.SendCommand "beep"
                ShowMessage "ERROR - No elements selected", , msdMessageCenterPriorityError, True
                GoTo finish
            Else
                Set eeInitialSelection = ActiveModelReference.GetSelectedElements
                Do While eeInitialSelection.MoveNext
                   Set oSelected = eeInitialSelection.Current
                   
                   If oSelected.ModelReference.IsAttachment = False And oSelected.ModelReference.Name = ActiveModelReference.Name Then
                       Set ph0 = CreatePropertyHandler(oSelected)
                       If ph0.SelectByAccessString("Groups[0].Description") = True Then
                           oSearch = InStr(ph0.GetDisplayString, "\")
                           oGroupName = Left(ph0.GetDisplayString, oSearch)
                           
                           If ph0.GetDisplayString = "" Then
                               CadInputQueue.SendCommand "beep"
                               ShowMessage "ERROR - Selected element is not Civil Annotation", , msdMessageCenterPriorityError, True
                               GoTo finish
                           End If
                       Else
                           CadInputQueue.SendCommand "beep"
                           ShowMessage "ERROR - Selected element is not Civil Annotation", , msdMessageCenterPriorityError, True
                           GoTo finish
                       End If
        
                   Else
                       CadInputQueue.SendCommand "beep"
                       ShowMessage "ERROR - Only elements in active model can be used for this tool", , msdMessageCenterPriorityError, True
                       GoTo finish
                   End If
                   
                   
                   ' Save current model name
                   'currMod = ActiveModelReference.Name
               
                   Dim oScanCriteria As New ElementScanCriteria
               
                   ' Cycle through models and delete matching annotation group elements
                   For Each oModel In ActiveDesignFile.Models
                   
                       If oModel.Type = msdModelTypeDrawing Then
                           totModels = totModels + 1
                           
                           count_within_Model = 0
                           
                           oScanCriteria.IncludeOnlyVisible
                           oScanCriteria.ExcludeNonGraphical
                           
                           Set oScanEnumerator = oModel.Scan(oScanCriteria)
                           oRun = 1
                           
                           'oModel.Activate
                           ShowTempMessage msdStatusBarAreaMiddle, "Processing Drawing model " + CStr(totModels) + " of " + CStr(count_drawing_models) + "..."
                           
                           Do While oScanEnumerator.MoveNext
                               Set oElement = oScanEnumerator.Current
                               count_total_deleted = count_total_deleted + 1
                               If oElement.IsGraphical = True And oElement.ModelReference.Name = oModel.Name And oElement.ModelReference.IsAttachment = False Then
                                   Set ph = CreatePropertyHandler(oElement)
                                   If ph.SelectByAccessString("Groups[0].Description") = True Then
                                       oSearch = ""
                                       oSearch = InStr(ph.GetDisplayString, "\")
                                       oNew = Left(ph.GetDisplayString, oSearch)
                                                                
                                       If StrComp(oNew, oGroupName, vbBinaryCompare) = 0 Then
                                           oModel.RemoveElement oElement 'TODO: reactivate this
                                           count_annotation_elements = count_annotation_elements + 1
                                           count_within_Model = count_within_Model + 1 'TODO: should this be count_annotation_elements ?
                                       End If
                                       
                                   End If
                               End If
                           Loop
                       
                           If count_within_Model > 0 Then
                               count_Model_affected = count_Model_affected + 1
                           End If
                           
                       End If
                       
                       Set oElement = Nothing
                       Set oModel = Nothing
                       Set oScanEnumerator = Nothing
                       
                   Next
                   
                   
                   ' Return to original model
                   'ActiveDesignFile.Models(currMod).Activate
                   
               
                   CadInputQueue.SendCommand "beep"
                   If count_annotation_elements > 0 Then
                       MsgBox CStr(count_annotation_elements) & " total annotation element(s)  deleted from " & CStr(count_Model_affected) & " Drawing models." _
                            & vbNewLine _
                            & vbNewLine & "Removed Annotation Group: " _
                            & vbNewLine & Left(ph0.GetDisplayString, oSearch - 1) _
                            , , msdMessageCenterPriorityInfo, True
                   Else
                       MsgBox "No associated Civil Annotation found in any Drawing models", , msdMessageCenterPriorityWarning, True
                   End If
                Loop 'eeInitialSelection.MoveNext
            End If
                        
        Else
        
            CadInputQueue.SendCommand "beep"
            ShowMessage "ERROR - Tool can only be run in a Drawing model", , msdMessageCenterPriorityError, True
        End If
        
        GoTo finish
        
    skip:
    
    
    finish:
    
        CommandState.StartDefaultCommand
        Exit Sub
    
    End Sub
    

  • Awesome Derek, looks good.

    I'm thinking of enhancing this to provide a dialog with a list of currently found Annotation Group instances instead of needing to pre-select an element from a group as another option. Hopefully will have that done in the not too distant future.

    Regards,

    Mark


    OpenRoads Designer 2022 R3 (10.12)  |  Microstation 2023  |  ProjectWise CE 3.4