在 Microsoft Word 中为邮件合并截断合并字段

Taz*_*Taz 4 ms-word mergefield

我希望创建一个公式并应用于 Word 2013 中的合并字段。我无法访问数据库,并且只提供了合并字段。我的目标是截断/缩短某些合并字段。例如,全名到首字母,年龄 [27 岁] 到短年龄 [27]。

Access 和 excel 有我尝试使用但没有成功的公式“左”。数字的可用选项似乎较少。

{=left({ MERGEFIELD First_Name },1)}
Run Code Online (Sandbox Code Playgroud)

但是,这会导致语法错误。是否有适用于合并字段的公式列表?

结果

'史蒂文' -> 'S'

'27 年' -> '27'

小智 6

对您的问题的简短回答是 Word 字段语言中没有任何内容可以可靠地进行字符串操作,例如 left()、mid() 等。{=} 字段只有 SUM、ABS、PRODUCT 等数字函数。有一些不可靠的方法,在某些情况下,它们可能足以满足您的要求,但这实际上取决于您对数据源始终包含按您期望的格式设置的值的确定程度。

作为一个简单的例子,让我们以“27 年”这件事为例。

如果相关数据源列中的每个值都采用相同的通用格式,我将其描述为“Word 将其识别为单个数字,后跟一个字母字符串”,那么您实际上可以使用

{ SET dat { MERGEFIELD age } }{ =dat }
Run Code Online (Sandbox Code Playgroud)

请注意,在这种情况下,如果您要合并到新文档,{ =dat }字段将保留在输出中,更新这些字段将导致错误。您可以通过嵌套{ =dat }字段或字段中的所有字段来避免这种情况QUOTE

{ QUOTE "{ SET dat { MERGEFIELD age } }{ =dat }" }

{ SET dat { MERGEFIELD age } }{ QUOTE { =dat } }
Run Code Online (Sandbox Code Playgroud)

但是,如果您的数据源字段可能包含一个值,例如

4 years 2 months
Run Code Online (Sandbox Code Playgroud)

那么这将不起作用,因为在这种情况下{ =dat }将评估为 6,而不是 2。 Word 还将评估任何看起来像{ = }字段表达式的内容,例如,如果您的数据源包含

SUM(23,25)
Run Code Online (Sandbox Code Playgroud)

然后{ =dat }将评估为 48。还有一些我现在不会描述的奇怪之处。

从字段中提取首字母的最简单的不可靠方法是使用大量 IF 字段来测试每个可能的首字母,例如

{ IF "{ MERGEFIELD First_Name }" = "A*" "A" }{ IF "{ MERGEFIELD First_Name }" = "B*" "B" } etc.
Run Code Online (Sandbox Code Playgroud)

如果不需要区分大小写,可以使用

{ IF "{ MERGEFIELD First_Name \*Upper }" = "A*" "A" } etc.
Run Code Online (Sandbox Code Playgroud)

如果您知道(例如)名称只能以 AZ,az 开头(并且您显然也可以测试 0-9 等。但是如果它可以以任何 Unicode 字母开头呢?不确定插入数千IF 字段是一种可靠的方法。

只要您使用的是最新版本的 Windows Word(不是 Mac Word),就有一种类似的“不可靠” - 并且消耗资源 - 使用左、中等函数的方法。

您可以做的是创建一个完全空的 Access/Jet 数据库 .mdb(假设它是 at c:\i\i.mdb,然后插入一个DATABASE嵌套在这样的QUOTE字段中的字段

{ QUOTE { DATABASE \d "c:\\i\\i.mdb" \s "SELECT left('{ MERGEFIELD First_Name }',1)" } }
Run Code Online (Sandbox Code Playgroud)

通常,DATABASE字段会插入 Word 表(除非数据源的列数超过 Word 表可以包含的列数),但是当您只插入没有标题的单个值时,Word 不会将该值放入单元格中。不幸的是,现在 Word 确实添加了一个段落标记,但是将DATABASE字段嵌套在QUOTE字段中似乎又将其删除了。

那为什么说“不可靠”呢?嗯,主要原因是如果 First_Name 字段包含任何引号(当然是单引号,而 OTTOMH 我认为是双引号)那么 Word 发送给 Jet 的查询将如下所示

SELECT left('a name containing a ' mark'),1)
Run Code Online (Sandbox Code Playgroud)

Jet 会返回一个语法错误。

DATABASE 字段方法还有其他问题,包括

  • Word 将 SELECT 语句限制为 255 个字符(我认为)。如果您提交的数据源导致 SLEECT 语句长度超过该长度,Jet 将返回错误。
  • 你必须把数据库放在某个地方。如果您只是自己使用此合并,那可能不是问题,但是如果您必须分发 Word 文档等以供其他人使用,您还必须确保他们拥有 .mdb 并且它位于指定的位置。
  • Word 有时会混淆邮件合并数据源和通过 DATABASE 字段引入的数据源。
  • 即使一个 DATABASE 字段也会对数据源中的每条记录执行查询。如果在多个地方使用此技术,将发出非常大量的查询。这可能会导致问题。

就“单个字母提取”而言,还有另一种方法与 DATABASE 方法非常相似,它使用外部 .XML 文件和一组 INCLUDETEXT 字段来指定文件中的节点并返回其内容。但也有类似的困难。我可能会修改此答案以在某些时候描述该方法,但据我所知,它从未在现实世界中使用过。

那么,如果您需要更可靠的东西怎么办?嗯,有几种方法,但所有方法都存在一种或另一种缺点。我知道的主要方法是:

  1. 使用 Word VBA 和 OpenDataSource 方法打开数据源。这允许您在数据源理解的 SQL 方言中指定查询。
  2. 使用在中间数据库中定义的查询/视图来提取您需要的数据项,并将查询/视图用作您的数据源
  3. 当 Word 处理邮件合并时,使用 Word VBA 的 MailMerge 事件来操作数据源中每条记录的数据
  4. 使用手动中间步骤
  5. (更激烈)放弃 Word MailMerge 并完全找到另一种方法,例如使用 .NET、相关数据库提供程序和 Office Open XML SDK 创建 .docx

如果您正在创建此合并供其他人使用,所有这些方法的两个副作用是整个过程对用户来说变得更加复杂或不熟悉,特别是他们可能无法使用 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。