How come the Find function in the script below is not being limited to the range provided?

huntson
huntson used Ask the Experts™
on
I am working on creating a Macro in VB to modify some formatting in Microsoft word.  You'll see in the code below that I set the variable whole_slide to only select certain paragraphs.  When I read whole_slide back with a message box, it shows the correct range.  When I do a search on whole_slide however, it returns content outside the range.  For example, based on the text below the code which is being fed into word, the only content that should be selected by whole_slide is the last section "0004...."

While this is the only content that's selected as verified by the msg box, when I perform a search operation, the first 'slide,' 0002 is returned.  Why is this?


Sub RemoveParaOrLineBreaks()



Dim staticTC As String
staticTC = "--:--:--:--,--:--:--:--,10"

Dim static_next_line As String
static_next_line = "80 80 80"



Dim Found As Boolean
Dim boolvar As Boolean
Dim firstsel As Boolean

Dim tpar As Variant
Dim parnum As Variant

Dim slide_s1 As String
Dim slide_s2 As String
slide_s1 = ""
slide_s2 = ""


Dim parasel As String

Dim new_replace As String

Dim vararray() As String



Dim newsel As Range
Dim whole_slide As Range

tpar = ActiveDocument.Paragraphs.count

boolvar = True
firstsel = True
Found = False

slide_s1 = ""
slide_s2 = ""


'Set whole_slide = Selection.Range
'whole_slide.WholeStory
'Set whole_slide = ActiveDocument.Content
Set slidenum = Selection.Range
slidenum.WholeStory
Set whole_doc = Selection.Range
whole_doc.WholeStory


'Do Until boolvar = False

'if this is the first time we're doing program, eval the first section

If firstsel = True Then

'find the first pattern of text: 4 digits followed by a space followed by a colon followed by a line break

parnum = 0
Set whole_slide = ActiveDocument.Range(Start:=ActiveDocument.Paragraphs(14).Range.Start, End:=ActiveDocument.Paragraphs(tpar).Range.End)
MsgBox whole_slide

    With whole_slide.Find
            .ClearFormatting
            .Execute FindText:="^#^#^#^#" & Chr(32) & ":" & Chr(13), Forward:=True, _
                Format:=False, Wrap:=wdFindStop
            

'if we find it, tell us what we found and set found to true
            If .Found = True Then

                whole_slide.Find.Execute FindText:="^#^#^#^#"
                slidenum = whole_slide
                continue = True
                Found = True
                firstsel = False
         
                MsgBox slidenum
                MsgBox whole_slide
                
            End If
                
    End With
    
  
    
'if found is still not true, find the second pattern: 4 digits, followed by a letter, followed by a colon followed by a line break
    If Found = False Then

        With whole_slide.Find
            .ClearFormatting
            .Execute FindText:="^#^#^#^#^$" & Chr(32) & ":" & Chr(13), Forward:=True, _
                Format:=False, Wrap:=wdFindStop
                

                
 'if we find it, tell us what we found and set found to true.  Also, parse found data and set slidenum to actual slide num
         If .Found = True Then
                    
                whole_slide.Find.Execute FindText:="^#^#^#^#^$"
                slidenum = whole_slide
                continue = True
                Found = True
                firstsel = False
            
                'MsgBox slidenum
                           
                End If
        End With

    End If

    
'if this is not the first time running the program

Else
'MsgBox whole_slide
'parnum = ActiveDocument.Range(0, whole_slide.Paragraphs(1).Range.End).Paragraphs.count
parnum = 13
Set whole_slide = ActiveDocument.Range(Start:=ActiveDocument.Paragraphs(parnum).Range.Start, End:=ActiveDocument.Paragraphs(tpar).Range.End)
MsgBox whole_slide

With whole_slide.Find
            .ClearFormatting
            .Execute FindText:="^#^#^#^#" & Chr(32) & ":" & Chr(13), Forward:=True, _
                Format:=False, Wrap:=wdFindStop
             
            

'if we find it, tell us what we found and set found to true
            If .Found = True Then

                whole_slide.Find.Execute FindText:="^#^#^#^#"
                slidenum = whole_slide
                continue = True
                Found = True
                MsgBox whole_slide
                
                'parnum = ActiveDocument.Range(0, whole_slide.Paragraphs(1).Range.End).Paragraphs.count
                MsgBox parnum
                MsgBox tpar
               ' MsgBox slidenum
                
            End If
                
    End With
    
  
    
'if found is still not true, find the second pattern: 4 digits, followed by a letter, followed by a colon followed by a line break
    If Found = False Then

        With whole_slide.Find
            .ClearFormatting
            .Execute FindText:="^#^#^#^#^$" & Chr(32) & ":" & Chr(13), Forward:=True, _
                Format:=False, Wrap:=wdFindStop
                

                
 'if we find it, tell us what we found and set found to true.  Also, parse found data and set slidenum to actual slide num
         If .Found = True Then
                    
                wholse_slide.Find.Execute FindText:="^#^#^#^#^$"
                slidenum = whole_slide
                continue = True
                Found = True
                'MsgBox slidenum
                           
                End If
        End With

    End If


End If

If Found = False Then
    Exit Sub
End If


If (continue = True And boolvar = True) Then


                'Assign sentence after slide number to slide_s1 var

                                slide_s1 = whole_slide.Next(Unit:=wdSentence, count:=1)


                'Assign second sentence to slide_s2 var
                                slide_s2 = whole_slide.Next(Unit:=wdSentence, count:=2)
                                
                'Check if slide_s2 winds up being part of the next slide.  If so, set it to null.
                          
                           If (slide_s2 Like "*####*" = True) Then
                                slide_s2 = ""
                            End If
                                    
                    

                'Decide if slide has one or two sentences
                
                            If Len(slide_s1) <> 0 And Len(slide_s2) < 1 Then
                                
                                'replace text and move whole_slide selection to end of slide
                                       
                                        whole_slide.MoveEnd wdParagraph, 2
                                        
                                        
                                        
                                        With whole_doc.Find

                                            .Text = whole_slide
                                            .ClearFormatting
                                            .Replacement.Text = Chr(13) & Chr(13) & slidenum & " : " & staticTC & Chr(11) & static_next_line & Chr(11) & "C2N03 " & slidenum & " : " & Chr(11) & "C2N03" & Chr(32) & Chr(32) & slide_s1
                                            .Execute Replace:=wdReplaceAll

                                        End With
                                 
                            ElseIf Len(slide_s1) <> 0 And Len(slide_s2) <> 0 Then
                                 
                            
                                 'truncate line breaks at end of second sentence
                                           slide_s2 = Replace(slide_s2, Chr(13), "")
                                           slide_s2 = Left$(slide_s2, Len(slide_s2) - 1)

                                 'replace text and move whole_slide selection to end of slide
                                 
                                 whole_slide.MoveEnd wdParagraph, 3
                                 
                                        With whole_doc.Find

                                            .Text = whole_slide
                                            .ClearFormatting
                                            .Replacement.Text = Chr(13) & Chr(13) & slidenum & " : " & staticTC & Chr(11) & static_next_line & Chr(11) & "C2N03 " & slidenum & " : " & Chr(11) & "C2N03" & Chr(32) & Chr(32) & slide_s1 & "C2N03  " & slide_s2
                                           .Execute Replace:=wdReplaceAll

                                        End With
                                        
                                    End If
                                 
   End If

 'Loop
                            
        
End Sub

Open in new window





Word doc

LA FILLE DU REGIMENT
GERMAN TITLES
FEBRUARY 27, 2019


0001a :
 Die Franzosen rücken näher.

0002 :
 Bewaffnet euch.

0003 :
 Wir warten hier, ganz still.

0004 :
 Wenn sie angreifen,
 schlagen wir sie zurück.
Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®
Top Expert 2014
Commented:
I cleaned up the code to make it more readable.  I'm not sure why the code isn't behaving as expected. I think you need to look at the range object .start and .end properties after you invoke the .find method.

It would be helpful if you posted a Word document that the experts can use in our quest to diagnose your code problem.

Sub RemoveParaOrLineBreaks()
    Dim staticTC As String
    staticTC = "--:--:--:--,--:--:--:--,10"

    Dim static_next_line As String
    static_next_line = "80 80 80"

    Dim Found As Boolean
    Dim boolvar As Boolean
    Dim firstsel As Boolean

    Dim tpar As Variant
    Dim parnum As Variant

    Dim slide_s1 As String
    Dim slide_s2 As String
    slide_s1 = ""
    slide_s2 = ""

    Dim parasel As String

    Dim new_replace As String

    Dim vararray() As String

    Dim newsel As Range
    Dim whole_slide As Range

    tpar = ActiveDocument.Paragraphs.count

    boolvar = True
    firstsel = True
    Found = False

    slide_s1 = ""
    slide_s2 = ""


    'Set whole_slide = Selection.Range
    'whole_slide.WholeStory
    'Set whole_slide = ActiveDocument.Content
    Set slidenum = Selection.Range
    slidenum.WholeStory
    Set whole_doc = Selection.Range
    whole_doc.WholeStory

    'Do Until boolvar = False

    'if this is the first time we're doing program, eval the first section
    If firstsel = True Then
        'find the first pattern of text: 4 digits followed by a space followed by a colon followed by a line break

        parnum = 0
        Set whole_slide = ActiveDocument.Range(Start:=ActiveDocument.Paragraphs(14).Range.Start, End:=ActiveDocument.Paragraphs(tpar).Range.End)
        MsgBox whole_slide

        With whole_slide.Find
            .ClearFormatting
            .Execute FindText:="^#^#^#^#" & Chr(32) & ":" & Chr(13), Forward:=True, _
                Format:=False, Wrap:=wdFindStop

            'if we find it, tell us what we found and set found to true
            If .Found = True Then

                whole_slide.Find.Execute FindText:="^#^#^#^#"
                slidenum = whole_slide
                continue = True
                Found = True
                firstsel = False
         
                MsgBox slidenum
                MsgBox whole_slide
                
            End If
                    
        End With
            
        'if found is still not true, find the second pattern: 4 digits, followed by a letter, followed by a colon followed by a line break
        If Found = False Then
            With whole_slide.Find
                .ClearFormatting
                .Execute FindText:="^#^#^#^#^$" & Chr(32) & ":" & Chr(13), Forward:=True, _
                    Format:=False, Wrap:=wdFindStop
                    
                'if we find it, tell us what we found and set found to true.  Also, parse found data and set slidenum to actual slide num
                If .Found = True Then
                            
                    whole_slide.Find.Execute FindText:="^#^#^#^#^$"
                    slidenum = whole_slide
                    continue = True
                    Found = True
                    firstsel = False
                
                    'MsgBox slidenum
                               
                End If
            End With

        End If

    'if this is not the first time running the program
    Else
        'MsgBox whole_slide
        'parnum = ActiveDocument.Range(0, whole_slide.Paragraphs(1).Range.End).Paragraphs.count
        parnum = 13
        Set whole_slide = ActiveDocument.Range(Start:=ActiveDocument.Paragraphs(parnum).Range.Start, End:=ActiveDocument.Paragraphs(tpar).Range.End)
        MsgBox whole_slide

        With whole_slide.Find
            .ClearFormatting
            .Execute FindText:="^#^#^#^#" & Chr(32) & ":" & Chr(13), Forward:=True, _
                Format:=False, Wrap:=wdFindStop
                     
            'if we find it, tell us what we found and set found to true
            If .Found = True Then

                whole_slide.Find.Execute FindText:="^#^#^#^#"
                slidenum = whole_slide
                continue = True
                Found = True
                MsgBox whole_slide
                
                'parnum = ActiveDocument.Range(0, whole_slide.Paragraphs(1).Range.End).Paragraphs.count
                MsgBox parnum
                MsgBox tpar
               ' MsgBox slidenum
                
            End If
                        
        End With
            
        'if found is still not true, find the second pattern: 4 digits, followed by a letter, followed by a colon followed by a line break
        If Found = False Then
            With whole_slide.Find
                .ClearFormatting
                .Execute FindText:="^#^#^#^#^$" & Chr(32) & ":" & Chr(13), Forward:=True, _
                    Format:=False, Wrap:=wdFindStop
        
                'if we find it, tell us what we found and set found to true.  Also, parse found data and set slidenum to actual slide num
                If .Found = True Then
                    wholse_slide.Find.Execute FindText:="^#^#^#^#^$"
                    slidenum = whole_slide
                    continue = True
                    Found = True
                    'MsgBox slidenum
                               
                End If
            End With

        End If


    End If

    If Found = False Then
        Exit Sub
    End If


    If (continue = True And boolvar = True) Then
        'Assign sentence after slide number to slide_s1 var

        slide_s1 = whole_slide.Next(Unit:=wdSentence, count:=1)

        'Assign second sentence to slide_s2 var
        slide_s2 = whole_slide.Next(Unit:=wdSentence, count:=2)
                        
        'Check if slide_s2 winds up being part of the next slide.  If so, set it to null.
        If (slide_s2 Like "*####*" = True) Then
            slide_s2 = ""
        End If

        'Decide if slide has one or two sentences
        If Len(slide_s1) <> 0 And Len(slide_s2) < 1 Then
            
            'replace text and move whole_slide selection to end of slide
                   
            whole_slide.MoveEnd wdParagraph, 2
                    
            With whole_doc.Find
                .Text = whole_slide
                .ClearFormatting
                .Replacement.Text = Chr(13) & Chr(13) & slidenum & " : " & staticTC & Chr(11) & static_next_line & Chr(11) & "C2N03 " & slidenum & " : " & Chr(11) & "C2N03" & Chr(32) & Chr(32) & slide_s1
                .Execute Replace:=wdReplaceAll

            End With
             
        ElseIf Len(slide_s1) <> 0 And Len(slide_s2) <> 0 Then
            'truncate line breaks at end of second sentence
            slide_s2 = Replace(slide_s2, Chr(13), "")
            slide_s2 = Left$(slide_s2, Len(slide_s2) - 1)

            'replace text and move whole_slide selection to end of slide
            whole_slide.MoveEnd wdParagraph, 3
             
            With whole_doc.Find
                .Text = whole_slide
                .ClearFormatting
                .Replacement.Text = Chr(13) & Chr(13) & slidenum & " : " & staticTC & Chr(11) & static_next_line & Chr(11) & "C2N03 " & slidenum & " : " & Chr(11) & "C2N03" & Chr(32) & Chr(32) & slide_s1 & "C2N03  " & slide_s2
                .Execute Replace:=wdReplaceAll

            End With
                    
        End If
                                     
    End If

    'Loop

End Sub

Open in new window

Author

Commented:
I think it has something to do with using or not using set for these variables.  I'm not a coder so the difference and why I can and can't use that at times is a bit elusive.  Attached is a word doc with four test slides.
LA-FILLE-DU-REGIMENT.docx

Author

Commented:
To be clear, it appears the range command is working as when I tell Word to msg box me whole_slide, it shows that I'm only look at the desired section of the slide.  The final command, however, appears to search outside of it anyway.  That part I don't get.

Author

Commented:
Touche.  This resolved it:

Set whole_slide = ActiveDocument.Range(ActiveDocument.Paragraphs(8).Range.Start, ActiveDocument.Paragraphs(tpar).Range.End)

Open in new window

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial