NotesCalendar:LotusScript 讀寫 Domino 行事曆的三個 Class

NotesCalendar:LotusScript 讀寫 Domino 行事曆的三個 Class

2026.06.03 約 695 字

公司的 Domino 行事曆系統要做自動化 — 每週五自動建下週一到週五的定期會議、或者把外部系統(人事、專案管理)產生的行程同步進 mail.nsf。看了文件才發現:行事曆資料不是存在一般 NotesDocument 裡、而是用 iCalendar 格式(RFC 5545) 結構化儲存、必須透過三個專用 class 操作。

本文拆解這三個 class 的分工、從建立行事曆項目到讀取時間段、到處理會議邀請。


重點摘要

  • 三個 class 分工NotesCalendar(行事曆物件、取得入口)/ NotesCalendarEntry(單一行程項目)/ NotesCalendarNotice(會議邀請通知)
  • 取得方式session.GetCalendar(db)db 必須是使用者的 mail.nsf(不能是任意 NSF)
  • 寫入要用 iCalendar 字串CreateEntry(iCalString) 接受 RFC 5545 格式的字串、不是直接設欄位
  • ReadRange 批次讀取指定時間段內的所有行程(回傳 iCalendar 字串)
  • GetNewInvitations 取得尚未處理的會議邀請、配合 NoticeAction 接受 / 拒絕
  • 操作行事曆前要設 session.ConvertMIME = False、否則行事曆的 MIME 結構會被自動轉換成 rich text 破壞資料

三個 Class 的分工

Class代表什麼建立方式
NotesCalendar使用者的整個行事曆session.GetCalendar(mailDb)
NotesCalendarEntry單一行程(會議 / 個人事項 / 週期性事件)calendar.GetEntry(uid)calendar.CreateEntry(iCalString)
NotesCalendarNotice會議邀請 / 更新通知calendar.GetNewInvitations 回傳陣列

取得 NotesCalendar 物件

Dim session As New NotesSession
Dim mailDb As NotesDatabase
' 開使用者自己的 mail.nsf
Set mailDb = session.GetDatabase("MailServer/ACME", "mail/jsmith.nsf")
If Not mailDb.IsOpen Then Call mailDb.Open("", "")
' 取得行事曆物件(必須是 mail database)
Dim cal As NotesCalendar
Set cal = session.GetCalendar(mailDb)

重要GetCalendar 只接受 mail database(db.IsMailDatabase = True)。一般業務 NSF 呼叫會拋錯。


CreateEntry — 寫入新行程

CreateEntry 接受一個 iCalendar 格式字串、建立行事曆項目並回傳 NotesCalendarEntry

' 建立一個 2026-06-03 10:00-11:00 的會議
Dim iCalStr As String
iCalStr = "BEGIN:VCALENDAR" & Chr(13) & Chr(10) & _
"VERSION:2.0" & Chr(13) & Chr(10) & _
"BEGIN:VEVENT" & Chr(13) & Chr(10) & _
"DTSTART:20260603T020000Z" & Chr(13) & Chr(10) & _
"DTEND:20260603T030000Z" & Chr(13) & Chr(10) & _
"SUMMARY:週一站立會議" & Chr(13) & Chr(10) & _
"LOCATION:Conference Room A" & Chr(13) & Chr(10) & _
"END:VEVENT" & Chr(13) & Chr(10) & _
"END:VCALENDAR"
Dim entry As NotesCalendarEntry
Set entry = cal.CreateEntry(iCalStr)
If Not (entry Is Nothing) Then
Print "建立成功,UID:" & entry.UID
End If

幾個注意:

  • 時間格式用 UTC(結尾 Z)、不要用本地時區字串(容易因伺服器時區設定產生誤差)
  • 換行必須是 CRLF(Chr(13) & Chr(10)、RFC 5545 的規定
  • AutoSendNotices = True 時、建立含 ATTENDEE 的 VEVENT 會自動寄邀請信

ReadRange — 批次讀取時間段行程

Dim startDt As New NotesDateTime("2026-06-03")
Dim endDt As New NotesDateTime("2026-06-07 23:59:00")
' 讀取這段時間內的所有行程、回傳 iCalendar 字串
Dim iCalResult As String
iCalResult = cal.ReadRange(startDt, endDt)
Print "本週行程 iCal 長度:" & Len(iCalResult) & " bytes"

回傳的是整個 iCalendar 字串(包含所有 VEVENT)、要解析可以用字串操作或寫 parser。EntriesProcessed 屬性記錄這次讀了幾筆。


GetNewInvitations — 取得未處理邀請

' 取得所有未處理的會議邀請
Dim invitations As Variant
invitations = cal.GetNewInvitations()
If IsArray(invitations) Then
Dim i As Integer
For i = 0 To UBound(invitations)
Dim notice As NotesCalendarNotice
Set notice = invitations(i)
Print "邀請:" & notice.Summary
Print "主辦人:" & notice.Organizer
Next
End If

GetNewInvitations 回傳 NotesCalendarNotice 物件陣列、每個代表一封尚未回應的邀請。


NoticeAction — 接受 / 拒絕邀請

NotesCalendarNoticeNoticeAction 方法處理邀請回應:

Dim notice As NotesCalendarNotice
' (從 GetNewInvitations 取得)
' 接受邀請
Call notice.NoticeAction(CALACTION_ACCEPT, "確認參加", Nothing, False)
' 拒絕邀請
Call notice.NoticeAction(CALACTION_DECLINE, "當天行程衝突", Nothing, False)
' 暫訂
Call notice.NoticeAction(CALACTION_TENTATIVE, "", Nothing, False)

常數說明:

常數動作
CALACTION_ACCEPT1接受
CALACTION_DECLINE2拒絕
CALACTION_TENTATIVE3暫訂
CALACTION_REQUESTINFO4要求更多資訊

必踩的坑:ConvertMIME

行事曆資料在 mail.nsf 是 MIME 格式儲存。如果你在操作行事曆前 session.ConvertMIMETrue(預設值)、Domino 會自動把 MIME 轉成 rich text — 這會破壞行事曆結構、造成無法預期的錯誤。

操作行事曆之前一定要設:

session.ConvertMIME = False
' ... 所有行事曆操作 ...
' 操作完還原
session.ConvertMIME = True

這個設定只影響當次 session、不會持久化。但忘記設、就算 GetCalendar 成功、後續讀寫行程資料時也可能拿到損壞的內容。


同類別在其他語言

語言對應
LotusScriptNotesCalendar / NotesCalendarEntry / NotesCalendarNotice
Javalotus.domino.Calendar / CalendarEntry / CalendarNotice(去掉 Notes 前綴、用完要 .recycle()
SSJS沒有直接對應 — 行事曆操作在 XPages 通常透過 Domino REST API 完成

參考來源

← 回到文章列表