Excel VBA通过Lotus Notes非主数据库发邮件的弹窗问题
解决Lotus Notes通过非主数据库发邮件时的"保存更改"弹窗问题
我写了一段Excel VBA代码,用来通过Lotus Notes的非主数据库发送邮件。当使用用户的主邮件数据库时,代码运行完全正常;但只要修改代码中的服务器和非主数据库名称后,邮件虽然能成功发送,Lotus Notes总会弹出一个提示框,询问**"Do you want to save your changes?"**,必须手动点击"是"或"否"才能完成整个流程。
提示弹窗说明:标题为"Notes",内容为"Do you want to save your changes?",包含"是"和"否"两个按钮。
以下是我的VBA代码,已标注关键修改点:
Sub SendWithLotus() Dim NSession As Object Dim NDatabase As Object Dim NUIWorkSpace As Object Dim NDoc As Object Dim NUIdoc As Object Set NSession = CreateObject("Notes.NotesSession") Set NUIWorkSpace = CreateObject("Notes.NotesUIWorkspace") ' 关键修改点:使用非主数据库时指定服务器和路径,主数据库可留空 Set NDatabase = NSession.GETDATABASE("XXXXX/XXX/XXXServer", "mail\YYYYY") If Not NDatabase.IsOpen Then NDatabase.OPENMAIL End If ' 创建新文档 Set NDoc = NDatabase.CREATEDOCUMENT With NDoc .SendTo = Range("O8").Value .CopyTo = "" .Subject = Range("O7").Value ' 邮件正文,包含后续要替换的标记文本 .body = vbNewLine & vbNewLine & _ "**Cell Contents**" & vbNewLine & vbNewLine & _ "" .Save True, False End With ' 编辑刚创建的文档,粘贴Excel单元格内容 Set NUIdoc = NUIWorkSpace.EDITDOCUMENT(True, NDoc) With NUIdoc ' 定位到Body字段并找到标记文本 .GOTOFIELD ("Body") .FINDSTRING "**Cell Contents**" '.DESELECTALL ' 取消注释可保留标记文本,在其前插入单元格内容 ' 复制Excel单元格为图片并粘贴 Sheets("Sheet1").Range("A1:L58").CopyPicture xlScreen, xlBitmap .Paste Application.CutCopyMode = False .Send .Close NDoc.SAVEMESSAGEONSEND = True End With ' 释放对象 Set NSession = Nothing Set NDatabase = Nothing Set NDoc = Nothing Set NUIdoc = Nothing End Sub
问题原因分析
这个弹窗出现的核心原因是:我们使用了NotesUIWorkspace.EditDocument方法打开邮件文档,通过UI操作粘贴了图片内容,导致文档被标记为"已修改"。当关闭UI文档时,Lotus Notes会检测到文档的变更,从而触发保存提示。而主数据库可能因为是用户默认邮箱,有特殊的自动保存/处理机制,所以不会弹出这个提示。
解决方案
这里提供两种可行的解决方法,你可以根据需求选择:
方法1:避免UI操作,用后端代码嵌入图片(推荐)
通过Lotus Notes的后端对象(NotesRichTextItem)直接将Excel单元格图片嵌入邮件,完全绕过UI交互,从根源上消除弹窗。修改后的代码如下:
Sub SendWithLotus_NoUI() Dim NSession As Object Dim NDatabase As Object Dim NDoc As Object Dim rtItem As Object Dim clipboardData As Object Set NSession = CreateObject("Notes.NotesSession") Set NDatabase = NSession.GETDATABASE("XXXXX/XXX/XXXServer", "mail\YYYYY") If Not NDatabase.IsOpen Then NDatabase.OPENMAIL End If ' 创建新邮件文档 Set NDoc = NDatabase.CREATEDOCUMENT With NDoc .Form = "Memo" .SendTo = Range("O8").Value .CopyTo = "" .Subject = Range("O7").Value End With ' 创建富文本项用于存放正文和图片 Set rtItem = NDoc.CREATERICHTEXTITEM("Body") ' 添加正文文本 Call rtItem.APPENDTEXT(vbNewLine & vbNewLine & "Cell Contents" & vbNewLine & vbNewLine) Call rtItem.ADDNEWLINE(2) ' 复制Excel单元格为图片到剪贴板 Sheets("Sheet1").Range("A1:L58").CopyPicture xlScreen, xlBitmap Set clipboardData = CreateObject("MSForms.DataObject") clipboardData.GetFromClipboard ' 将剪贴板中的图片嵌入富文本项 Call rtItem.EMBEDOBJECT(1454, "", "", clipboardData.GetText(1)) ' 1454对应EMBED_BITMAP ' 保存并发送邮件 NDoc.SAVEMESSAGEONSEND = True Call NDoc.Send(False) ' 释放对象 Set clipboardData = Nothing Set rtItem = Nothing Set NDoc = Nothing Set NDatabase = Nothing Set NSession = Nothing Application.CutCopyMode = False End Sub
方法2:修改UI操作逻辑,自动处理保存提示
如果必须保留UI操作的方式,可以在关闭文档前明确处理保存状态,避免弹窗。修改原代码中With NUIdoc的部分:
With NUIdoc .GOTOFIELD ("Body") .FINDSTRING "**Cell Contents**" Sheets("Sheet1").Range("A1:L58").CopyPicture xlScreen, xlBitmap .Paste Application.CutCopyMode = False .Send ' 先保存文档,再关闭,避免提示 .Save True ' 保存更改 .Close True ' 关闭时不提示保存(因为已经保存) NDoc.SAVEMESSAGEONSEND = True End With
或者,如果你不需要保存修改后的邮件副本,可以直接丢弃更改:
With NUIdoc ' ... 其他操作不变 ... .Send .DiscardChanges ' 丢弃文档更改 .Close False ' 关闭文档不保存 End With
额外提示
- 确保非主数据库有足够的权限:你需要拥有该数据库的创建、编辑文档权限,否则可能出现其他异常。
- 测试时建议先在测试环境验证:避免影响正式业务流程。
内容的提问来源于stack exchange,提问作者Bilal Çelik
相关产品推荐
相关产品推荐

