Fill in Microsoft Word Template from Windows Forms C# Application

Hi!

What I would like to do is have my application launch a word document which has fields specified (just text).  For instance:
<firstname> <lastname>
<city>, <state> <zip>

Then I would like for my app to find those tags and replace with some data.  This is proving to be very hard!

I have code that works so far, and what it does is finds and replaces one of the tags, but when it gets to the second tag to replace, it just goes over the code and does not work.

Here is what I have so far:

private void linkLabel1_LinkClicked_1(object sender, System.Windows.Forms.LinkLabelLinkClickedEventArgs e)
            {

                  object oMissing = System.Reflection.Missing.Value;
                  object oTemplate = Application.StartupPath + "\\letter.doc";

                  Word.Application ThisApplication;
                  Word._Document oDoc;                  
            
                  ThisApplication = new Word.Application();

                  ThisApplication.Documents.Open(ref oTemplate, ref oMissing, ref oMissing, ref oMissing
                        , ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing,
                        ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing);

                  string sqlString = "Select * From Contacts where ContactID = " + Convert.ToInt32(lvContacts.SelectedItems[0].Text);                                    

                  GenericDB.FillTable(sqlString);

                  DataRow dRow = GenericDB.dTable.Rows[0];            

                  InsertWord("<lastname>", dRow["LastName"], ThisApplication);
                  InsertWord("<firstname>", dRow["FirstName"], ThisApplication);                  
                  InsertWord("<city>", dRow["City"], ThisApplication);
                  InsertWord("<state>", dRow["State"], ThisApplication);
                  InsertWord("<address>", dRow["Address"], ThisApplication);
                  InsertWord("<zip>", dRow["ZipCode"], ThisApplication);
                  InsertWord("<customername>", this.txtCustomertName.Text, ThisApplication);
                  
            }

      private void InsertWord(object findText, object replaceText, Word.Application ThisApplication)
            {
                  object oMissing = System.Reflection.Missing.Value;
                  Word.Find myFind = ThisApplication.Selection.Find;                         
                  
                  object[] Parameters;
                  Parameters = new object[15];
                  Parameters[0] = findText;
                  Parameters[1] = oMissing;
                  Parameters[2] = oMissing;
                  Parameters[3] = oMissing;
                  Parameters[4] = oMissing;
                  Parameters[5] = oMissing;
                  Parameters[6] = oMissing;
                  Parameters[7] = oMissing;
                  Parameters[8] = oMissing;
                  Parameters[9] = replaceText;
                  Parameters[10] = oMissing;
                  Parameters[11] = oMissing;
                  Parameters[12] = oMissing;
                  Parameters[13] = oMissing;
                  Parameters[14] = oMissing;

                  myFind.GetType().InvokeMember("Execute", BindingFlags.InvokeMethod, null, myFind, Parameters );                                    
            }


Any help is greatly appreciated as I am on a tight schedule!!

Thanks!!
The_machineAsked:
Who is Participating?
 
Jens FiedererConnect With a Mentor Test Developer/ValidatorCommented:
First option:
"Failure" is a matter of preference here.  Most template applications actually prefer to replace all instances of a token, allowing constructs such as:

<firstname> <lastname>
<address>
<city>, <state> <zip>

Dear <firstname>,

In your lovely town of <city>,

etc.
It is rare to actually want to preserve instances of <city> (for example) in the document, but it is conceivable, so
for second option:

Try
            ThisApplication.Selection.SetRange(ThisApplication.ActiveDocument.Content.Start,
                ThisApplication.ActiveDocument.Content.End);
at the beginning of your InsertWord function.
0
 
Jens FiedererTest Developer/ValidatorCommented:

Try adding

            object replaceAll = Word.WdReplace.wdReplaceAll;

and
            Parameters[10] = replaceAll;

in appropriate places in your InsertWord function.

(Alternatively, you can reset your position to the start after each InsertWord, if you don't want ALL instances of, say, <city>
replaced by the replacement value).
0
 
The_machineAuthor Commented:
For your first option:
I think this will fail because replace all will replace all occurences of the same string.  So if I had <city> called out twice or three times then city would be replaced all over the document instead of the first occurence.

For your second option:
Can you please show me how to reset the position to the start of the document after I run through my InsertWord function?

EG:
ThisApplication.Position.SendToStart();  //Something like this after I run through all the other code?

Thanks for your reply!!!
0
 
The_machineAuthor Commented:
Good point, I did not think of that!

I will try the code later today and let you know what happens.

Thanks again for your help!!!!
0
 
The_machineAuthor Commented:
Works perfectly!

Thank you so much!!!
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.