Ms word MS Word合并:如何排除';金额';合并字段

Ms word MS Word合并:如何排除';金额';合并字段,ms-word,mailmerge,Ms Word,Mailmerge,环境 我需要做一个每周邮件合并,以创建捐款信收据。我们使用的数据库程序生成一个Excel文件(xls),然后将其合并到Word文档(2010)中以打印收据。每次运行将有3-6000张收据打印收据。我们接受许多不同货币的捐款 问题 数据库程序导出带有货币符号且不带小数点的货币金额。例如。: 5000美元(50美元) 或 50万欧元(5000.00欧元) 或 1000瑞士法郎(10瑞士法郎) (我不知道开发人员为什么决定这样做!但总体而言,该程序相当不错。) 通过合并字段中的一个简单公式,我可以去掉

环境

我需要做一个每周邮件合并,以创建捐款信收据。我们使用的数据库程序生成一个Excel文件(xls),然后将其合并到Word文档(2010)中以打印收据。每次运行将有3-6000张收据打印收据。我们接受许多不同货币的捐款

问题

数据库程序导出带有货币符号且不带小数点的货币金额。例如。: 5000美元(50美元) 或 50万欧元(5000.00欧元) 或 1000瑞士法郎(10瑞士法郎)

(我不知道开发人员为什么决定这样做!但总体而言,该程序相当不错。)

通过合并字段中的一个简单公式,我可以去掉美元和欧元符号,然后将金额除以100

{ = { MERGEFIELD currency_amount \# 0.00}  / 100 \# #,0.00}
然而,对于瑞士法郎这样的货币,这个公式给了我一个问题。我收到这个错误:
!未定义书签,CHF1000


我试图修改公式并在网上搜索,但迄今为止没有成功

有没有人有解决方法或想法如何解决?如果可能,我不想编辑原始excel文件(例如,运行宏、搜索和替换等)

另外,执行合并的用户也不是那么精通计算机


谢谢

我希望有人有一个简洁的解决方案,但在我看来,这个问题的每一个解决方案都可能带来复杂性,如果您可以更改提取软件,就可以避免这种复杂性——要么将货币字符串和金额拆分为两列,要么至少在“CHF”和数字之间引入一个空格

你认为你可以使用大量的字段代码来实现这一点,但是如果只有“CHF”会导致这个问题,那就更简单了。下面给出了另一种不需要编辑数据源的方法,但这种方法仅在某些情况下有用

我不认为您可以使用一组简单的字段代码来实现这一点,因为尽管您可以编写代码来检测Word是否将金额视为一个数字,但当您发现它不是一个数字时,仍然存在一个问题

您可以使用以下字段集来确定Word是否将该值视为数字:

{ SET tmp { MERGEFIELD currency_amount } }{ IF { tmp } = { =tmp } "it's a number" "it's not a number" }
这应该可以正常工作,并且在合并时不会产生错误。例如,如果您有一个值CHF1000,而实际上您有一个名为“CHF1000”的书签,那么它将无法正常工作

如果Word认为它是一个数字,那么您可以使用{=tmp#0}来获取该数字并对其执行所需操作

在不存在的情况下,您必须考虑如何将数字部分从字段中取出。 您不能以任何有用的方式使用{=}。(有时可以使用算术“技巧”从数字中提取数据,但我认为在这种情况下是不可能的)

您不能以任何有用的方式使用间接寻址(例如,在您使用

{ DOCVARIABLE { REF tmp } }
要访问一个名为CHF1000的变量,其值为1000。要做到这一点,您需要为每一个可能的金额使用一个这样的变量。实际上,如果您只能获取金额,例如CHF9999,那么它可能是可行的

因此,我认为你必须使用“暴力”一个接一个地提取数字。同样,如果只是针对CHF,并且数字总是采用相同的格式(CHF1、CHF2、…、CHF1000等),并且你知道最大位数,那么你可以使用一整串的if字段来实现这一点,比如:

{ IF tmp = "CHF0*" { SET tmp2 "0" }
}{ IF tmp = "CHF1*" { SET tmp2 "1" }
}{ IF tmp = "CHF2*" { SET tmp2 "2" }
}{ IF tmp = "CHF3*" { SET tmp2 "3" }
}{ IF tmp = "CHF4*" { SET tmp2 "4" }
}{ IF tmp = "CHF5*" { SET tmp2 "5" }
}{ IF tmp = "CHF6*" { SET tmp2 "6" }
}{ IF tmp = "CHF7*" { SET tmp2 "7" }
}{ IF tmp = "CHF8*" { SET tmp2 "0" }
}{ IF tmp = "CHF9*" { SET tmp2 "9" }
}{ SET tmp1 { tmp2 }
}{ IF tmp = "CHF?0*" { SET tmp2 "{ tmp1 }0" }
}{ IF tmp = "CHF?1*" { SET tmp2 "{ tmp1 }1" }
}{ IF tmp = "CHF?2*" { SET tmp2 "{ tmp1 }2" }
}{ IF tmp = "CHF?3*" { SET tmp2 "{ tmp1 }3" }
}{ IF tmp = "CHF?4*" { SET tmp2 "{ tmp1 }4" }
}{ IF tmp = "CHF?5*" { SET tmp2 "{ tmp1 }5" }
}{ IF tmp = "CHF?6*" { SET tmp2 "{ tmp1 }6" }
}{ IF tmp = "CHF?7*" { SET tmp2 "{ tmp1 }7" }
}{ IF tmp = "CHF?8*" { SET tmp2 "{ tmp1 }8" }
}{ IF tmp = "CHF?9*" { SET tmp2 "{ tmp1 }9" }
}{ SET tmp1 { tmp2 }
}{ IF tmp = "CHF??0*" { SET tmp2 "{ tmp1 }0" }
}{ IF tmp = "CHF??1*" { SET tmp2 "{ tmp1 }1" }
}{ IF tmp = "CHF??2*" { SET tmp2 "{ tmp1 }2" }
}{ IF tmp = "CHF??3*" { SET tmp2 "{ tmp1 }3" }
}{ IF tmp = "CHF??4*" { SET tmp2 "{ tmp1 }4" }
}{ IF tmp = "CHF??5*" { SET tmp2 "{ tmp1 }5" }
}{ IF tmp = "CHF??6*" { SET tmp2 "{ tmp1 }6" }
}{ IF tmp = "CHF??7*" { SET tmp2 "{ tmp1 }7" }
}{ IF tmp = "CHF??8*" { SET tmp2 "{ tmp1 }8" }
}{ IF tmp = "CHF??9*" { SET tmp2 "{ tmp1 }9" }
}{ SET tmp1 { tmp2 }
}
然后对你可能拥有的每个数字重复这个批次,每次将“?”字符的数量减少一个。然后使用{=tmp1#0}来获得值

<>你可以考虑用Excel数据源写VBA,它使用Jet SQL修改数据(也就是说,它不会修改主数据)。。如果只有一个用户,则定义所有邮件合并主文档,并且可以复制其环境,理论上,您只需运行一次VBA—每次他们重新打开邮件合并主文档时,都会执行相同的SQL。实际上,这很少如此简单。如果您只需要处理“CHF”,则可以同时使用代码以下几行:

Sub SetupDataSource()
ActiveDocument.MailMerge.OpenDataSource _
  Name:="c:\a\yourdatasource.xlsx", _
  sqlstatement:="SELECT t.*, iif(ucase(left(t.currency_amount,3))='CHF',mid(t.currency_amount,4),t.currency_amount) AS new_amount FROM [Sheet1$] t"
End Sub
如果您必须检测更多的“异常”,或者需要从多个货币字段中提取,那么事情可能会变得更困难,因为

  • 并非VBA中的所有字符串处理函数都在Jet中可用 以这种方式通过OLE DB连接时
  • Word将SQL限制为511个字符(在某些情况下可能是255个字符)。 其实并不多

非常感谢您的详细回答!我将首先尝试SQL方法,然后返回结果,但这在我的环境中似乎是最简单的。