You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

IBM Notes:创建按用户输入日期发送邮件的定时代理

实现按指定日期定时发送邮件的方案

针对你的需求,我们需要把「立即发送邮件」的逻辑拆成两部分:存储待发送任务定时触发发送。下面是具体的实现步骤和代码修改:

一、修改原按钮代码:创建待发送任务文档

原来的按钮是直接发送邮件,现在我们改成创建一个专门的「待发送邮件任务」文档,把邮件的关键信息(收件人、主题、正文、发送日期)都存进去,留给后面的定时代理处理。

假设你的表单上已经添加了一个日期字段SendDate(让用户选择要发送的日期时间),修改后的按钮代码如下:

Sub Click(Source As Button)
    Dim incharge As String
    Dim Session As New NotesSession
    Dim db As NotesDatabase
    Set db = session.CurrentDatabase
    Dim ws As New NotesUIWorkspace
    Dim uidoc As NotesUIDocument
    Dim doc As NotesDocument
    Dim varValues As Variant
    Dim varCC As Variant
    
    Set uidoc = ws.currentDocument
    Set doc = uidoc.Document
    
    ' 获取用户输入的发送日期
    Dim sendDateTime As NotesDateTime
    Set sendDateTime = doc.GetItemValue("SendDate")(0)
    If sendDateTime Is Nothing Then
        Msgbox "请选择要发送的日期时间!", MB_EXCLAMATION
        Exit Sub
    End If
    
    varCC = "(the CC address)"
    varValues = doc.GetItemValue( "incharge" )
    
    ' 把员工信息整理成数组,简化循环逻辑
    Dim employeeList As Variant
    employeeList = Array( _
        Array("Employee 1", "Employee 1 Address", "Message"), _
        Array("Employee 2", "Employee 2 Address", "Message"), _
        Array("Employee 3", "Employee 3 Address", "Message"), _
        Array("Employee 4", "Employee 4 Address", "Message"), _
        Array("Employee 5", "Employee 5 Address", "Message"), _
        Array("Employee 6", "Employee 6 Address", "Message") _
    )
    
    Dim empInfo As Variant
    For Each empInfo In employeeList
        Dim empName As String, empAddr As String, empMsg As String
        empName = empInfo(0)
        empAddr = empInfo(1)
        empMsg = empInfo(2)
        
        If Not Isnull( Arraygetindex( varValues, empName ) ) Then
            ' 创建待发送任务文档
            Dim pendingDoc As NotesDocument
            Set pendingDoc = db.CreateDocument
            pendingDoc.Form = "PendingEmail" ' 需要先创建这个表单
            pendingDoc.SendTo = empAddr
            pendingDoc.CopyTo = varCC
            pendingDoc.Subject = "(subject)"
            pendingDoc.Body = empMsg
            pendingDoc.Principal = "(the sender address)"
            pendingDoc.SendDate = sendDateTime ' 存储计划发送的时间
            pendingDoc.Status = "Pending" ' 标记为待发送状态
            Call pendingDoc.Save(True, False)
        End If
    Next
    
    Msgbox "定时发送任务已创建,将在指定时间发送邮件!", MB_INFORMATION
End Sub

关键准备工作:

你需要先在数据库中创建一个名为PendingEmail的表单,包含以下字段:

  • SendDate(日期时间型):存储计划发送的时间
  • Status(文本型):标记任务状态(Pending表示待发送,Completed表示已发送)
  • SendTo(文本/姓名型):收件人地址
  • CopyTo(文本/姓名型):抄送地址
  • Subject(文本型):邮件主题
  • Body(富文本/文本型):邮件正文
  • Principal(文本型):发件人地址

二、创建定时触发的代理:执行发送任务

接下来创建一个定时代理,让它定期扫描数据库中的PendingEmail文档,当到达指定发送时间时,执行邮件发送操作。

代理设置步骤:

  1. 在Notes Designer中打开目标数据库,新建代理
  2. 代理类型选择「LotusScript」
  3. 触发方式选择「定时运行」,比如设置为「每天」或者「每小时」运行一次(根据你的需求调整频率)
  4. 目标可以选择「所有文档」,或者后续通过视图筛选更高效

代理代码:

Sub Initialize
    Dim session As New NotesSession
    Dim db As NotesDatabase
    Set db = session.CurrentDatabase
    
    ' 获取当前服务器时间
    Dim currentTime As NotesDateTime
    Set currentTime = New NotesDateTime(Now)
    
    ' 查询所有待发送的任务文档
    ' 建议后续创建一个专用视图(选择公式:SELECT Form="PendingEmail" & Status="Pending"),用视图查询效率更高
    Dim collection As NotesDocumentCollection
    Set collection = db.Search({Form="PendingEmail" & Status="Pending" & SendDate <= @Now}, Nothing, 0)
    
    Dim doc As NotesDocument
    Set doc = collection.GetFirstDocument()
    
    While Not doc Is Nothing
        Dim sendDate As NotesDateTime
        Set sendDate = doc.GetItemValue("SendDate")(0)
        
        ' 判断是否到达发送时间(考虑可能的时间差)
        If sendDate.TimeDifference(currentTime) <= 0 Then
            ' 创建邮件文档并发送
            Dim email As NotesDocument
            Set email = db.CreateDocument
            email.Form = "Memo" ' 使用标准邮件表单
            email.Principal = doc.Principal(0)
            email.Subject = doc.Subject(0)
            email.CopyTo = doc.CopyTo
            email.SendTo = doc.SendTo
            email.Body = doc.Body
            
            ' 发送邮件(False表示不保存已发送邮件到发件箱)
            On Error Resume Next
            Call email.Send(False)
            If Err = 0 Then
                ' 发送成功,标记任务为已完成
                doc.Status = "Completed"
                doc.SentTime = currentTime
                Call doc.Save(True, False)
            Else
                ' 发送失败,记录错误信息方便排查
                doc.ErrorMsg = Err & ": " & Error$
                Call doc.Save(True, False)
            End If
            On Error GoTo 0
        End If
        
        Set doc = collection.GetNextDocument(doc)
    Wend
End Sub

优化建议:

  • 优先创建专用视图:创建一个视图展示待发送任务,选择公式为SELECT Form="PendingEmail" & Status="Pending",并按SendDate排序,代理通过视图查询会比用Search方法效率更高。
  • 时区处理:如果用户和服务器不在同一时区,需要确保SendDate存储的是服务器时区的时间,或者在代码中做时区转换。
  • 失败重试:可以给发送失败的任务添加重试逻辑,比如标记为Failed,后续代理再次尝试发送。

内容的提问来源于stack exchange,提问作者Jamie

火山引擎 最新活动