VB.NET Mail Merge实现Excel到Word邮件合并时值异常解决方法
VBA实现Excel到Word邮件合并时数值异常问题
问题场景
我正在使用Mail Merge(邮件合并)功能将Excel工作表中的数据合并到Word信函中,当前使用的连接配置与执行代码如下:
Sub WriteInWord() Dim WdApp As Object Dim WdDoc As Object result = Path.GetFileName(TextBox1.Text) Dim BatchNumber = Mid(result, 18, 5) WdApp = CreateObject("Word.Application") WdDoc = CreateObject("Word.Document") WdDoc = WdApp.Documents.Open(TextBox2.Text, ConfirmConversions:= False, ReadOnly:=False, AddToRecentFiles:=False, PasswordDocument:="", PasswordTemplate:="", Revert:=False, WritePasswordDocument:="", WritePasswordTemplate:="", XMLTransform:="") WdDoc.MailMerge.OpenDataSource(Name:=TextBox1.Text, ConfirmConversions:=False, ReadOnly:=False, LinkToSource:=True, AddToRecentFiles:=False, PasswordDocument:="", PasswordTemplate:="", WritePasswordDocument:="", WritePasswordTemplate:="", Revert:=False, Connection:= "Provider=Microsoft.ACE.OLEDB.12.0;User ID=Admin; Mode=Read; Extended Properties=""HDR=YES;IMEX=1;"";Jet OLEDB:System database=""""; Jet OLEDB:Registry Path="""";Jet OLEDB:Engine Type=35;Jet OLEDB:Database Locking Mode=0; Jet OLEDB:Global", SQLStatement:="SELECT * FROM `Sheet1$`", SQLStatement1:="") ' .Destination 0 = DOCUMENT, 1 = PRINTER WdApp.ActiveDocument.MailMerge.Destination = 0 'wdSendToNewDocument WdApp.ActiveDocument.MailMerge.SuppressBlankLines = True With WdApp.ActiveDocument.MailMerge.DataSource .FirstRecord = 1 'wdDefaultFirstRecord .LastRecord = -16 'wdDefaultLastRecord End With WdApp.ActiveDocument.MailMerge.Execute(Pause:=False) WdDoc.Close(savechanges:=False) 'Close the original mail-merge template file. Dim outputFilename As String = Path.ChangeExtension(inputFilePath + "\" + BatchNumber + ".docx", "pdf") Dim fileFormat As Object = WdSaveFormat.wdFormatPDF WdApp.ActiveDocument.SaveAs(outputFilename, fileFormat) WdApp.Quit() WdDoc = Nothing WdApp = Nothing MsgBox("FINISHED WITH MERGE") End Sub
参考截图:
从上述截图可见,Excel中的原始数值合并到Word后发生了异常变化,需要定位问题并给出修复方案。
问题根因
数值异常是OLEDB数据源连接的类型识别错误导致的:
- 现有连接字符串中
Jet OLEDB:Engine Type=35是适配Excel 97格式(.xls)的引擎参数,和使用的Microsoft.ACE.OLEDB.12.0驱动不匹配,会触发类型解析逻辑异常。 - 默认配置下ACE引擎只会扫描列前8行数据判断列数据类型,若前8行存在类型混合、长数字(如编码、批次号、订单号),会将整列识别为浮点数值类型,读取时出现精度丢失、科学计数法转换,最终合并到Word的内容和Excel原始值不一致。
- 代码中使用
SELECT *全量读取,没有对易出错的数值类编码字段做显式类型转换,进一步放大了类型识别错误的影响。
修复方案
按优先级从高到低操作即可解决问题:
- 修正连接字符串配置
替换OpenDataSource方法中的Connection参数为以下内容,强制引擎扫描全表判断类型,混合类型列按文本读取,同时匹配正确的引擎版本:
注:如果数据源是.xls格式的老版本Excel,把Connection:="Provider=Microsoft.ACE.OLEDB.12.0;User ID=Admin;Mode=Read;Extended Properties=""HDR=YES;IMEX=1;TypeGuessRows=0;ImportMixedTypes=Text"";Jet OLEDB:System database="""";Jet OLEDB:Registry Path="""";Jet OLEDB:Engine Type=37;Jet OLEDB:Database Locking Mode=0;"Jet OLEDB:Engine Type=37改回35即可。 - 显式转换字段类型
不要使用SELECT *读取全量数据,针对存储编码、ID、长数字的非计算类字段,在SQL语句中显式转换为文本类型,从查询层避免数值类型转换错误,示例:SQLStatement:="SELECT 普通文本列1, 普通文本列2, CStr(长数字编码列) AS 长数字编码列, CStr(批次号列) AS 批次号列 FROM `Sheet1$`" - 源文件格式预处理
打开作为数据源的Excel文件,将所有不参与数值计算的长数字、编码类列的单元格格式设置为文本,从数据源侧避免引擎误判列类型。 - 补全代码逻辑缺陷
现有代码存在两处会导致运行异常的问题,需要同步修复:- 晚期绑定场景下对象赋值需要加
Set关键字,例如Set WdApp = CreateObject("Word.Application"),否则会触发对象赋值错误。 - 代码中
inputFilePath变量未定义赋值,会导致输出PDF路径错误,需要提前补全该变量的取值逻辑。
- 晚期绑定场景下对象赋值需要加
内容的提问来源于stack exchange,提问作者Wind
相关产品推荐
相关产品推荐

