这是一个 C# 版本的代码,用于将 Word 文档中的“占位符”替换为合并字段。 (对于寻找 VB 版本的读者,请参阅https://stackoverflow.com/a/50159375/3077495。)
我的代码使用了一个已经运行的 Word 实例,所以您感兴趣的部分从 foreach (Word.MailMergeDataField...
查找/替换操作在它们自己的过程 ReplaceTextWithMergeField 中,数据源字段的名称(如 Word 所见!)和搜索的目标范围被传递到该过程。
注意在此过程中尖括号对是如何附加到数据字段名称的。
Find/Replace 操作是标准的,重新设置继续搜索数据字段名称的 Range 对象有点不同,因为有必要获取合并字段外部的位置- 插入字段后,范围位于字段代码内。如果不这样做,Find 可能会“无限”地出现在同一个字段中。 (注意:在这种情况下,不是用双尖括号。但是如果有人在没有它们的情况下使用代码,那么就会出现问题。)
编辑:为了在Shape 对象中查找和替换,这些对象必须单独循环。使用文本换行格式化的任何内容都位于文档的不同层中,并且不属于Document.Content。我在第三个过程中调整了查找过程,以搜索文档的ShapeRange,特别是测试文本框。
private void btnDataToMergeFields_Click(object sender, EventArgs e)
{
getWordInstance();
if (wdApp != null)
{
if (wdApp.Documents.Count > 0)
{
Word.Document doc = wdApp.ActiveDocument;
Word.Range rng = doc.Content;
Word.ShapeRange rngShapes = rng.ShapeRange;
if (doc.MailMerge.MainDocumentType != Word.WdMailMergeMainDocType.wdNotAMergeDocument)
foreach (Word.MailMergeDataField mmDataField in doc.MailMerge.DataSource.DataFields)
{
System.Diagnostics.Debug.Print(ReplaceTextWithMergeField(mmDataField.Name, ref rng).ToString()
+ " merge fields inserted for " + mmDataField.Name);
rng = doc.Content;
System.Diagnostics.Debug.Print(ReplaceTextWithMergeFieldInShapes(mmDataField.Name, ref rngShapes)
+ " mergefields inserted for " + mmDataField.Name);
}
}
}
}
//returns the number of times the merge field was inserted
public int ReplaceTextWithMergeField(string sFieldName, ref Word.Range oRng)
{
int iFieldCounter = 0;
Word.Field fldMerge;
bool bFound;
oRng.Find.ClearFormatting();
oRng.Find.Forward = true;
oRng.Find.Wrap = Word.WdFindWrap.wdFindStop;
oRng.Find.Format = false;
oRng.Find.MatchCase = false;
oRng.Find.MatchWholeWord = false;
oRng.Find.MatchWildcards = false;
oRng.Find.MatchSoundsLike = false;
oRng.Find.MatchAllWordForms = false;
oRng.Find.Text = "<<" + sFieldName + ">>";
bFound = oRng.Find.Execute();
while (bFound)
{
iFieldCounter = iFieldCounter + 1;
fldMerge = oRng.Fields.Add(oRng, Word.WdFieldType.wdFieldMergeField, sFieldName, false);
oRng = fldMerge.Result;
oRng.Collapse(Word.WdCollapseDirection.wdCollapseEnd);
oRng.MoveStart(Word.WdUnits.wdCharacter, 2);
oRng.End = oRng.Document.Content.End;
oRng.Find.Text = "<<" + sFieldName + ">>";
bFound = oRng.Find.Execute();
}
return iFieldCounter;
}
public int ReplaceTextWithMergeFieldInShapes(string sFieldName,
ref Word.ShapeRange oRng)
{
int iFieldCounter = 0;
Word.Field fldMerge;
bool bFound;
foreach (Word.Shape shp in oRng)
{
if (shp.Type == Office.MsoShapeType.msoTextBox)
{
Word.Range rngText = shp.TextFrame.TextRange;
rngText.Find.ClearFormatting();
rngText.Find.Forward = true;
rngText.Find.Wrap = Word.WdFindWrap.wdFindStop;
rngText.Find.Format = false;
rngText.Find.MatchCase = false;
rngText.Find.MatchWholeWord = false;
rngText.Find.MatchWildcards = false;
rngText.Find.MatchSoundsLike = false;
rngText.Find.MatchAllWordForms = false;
rngText.Find.Text = "<<" + sFieldName + ">>";
bFound = rngText.Find.Execute();
while (bFound)
{
iFieldCounter = iFieldCounter + 1;
fldMerge = rngText.Fields.Add(rngText, Word.WdFieldType.wdFieldMergeField, sFieldName, false);
rngText = fldMerge.Result;
rngText.Collapse(Word.WdCollapseDirection.wdCollapseEnd);
rngText.MoveStart(Word.WdUnits.wdCharacter, 2);
rngText.End = shp.TextFrame.TextRange.End;
rngText.Find.Text = sFieldName;
bFound = rngText.Find.Execute();
}
}
}
return iFieldCounter;
}