Search code examples
vbams-worduserform

Word userform only shows with the last item found


I want to find certain errors in a document and handle them individually with a modeless userform. With the following code the userform only shows at the last error found instead of showing at each error as I intended. I set it modeless since the user would need to move around and do various things. Any suggestion will be greatly appreciated.

  1. This is the code in the main module.

     Dim rng As Range
     Dim doc As Document
     Set doc = ActiveDocument
     Set rng = doc.Range.Duplicate    
     With rng.Find
       .text = "error"
       Do While rng.Find.Execute
           rng.Select
           UserForm1.Show vbModeless
       Loop
     End With 
    
  2. This is the code in the form, which contains primarily a command button.

     Private Sub CommandButton1_Click()
     If OptionButton1.Value = True Then
       Action1
     Else
       Action2
       unload Me
     End If
     End Sub
    

I tried to add "DoEvents" after userform1.show in the above code, hoping the form can remain open, but it simply moved on and the form dissapearred with a blink.


Solution

  • When the form is not opened in a modal, the program will continue to run and you must give control of this procedure to the form after it is opened instead of leaving it in this procedure. In order to transfer the control of program execution to the form, it is necessary to dispose of the form during its initialization or activation.

    Option Explicit
    
    
    Public Rng_Word_userform_only_shows_with_the_last_item_found As Range
    
    Rem https://stackoverflow.com/questions/76586384/word-userform-only-shows-with-the-last-item-found
    Sub Word_userform_only_shows_with_the_last_item_found()
     Dim rng As Range
     Dim doc As Document
     Set doc = ActiveDocument
     If Not Rng_Word_userform_only_shows_with_the_last_item_found Is Nothing Then
        Set rng = Rng_Word_userform_only_shows_with_the_last_item_found
     Else
        Set rng = doc.Range.Duplicate
     End If
     With rng.Find
       .Text = "error"
       Do
            If rng.Find.Execute() Then
                rng.Select
                rng.Document.ActiveWindow.ScrollIntoView rng
           
                Rem When the form is not opened in a modal, the program will continue to run _
                          and you must give control of this procedure to the form after it is opened instead of leaving it in this procedure
                Rem In order to transfer the control of program execution to the form, _
                     it is necessary to dispose of the form during its initialization or activation.
                With UserForm1
                    .Show vbModeless
                    Set .rng = rng
                    Exit Sub
                End With
            Else
                Set Rng_Word_userform_only_shows_with_the_last_item_found = Nothing
                Exit Do
                
            End If
       Loop
     End With
    End Sub
    

    enter image description here

    • This is the code in the form:
    Option Explicit
    Private is_loaded As Boolean 'just for test
    Public rng As Range
    
    Private Sub CommandButton1_Click()
     If OptionButton1.Value = True Then
    '   Action1
     Else
    '   Action2
       rng.SetRange rng.End, rng.End ' rng.Document.Range.End
       Set Module1.Rng_Word_userform_only_shows_with_the_last_item_found = rng
       Unload Me
       Module1.Word_userform_only_shows_with_the_last_item_found
     End If
    End Sub
    
    'just for test
    Public Property Get Isloaded() As Variant
        Isloaded = is_loaded
    End Property
    'just for test
    Public Property Let Isloaded(ByVal vNewValue As Variant)
        is_loaded = vNewValue
    End Property
    'just for test
    Private Sub UserForm_Initialize()
        is_loaded = True
    End Sub
    'just for test
    Private Sub UserForm_Terminate()
        Isloaded = False
    End Sub
    
    

    enter image description here