First, if you need to "roll your own" merge, be aware that Mailmerge
actually does quite a lot of stuff that is non-trivial and not easy to code.
If you are creating all the templates, that's one thing. If you are still
allowing users to create templates,
a. it is highly unlikely that your own code will behave the same way as
Microsoft's. That may confuse some users
b. unless you constrain users to a very simple use of MERGEFIELD and other
field types, the chances are that they will create templates that your code
will not proces correctly or sensibly unless you put a greate deal of effort
in. For example, evaluating nested fields is, in the general case,
non-trivial. It isn't just a case of writing a recursive algorithm as some
programmers might imagine when they first approch the problem.
So it may be better to try to use Word's own mailmerge feature if possible,
even if it means that you have to write the selected data to a data source
that Word can use before doing so. NB, you can't use disconnected recordsets
as a data source, and you can't subclass the DataSource object to define
your own methods for reading data source data.
I can't point you to VB.NET examples, but it shouldn't be hard to convert
VBA samples to VB.NET. So for example, this is a way to cycle through the
fields in a document - detecting /all/ fields in a document is
non-trivial (in fact, evidence suggests that it may not be possible) but the
following code should catch most of them:
---------------------------------------------
Dim objStory As Range
Dim objField As Field
For Each objStory In ActiveDocument.StoryRanges
For Each objField In objStory.Fields
' do what you want to the field here. You can test objField.Type
' to process specific field types
Next
' The header/footer ranges can be linked in a way
' that is not revealed by the outer For Each
' so we have to do the following
While Not (objStory.NextStoryRange Is Nothing)
Set objStory = objStory.NextStoryRange
For Each objField In objStory.Fields
' do what you want to the field here
Next
Wend
Next objStory
Set objStory = Nothing
Set objField = Nothing
---------------------------------------------
Where the above code says "' do what you want to the field here", you
presumably want to insert some data from your data record. To do that, you
would need the name of the field (column) you want to get the data from,
e.g. (this will probably be significantly different in VB.NET)
Dim strMergeFieldCode
Dim strMergeFieldName
If objField.Type = wdFieldMergeField Then
strFieldCode = Split(objField.Code)
strFieldName = strFieldCode(2)
If Right(strFieldName, 1) = Chr(34) Then
strFieldName = Left(strFieldName, Len(strFieldName) - 1)
End If
If Left(strFieldName, 1) = Chr(34) Then
strFieldName = Right(strFieldName, Len(strFieldName) - 1)
End If
End If.
You probably then need to insert the value of your data column. Let's
suppose you have a function myvalue(strFieldName) that returns that value.
One way to do it is
objField.Result.Text = myvalue(strFieldName)
However, be aware that Word "wants" to assign its own results to fields. You
may find that as soon as the user does something like print preview, print
or save, Word updates the field results and destroys your results.
Another approach is to select the field and replace the selection by the
text you want, e.g.
objField.Select
Selection.Range.Text = myvalue(strFieldName)
but that destroys the field, so you would probably need to make a copy of
the Mail Merge main document before using it.
MVP Cindy Meister used to have one or two articles about this kind of thing,
but I do not think they are still available on the web - I'm thinking of the
article
"Beyond Mail Merge: Alternatives to Word's Built-in Feature"
that she references in the "List of my publications" link (see
http://homepage.swissonline.ch/cindymeister/ )
what is this mean:
mMergeField.Code.Tex
It should be clear from the above example what this is.
how to use this to assign value:
ActiveDocument.MailMerge.Fields
I think the above examples show you what you will need.
Peter Jamieson