Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations SkipVought on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

How to replace variable placeholder in Word doc with variable text 2

Status
Not open for further replies.

VicRauch

Programmer
Sep 26, 2004
242
0
0
US
I have multiple variable placeholders in a Word document that need to be replaced with variable information from an Access table. My Word document defines these variable placeholders with this syntax: "{mfld...}" The {mfld signifies the start of the variable placeholder, and the } signifies the end of the placeholder. I have done this type of thing many times in Access VBA using InStr, Left, Mid, and Right as necessary. But in Word, it (I think) would be best to use Selection... and/or Range... I've been doing a lot of reading on these two objects but just not getting the hang of it yet.
Here is what I'm trying to accomplish.
The characters between the "{mfld" and "}" make up the name of a field in a table of variable information found in MS Access. By getting that table field name, I can use a DLookUp in Access to get the data I need to put into the Word document. For me, that is the easy part. What I need is how to work with Range (or Selection) to get that variable name that is between the "{mfld" and "}".
So, here are the steps as I see them.
1. find "{mfld"
2. copy the variable name between {mfld and } into a variable within VBA.

For example, within the document I will have {mfldTenantNames}, and {mfldTenacyAddress}, and {mfldLandlordName}, etc. I want to put "TenantNames" into a VBA variable so I can use that with the DLookup operaton in Access. After I have the data from Access, I will do a .Find.Execute Replace:=wdReplaceAll to get the data into the Word document. Then I want to move to the next "{mfld...}"

Thanks!
ps: I do not want to use Word fields as that would be more difficult for my users to define these documents in the first place.
 
You should read Word's help regarding Bookmarks, Document Variables and Reference Fields.

These built-in features exist to facilitate doing exactly what your are trying to do.
 
To quote myself: "ps: I do not want to use Word fields as that would be more difficult for my users to define these documents in the first place."
 
I did find something that helped, and have put 2 and 2 together and here is the code I came up with:
Code:
  ActiveDocument.Select
  Selection.Find.ClearFormatting
  Selection.Find.Replacement.ClearFormatting
  
  With Selection.Find
    .Text = "{mfld"
    .Forward = True
    .Wrap = wdFindContinue
    .Execute
  End With
  Selection.Extend
  Selection.Find.ClearFormatting
  With Selection.Find
    .Text = "}"
    .Forward = True
    .Wrap = wdFindContinue
    .Format = False
    .Execute
  End With
    
  Selection.MoveEnd Unit:=wdCharacter, Count:=-1
  Selection.MoveStart Unit:=wdCharacter, Count:=5
  MsgBox "Here is the variable name:  " & Selection.Range
If there is a better way, but not using document fields, bookmarks, etc. I would be interested. I'm looking for how to manipulate this information within VBA, not how to use bookmarks, fields, etc.
Thanks
 
Yeah, because making the menu picks Insert | Bookmark and typing "TennantAddress" is sooooo much harder than than typing "{mfldTenantAddress}".

If your users are so incompetent that they can't be trained on how to insert a bookmark or a field in a document, then you probably can't trust them to reliably type "{mfldTenantAddress}" without introducing excesses spaces, or spelling errors or using the wrong braces - any of which will make make your search and replace routine fail unless it is exceedingly robust.

Why don't you a simple add-in UserForm that inserts a properly formatted bookmark or field at the current currsor location with a single button click?
 
I have this thing 99% complete, or I can do it your way and be back to 55 - 60 % complete. Not what I want to do on a fixed price contract.
I was VERY clear in my original post as to what I was looking for. And asking for how I should have done this in the first place was not what I was looking for.
 
Hi Vic,

Since you appear to be doing no more than inserting field data from your database, perhaps you could explain why a mailmerge won't do what you need. Very simple and probably no vba required.

Cheers

[MS MVP - Word]
 
Actually I came here for some help with a VBA problem, and what I have found is advice on how I should have designed the system so I would not need VBA help with this one thing. No telling where else I would have run into a different VBA coding situation that I would have needed help with.
Why not use mailmerge?
The client has 20 to 30 possible documents to choose from to include into the legal case documents that need to be assembled for the specific case he is working on with a client. There will always be certain, very specific data needed no matter what the case. This system will allow the attorney to pick the 2 to 6 documents needed, the system will assemble one Word document from the selected individual documents, do a find and replace of the client's data into the needed spots, and finally present the attorney with the one Word document for him to make final changes to.

Why did I design the system without Word fields? Because I like my {mfld...} better. I find it much easier to deal with, for the user to be able to see exactly where the field will start, and usually end because it is a piece of text just like users are used to dealing with. Where as the Word fields are a new thing, they look different, act different than regular text, etc., etc., etc. I'm not doing a mailmerge because of the multiple documents (yes, the built document could have been used with the mailmerge process after it was built), plus the whole thing is being controlled from Access, not from Word. So, VBA is being used to control the whole process. Is there actually a way to do this without VBA? I would love to learn about that.
Is this the only way to design the system? No, but it is the way I felt would be best based on the knowledge I had going into the system. Have I learned anything? Yes. Would I design the system any differently if I had to start from scratch again? No. The system is well designed, works very quickly and smoothly right now in testing, and I really don't see any reason for that to change. I have worked with Access for over 15 years. I have used Access to work with Word and Excel before, very successfully, and have found the only problem is working with the differences in the object models within Word and Excel. Everything has a different name, and a different way of doing things. And that is why I posted the question I posted. I wanted help on one small, but frustrating Word VBA coding problem. I am VERY glad I was able to figure that small problem out, because I sure have not gotten any help here.
Any suggestions on how to get help with VBA coding when that is what is needed rather than unrequested design suggestions? Wouldn't it be nice to help the requestor with what was asked, and then maybe suggest an alternate way to do the same thing? That way the requestor has the answer that was requested, and some new idea to think about as far as his/her original design.
 
I don't know if this is better than your solution, I tried it and it didn't work. Why not stick with what you know, Instr, Right, Mid always work for me.
Try this if you like

Code:
Sub ReturnVariables()

Dim bReturn As Integer, eReturn As Integer, vReturn(100) As String
Dim MySent, x As Integer, y As Integer, z As Integer

    y = 0
    For Each MySent In ActiveDocument.Sentences
        x = x + 1
        bReturn = InStr(1, MySent, "{mfld")
        eReturn = InStr(1, MySent, "}")
            If eReturn <> 0 And bReturn <> 0 Then
                y = y + 1
                vReturn(y) = Mid(MySent, bReturn + 5, eReturn - bReturn - 5)
                    Do
                        bReturn = InStr(bReturn + 1, MySent, "{mfld")
                        eReturn = InStr(eReturn + 1, MySent, "}")
                            If eReturn = 0 Then Exit Do
                        y = y + 1
                        vReturn(y) = Mid(MySent, bReturn + 5, eReturn - bReturn - 5)
                    Loop
            End If
    Next

   [green] 'all of the names are now stored in the array vReturn(), do as you like from here[/green]

    For c = 1 To y
        Set myRange = ActiveDocument.Range(Start:=(0), End:=0)
            With myRange
                .InsertBefore vReturn(c)
                .Font.Name = "Arial"
                .Font.Size = 10
                .InsertParagraphAfter
            End With
    Next
End Sub

Michael Bryant
Southern Ocean Software
 
A starting point:
Code:
  objWord.ActiveDocument.Select
  objWord.Selection.Find.ClearFormatting
  With objWord.Selection.Find
    .Text = "\{mfld[!}]@\}"
    .Forward = True
    .Wrap = wdFindContinue
    .MatchWildcards = True
    .Execute
  End With
  With objWord.Selection.Range
    strVarName = Mid(.Text, 6, Len(.Text) - 6)
    .Text = DLookUp(strVarName, "yourTable", "yourCriteria")
  End With

Hope This Helps, PH.
FAQ219-2884
FAQ181-2886
 
Michael and PHV,
THANK YOU!, THANK YOU!, THANK YOU!!!!!

Michael, I don't know what did not work for you in your test with my code, but right now that is not important to me because it is working for me.
PHV, Your code sample is EXACTLY what I was looking for! I tried to find information on wild cards but could not. Microsoft's help system, unless I know exactly what I want, is horrible!

Thank you both for your time to do this and giving me some help on the actual problem I was having. Bless you both!

Again, thank you both! This was a wonderful (and Thankful) morning as I stumbled to my computer and these two great examples were waiting for me.

Happy Thanksgiving to you both,
Vic
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top