对您的问题的简短回答是,Word 字段语言中没有任何东西可以可靠地 进行诸如 left()、mid() 等字符串操作。 {=} 字段只有 SUM、ABS、PRODUCT 等数值函数。有一些不可靠的方法,在某些情况下,它们可能对您的要求足够可靠,但这实际上取决于您对数据源将始终包含按您预期格式化的值的把握程度。
举个简单的例子,我们以“27年”为例。
如果相关数据源列中的每个值都采用相同的通用格式,我将其描述为“Word 将其识别为单个数字,后跟一个字母字符串”,那么您实际上可以使用
{ SET dat { MERGEFIELD age } }{ =dat }
请注意,在这种情况下,如果您要合并到新文档,{ =dat } 字段将保留在输出中,更新这些字段会导致错误。您可以通过嵌套 { =dat } 字段或 QUOTE 字段中的所有字段来避免这种情况:
{ QUOTE "{ SET dat { MERGEFIELD age } }{ =dat }" }
{ SET dat { MERGEFIELD age } }{ QUOTE { =dat } }
但是,如果您的数据源字段可能包含诸如
之类的值
4 years 2 months
那么这将不起作用,因为在这种情况下,{ =dat } 将评估为 6,而不是 2。Word 还将评估任何看起来像 { = } 字段表达式的内容,例如如果您的数据源包含
SUM(23,25)
然后{ =dat } 将评估为 48。我现在不会描述更多的奇怪之处。
从字段中提取首字母的最简单不可靠的方法是使用大量的 IF 字段来测试每个可能的首字母,例如
{ IF "{ MERGEFIELD First_Name }" = "A*" "A" }{ IF "{ MERGEFIELD First_Name }" = "B*" "B" } etc.
如果不需要区分大小写可以使用
{ IF "{ MERGEFIELD First_Name \*Upper }" = "A*" "A" } etc.
如果您知道(例如)名称只能以 A-Z、a-z 开头(显然您也可以测试 0-9 等),那没关系。但是如果它可以以任何 Unicode 字母开头怎么办?不确定插入数千个 IF 字段是一种可靠的方法。
只要您使用的是最新版本的 Windows Word(不是 Mac Word),就有一种类似“不可靠”且耗费资源的方式来使用左、中等功能。
您可以做的是创建一个完全空的 Access/Jet 数据库 .mdb(假设它位于 c:\i\i.mdb,然后像这样插入一个嵌套在 QUOTE 字段中的 DATABASE 字段
{ QUOTE { DATABASE \d "c:\\i\\i.mdb" \s "SELECT left('{ MERGEFIELD First_Name }',1)" } }
通常,DATABASE 字段会插入 Word 表(除非数据源的列数超过 Word 表可以包含的数量),但是当您只插入没有标题的单个值时,Word 不会将该值放入细胞。不幸的是,现在 Word 确实添加了一个段落标记,但是将 DATABASE 字段嵌套在 QUOTE 字段中似乎又将其删除了。
那为什么“不可靠”呢?嗯,主要原因是如果 First_Name 字段包含任何引号(当然是单引号,OTTOMH 我认为是双引号),那么 Word 发送给 Jet 的查询将如下所示
SELECT left('a name containing a ' mark'),1)
Jet 会返回一个语法错误。
DATABASE 字段方法还有其他问题,包括
- Word 将 SELECT 语句限制为 255 个字符(我认为)。如果
您提交的数据源导致 SLEECT 语句长度超过
那样的话,Jet 会返回一个错误。
- 您必须将数据库放在某个地方。如果你只是使用这个
合并自己,这可能不是问题,但如果你必须
分发Word文档等供他人使用,您还必须
确保他们拥有 .mdb 并且位于指定位置。
- Word 有时会混淆邮件合并数据源和
通过 DATABASE 字段引入的数据源。
- 即使是一个 DATABASE 字段也会对数据源中的每条记录执行查询。如果您在多个地方使用此技术,则会发出大量查询。这可能会导致问题。
就“单字母提取”而言,还有另一种方法,与 DATABASE 方法非常相似,它使用外部 .XML 文件和一组 INCLUDETEXT 字段来指定文件中的节点并返回其内容.但也有类似的困难。我可能会在某个时候修改此答案以描述该方法,但据我所知,它从未在实际场景中使用过。
如果您需要更可靠的东西怎么办?好吧,有几种方法,但它们都存在一种或另一种缺点。我知道的主要方法是:
- 使用 Word VBA 和 OpenDataSource 方法打开数据源。
这允许您在 SQL 方言中指定查询
数据源。
- 使用在中间数据库中定义的查询/视图来提取
您需要的数据项,并使用 那个 Query/View 作为您的数据源
- 使用 Word VBA 的 MailMerge 事件来处理每个
在 Word 处理邮件合并时记录在数据源中
- 使用手动中间步骤
- (更激烈)放弃 Word MailMerge 并找到另一种方法
完全,例如使用 .NET 创建一个 .docx,相关数据库
提供程序和 Office Open XML SDK
如果您创建此合并以供其他人使用,所有这些方法的两个副作用是整个过程变得更加复杂或用户不熟悉,特别是他们可能无法使用 Word 的工具用于数据源记录过滤等。有些人遇到的另一个问题是,如果您的数据库包含超过 255 个字符的长文本字段/备注字段,那么每当您执行比默认的“SELECT * FROM TABLE”更复杂的操作时,它们就会被 Jet 截断
(1) 要求您可以编写合适的查询以从数据源中获取所需的列。因为查询是使用 OLE DB 执行的,所以实际上不需要在数据库中创建任何永久对象。因此,只要后端数据库允许您执行外部查询,这可能是一种可行的方法。但是 Word 对查询也有 255 或 511 个字符的限制,所以如果你要操作很多字段或者你需要的功能很复杂,你可能会发现你很快就超过了字符限制。
(2) 与 (1) 非常相似,但可能允许您指定更复杂的查询。例如,如果您的数据源是 Jet .accdb,您也许可以创建自己的 .accdb 并定义一个查询,以访问 .accdb 中不允许您访问的表调整。您可以使用“链接表”来实现这一点,或者在某些情况下,您可以在 SQL 中指定基础表/查询的位置。
(3) 表示您使用 VBA 在 Word 处理每个数据源记录时拦截它。我让你去研究。您必须从 VBA 控制进程以确保调用 MailMerge 事件。有各种不可靠的报告。 VBA 只能访问任何备注字段的前 255 个字符。
(4),例如您创建一个 Excel 工作簿并使用它来查询数据库。在这种情况下,您可以发出比在 Word 中更长的 SQL 查询,并且您可以创建新的 Excel 列来使用 Excel 公式处理数据。 (不过,我从未尝试过)。然后将其用作您的数据源。
最后,网络搜索应显示 Word 的“=”字段识别的函数列表,但最近的 Microsoft 文档倾向于省略 IF() 函数。 .docx 标准上的 ISO29500 文档也省略了它,但我认为这不是本意,可能会在标准的未来版本中得到修复。功能是:
ABS, AND, AVERAGE, COUNT, DEFINED, FALSE, IF, INT, MIN, MAX, MOD, NOT, OR, PRODUCT, ROUND, SUM, TRUE。