截断Microsoft Word中的合并域以用于mailmerge

时间:2016-07-22 01:56:53

标签: ms-word mergefield

我正在寻找创建公式并应用于Word 2013中的合并域。我无法访问数据库,只能使用合并字段。我的目标是截断/缩短某些合并域。例如。姓名到最初,年龄[27岁]到短期[27]。

Access和excel有公式' left'我试图使用但没有成功。似乎有更多的选项可用于数字。

{=left({ MERGEFIELD First_Name },1)}

然而,这会产生语法错误。是否有适用于mergefield的公式列表?

结果

'史蒂芬' - > ' S'

' 27年' - > ' 27'

1 个答案:

答案 0 :(得分:3)

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

举个简单的例子,让我们来看看" 27岁"的事情。

如果相关数据源列中的每个值采用相同的通用格式,我将其描述为" Word将其识别为单个数字,然后是字符串&#34 34;,那么你实际上可以使用

{ 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.

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

有类似的"不可靠" - 和资源消耗 - 使用左,中等功能的方法,只要您使用的是最新版本的Windows Word(不是Mac Word)。

你可以做的是创建一个完全空的Access / Jet数据库.mdb(让我们说它在c:\i\i.mdb,然后插入一个嵌套在DATABASE的{​​{1}}字段像这样的字段

QUOTE

通常,{ QUOTE { DATABASE \d "c:\\i\\i.mdb" \s "SELECT left('{ MERGEFIELD First_Name }',1)" } } 字段会插入Word表格(除非数据源的列数多于Word表格可以包含的列数),但是当您只插入没有标题的单个值时,Word不会放置值在一个牢房里。不幸的是,这些天Word确实添加了一个段落标记,但将DATABASE字段嵌套在DATABASE字段中似乎会再次删除它。

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

QUOTE

和Jet将返回语法错误。

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

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

至于#34;单字母提取"关注的是,还有另一种方法,与DATABASE类似,它使用外部.XML文件和一组INCLUDETEXT字段来指定文件中的节点并返回其内容。但也存在类似的困难。我可以修改这个答案,以便在某些时候描述这种方法,但据我所知,它从未在现实场景中使用过。

那么如果你需要更可靠的东西呢?嗯,有几种方法,但所有方法都有这种或那种的缺点。我所知道的主要方法是:

  1. 使用Word VBA和OpenDataSource方法打开数据源。 这允许您在理解的SQL方言中指定查询 数据来源。
  2. 使用在中间数据库中定义的Query / View来提取 您需要的数据项,并使用 查询/查看作为您的数据源
  3. 使用Word VBA的MailMerge事件来处理每个事件的数据 在Word处理mailmerge
  4. 时记录在数据源中
  5. 使用手动中间步骤
  6. (更激烈)沟通Word MailMerge并找到另一种方法 完全,例如使用.NET(相关数据库)创建.docx 提供程序和Office Open XML SDK
  7. 如果您要创建此合并以供其他人使用,则所有这些方法的两个副作用是整个过程对用户变得更加复杂或不熟悉,特别是,他们可能无法使用Word&# 39;用于数据源记录过滤的设施等。有些人遇到的另一个问题是,如果您的数据库包含长度超过255个字符的长文本字段/备注字段,那么当您执行比默认值更复杂的事情时,它们会被Jet截断;#34; SELECT * FROM TABLE& #34;

    (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。