MS Access使用CDO SMTP发邮件报错-2147220973解决方案求助
解决方案
1 系统级TLS 1.2适配(核心解决微软淘汰低版本TLS的问题)
- 故障根因大概率是Windows系统未将TLS 1.2设为WinHTTP的默认安全协议,CDO底层依赖WinHTTP发送请求,默认优先用TLS1.0/1.1,被微软邮件服务拒绝后才会重试TLS1.2,重试失败就会触发对应报错,这也解释了30%概率失败的现象。
- 修改注册表开启TLS1.2默认支持:
- 32位Office/Access,修改路径:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Internet Settings\WinHttp,新建DWORD值DefaultSecureProtocols,赋值为0x00000A00(对应启用TLS1.1+1.2,或仅设为0x00000800仅启用TLS1.2) - 64位Office/Access,额外修改路径:
HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Internet Settings\WinHttp,添加相同的DWORD值即可
- 32位Office/Access,修改路径:
- 修改后重启电脑生效。
2 CDO配置修正
你现有代码中smtpusessl和sendtls同时设为True是错误配置,两者不能同时生效,根据端口修正配置:
- 用587端口(STARTTLS模式):
smtpusessl = False,sendtls = True - 用465端口(隐式SSL模式):
smtpusessl = True,sendtls = False - 同时确认你存储在tblCompanyInfo表中的端口和两个开关参数的匹配关系,避免出现配置冲突。
3 无CDO替代方案(稳定兼容TLS1.2)
如果CDO调整后仍不稳定,可以用VBA调用WinHTTP对象或Outlook自动化对象实现发信,原生支持TLS1.2,无需依赖CDO组件,核心逻辑示例:
' 方案A:调用本地Outlook发信(只要本地Outlook配置了对应邮箱即可用) Function Mailer_Outlook(SendTo As String, Subject As String, Body As String, Optional AttPath As String = "") Dim olApp As Object, olMail As Object Set olApp = CreateObject("Outlook.Application") Set olMail = olApp.CreateItem(0) With olMail .To = SendTo .Subject = Subject .Body = Body & Chr(13) & Chr(10) & Chr(13) & Chr(10) & "THIS MAILBOX IS NOT MONITORED. PLEASE DO NOT REPLY!" If AttPath <> "" Then .Attachments.Add AttPath .Send End With Set olMail = Nothing Set olApp = Nothing End Function
4 其他排查方向
- 确认本地防火墙、杀毒软件未随机拦截SMTP端口的出站请求
- 确认Office365账号未触发发送频率限制,短时间内发送大量邮件会被服务端临时拒连
内容的提问来源于stack exchange,提问作者dbblmb
相关产品推荐
相关产品推荐

