vbams-word

VBA in Word causes infinite loop without message box


The desire for the code is that when a "=?" is encountered in the Word document a string, in this case "Result" will be added. I need to move down the Word document from top to bottom so that the "Result" String will be correct for the line in the document (code for determining "Result" string is not shown for simplicity). A simple find and replace will not work in this case.

The code gets into an infinite loop if I take out the msgbox "Calculating". I believe that it may be in something to do with the refresh of Word as I try to add "Result" to the ParaRange.Text. By reading other posts on this site I thought the wdCollapseEnd would fix the issue, but it has not.

Public Sub TrialParse()
    Dim singleLine As Paragraph
    Dim t As String
    Dim s As String
    Dim lineText As String
    Dim lineNumber As Long
    Dim ParaCol As Long
    Dim ParaRange As Range
    Dim ReplaceText As String
    
    Application.ScreenUpdating = False
    Set Evaluator = New VBAexpressions
    
               'Seperate by lline
            For Each singleLine In ActiveDocument.Paragraphs
                Set ParaRange = singleLine.Range
                lineText = singleLine.Range.Text
                lineNumber = ParaRange.Information(wdFirstCharacterLineNumber)
                ParaCol = ParaRange.Information(wdFirstCharacterColumnNumber)
                
                'seperate by tabs
                tstring = Split(lineText, vbTab)
                For i = LBound(tstring, 1) To UBound(tstring, 1)
                    'find the variable definitions
                    If (tstring(i) <> "") Then
                        If (InStr(tstring(i), "=") > 0 And InStr(tstring(i), "=?") < 1) Then
                              tstring(i) = Replace(tstring(i), " ", "")     'Remove spaces
                              tstring(i) = Replace(tstring(i), vbCr, "")     'Remove Line Return
                              seq = Split(tstring(i), "=")
                              'Call docvariables(CStr(seq(0)), Val(seq(1)))
                        ElseIf (InStr(tstring(i), "=?") > 0) Then   'This is an evaluation point
                            cstring = Split(tstring(i), "=?")
                            
                               ReplaceText = ParaRange.Text & "Result"
                                                            
                                MsgBox "Calculating"
                               
                                ParaRange.Text = ReplaceText
                                
                                   ' Move the range to the next character after the replacement
                               ParaRange.Collapse wdCollapseEnd
               
                        End If
                    End If
                Next i
            Next singleLine
            Application.ScreenUpdating = True
End Sub

I have tried changing the Application.Updating to False as well as Application.Refresh at a specific point in time. Any help would be appreciated.


Solution

  • I think you have somewhat over-complicated a fairly simple task:

    Sub FindAndReplaceWithResult()
        Dim para As Paragraph
        Dim rng As Range
        Dim searchText As String
        Dim replaceText As String
        Dim foundPos As Long
        
        searchText = "=?"
        replaceText = "Result"
        
        ' Loop through each paragraph in the document
        For Each para In ActiveDocument.Paragraphs
            Set rng = para.Range
            
            ' Search for "=?" within the paragraph
            With rng.Find
                .Text = searchText
                .Forward = True
                .Wrap = wdFindStop
                
                ' Execute find and add "Result" after each found instance
                Do While .Execute
                    foundPos = rng.End ' Store the position after "=?"
                    rng.InsertAfter " " & replaceText ' Insert "Result" after "=?"
                    
                    ' Move the range after the inserted text to prevent finding the same instance
                    rng.Start = foundPos + Len(" " & replaceText)
                    rng.End = para.Range.End
                Loop
            End With
        Next para
    End Sub