Jonathan
Jonathan

Reputation: 12025

Annoying problem with the "with" clause in VBA

I'm using this function to replace some strings from access in a word document. This function works pretty well

Sub reemplazar(doc As Word.Document, after As String, before As String, replaceall As Boolean)
    With doc.Content.Find
        .Text = after 
        .Replacement.Text = before 
        .Forward = True
        .Wrap = wdFindContinue
        .Format = False
        .MatchCase = False
        .MatchWholeWord = True
        .MatchWildcards = False
        .MatchSoundsLike = False
        .MatchAllWordForms = False
        If replaceall Then
            .Execute replace:=wdReplaceAll
        Else
            .Execute replace:=wdReplaceOne
    End If
    End With
End Sub

But... I don't know why if I rewrite the function in this way it stop working. There is no error or warning, but the replacement are not made.

Sub reemplazar(doc As Word.Document, after As String, before As String, replaceall As Boolean)
    doc.Content.Find.Text = after 
    doc.Content.Find.Replacement.Text = before 
    With doc.Content.Find
        .Forward = True
        .Wrap = wdFindContinue
        .Format = False
        .MatchCase = False
        .MatchWholeWord = True
        .MatchWildcards = False
        .MatchSoundsLike = False
        .MatchAllWordForms = False
        If replaceall Then
            .Execute replace:=wdReplaceAll
        Else
            .Execute replace:=wdReplaceOne
        End If
    End With
End Sub

Can someone explain what is the difference between this two snippets or why the second one is not working propertly? Thanks!

Upvotes: 3

Views: 1230

Answers (2)

Dick Kusleika
Dick Kusleika

Reputation: 33145

The Find property returns a Find object every time you call it. So in your second code snippet you're

  1. Creating a Find object and setting its Text property
  2. Creating a new Find object and setting its Replacement.Text property
  3. Creating a third Find object and setting a bunch of other properties and executing

That last executed Find object doesn't have it's Text or Replacement.Text properties set. If you wanted to use it in this manner, you could create an object variable like

Sub reemplazar(doc As Word.Document, after As String, before As String, replaceall As Boolean)

    Dim fnd As Find

    Set fnd = doc.Content.Find

    fnd.Text = after
    fnd.Replacement.Text = before
    With fnd
        .Forward = True
        .Wrap = wdFindContinue
        .Format = False
        .MatchCase = False
        .MatchWholeWord = True
        .MatchWildcards = False
        .MatchSoundsLike = False
        .MatchAllWordForms = False
        If replaceall Then
            .Execute Replace:=wdReplaceAll
        Else
            .Execute Replace:=wdReplaceOne
        End If
    End With
End Sub

Upvotes: 7

Vicky
Vicky

Reputation: 13244

Is this an actual true cut and paste of your code? These two should work identically. Are you sure there isn't something else going on like odd line endings?

(I notice in the first example your End If is not indented correctly, but I doubt that's anything to do with it)

Upvotes: 1

Related Questions