Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Annoying problem with the "with" clause in VBA

Tags:

vba

ms-access

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!

like image 982
Jonathan Avatar asked Dec 02 '25 20:12

Jonathan


2 Answers

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
like image 63
Dick Kusleika Avatar answered Dec 04 '25 10:12

Dick Kusleika


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)

like image 41
Vicky Avatar answered Dec 04 '25 10:12

Vicky



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!