Search code examples
vbams-word

find matches and replace with dynamic values


I need to find and replace some characters with other characters (or just delete them). Replacement rules: if the first character found is "A", then replace this character with the value of currNumber +100; if the first character found is "B", then replace this character with the value of currNumber -10. And if the characters "*_" are found (the _ sign can be repeated as many times as you like), then simply replace with "".

Unfortunately my version of the code does not work. Perhaps the search does not start from the beginning every time

    Dim xStr_1 As Long    ' A
    Dim xStr_2 As Long    ' B
    Dim xStr_3 As Long    ' *_
    
    Dim i As Long
    
    Dim  currNumber As long
    
    currNumber = 0
    
    xStr_1 = InStr(1, Selection, "A")
    xStr_2 = InStr(1, Selection, "B")
    xStr_3 = InStr(1, Selection, "*_")
    
    if xStr_1 > 0 and xStr_1 < xStr_2 and xStr_1 < xStr_3 then i = xStr_1
    if xStr_2 > 0 and xStr_2 < xStr_1 and xStr_2 < xStr_3 then i = xStr_2
    if xStr_3 > 0 and xStr_3 < xStr_1 and xStr_3 < xStr_2 then i = xStr_3
    
    Do While i <> 0
    
        If xStr_1 = i Then
            
            With Selection.Find
                .ClearFormatting
                .Text = "A"
                .Wrap = wdFindContinue
                With .Replacement
                    .ClearFormatting
                    .Text = currNumber + 100
                End With
                .Execute Replace:=wdReplaceOne
            End With
            
            currNumber  = currNumber + 100
            
        elseif xStr_2 = i Then
            
            With Selection.Find
                .ClearFormatting
                .Text = "B"
                .Wrap = wdFindContinue
                With .Replacement
                    .ClearFormatting
                    .Text = currNumber - 10
                End With
                .Execute Replace:=wdReplaceOne
            End With
                
            currNumber  = currNumber - 10
    
        elseif xStr_3 = i Then
            
            With Selection.Find
                .ClearFormatting
                .Text = "\*{1}\_{1,}"
                .Wrap = wdFindContinue
                With .Replacement
                    .ClearFormatting
                    .Text = currNumber
                End With
                .Execute Replace:=wdReplaceOne
            End With
                
        end if

        xStr_1 = InStr(1, Selection, "A")
        xStr_2 = InStr(1, Selection, "B")
        xStr_3 = InStr(1, Selection, "*_")
        
        if xStr_1 > 0 and xStr_1 < xStr_2 and xStr_1 < xStr_3 then i = xStr_1
        if xStr_2 > 0 and xStr_2 < xStr_1 and xStr_2 < xStr_3 then i = xStr_2
        if xStr_3 > 0 and xStr_3 < xStr_1 and xStr_3 < xStr_2 then i = xStr_3   
    
    Loop    

Solution

  • Try something like:

    Sub Demo()
    Application.ScreenUpdating = False
    Dim i As Long
    i = CLng(InputBox("Starting number?", , 0))
    With ActiveDocument.Range
      With .Find
        .ClearFormatting
        .Replacement.ClearFormatting
        .Forward = True
        .Text = "*_"
        .Replacement.Text = ""
        .Wrap = wdFindContinue
        .MatchWildcards = False
        .Execute Replace:=wdReplaceAll
        .Text = "<[AB]>"
        .Wrap = wdFindStop
        .MatchWildcards = True
      End With
      Do While .Find.Execute
        Select Case .Text
          Case "A"
            i = i + 100
            .Text = i
          Case "B"
            i = i - 10
            .Text = i
        End Select
        .Collapse wdCollapseEnd
      Loop
    End With
    Application.ScreenUpdating = True
    End Sub