NotesDbDirectory:列出 server 上的每一個資料庫

NotesDbDirectory:列出 server 上的每一個資料庫

2026.06.14 約 805 字

你要寫一支管理用 agent:掃過某台伺服器上的每一個 NSF,檢查 ACL 有沒有開太大、或統計各 db 的大小。問題是 —— 你手上有 NotesDatabase(操作單一資料庫)、也有先前介紹過的 NotesDirectory,但後者是查 Domino Directory(names.nsf 裡的人、群組、伺服器)的,不是列檔案的。

要「列出伺服器上有哪些資料庫」,靠的是名字很像、但工作完全不同的 NotesDbDirectory。官方定義:「Represents the Notes databases on a specific server or local computer.」這篇拆解它怎麼走訪、有哪些方法,以及一個一定會中的坑。


重點摘要

  • session.GetDbDirectory(server$) 建立;server$"" 代表本機
  • 走訪兩步驟GetFirstDatabase(fileType%) 取第一個、再迴圈 GetNextDatabase() 取後續
  • 四個 file-type 常數DATABASE(.nsf 等)、TEMPLATE(.ntf)、REPLICA_CANDIDATE(未停用複寫的)、TEMPLATE_CANDIDATE
  • 最大的坑:走訪拿到的 NotesDatabase關閉的 — 官方明說「The database is closed」,要先 .Open 才能讀 Title 以外的東西
  • 不只走訪:OpenDatabaseCreateDatabaseOpenDatabaseByReplicaIDOpenMailDatabaseOpenDatabaseIfModified
  • 別跟 NotesDirectory 搞混:那個查人/群組,這個列資料庫檔案

建立:GetDbDirectory

NotesSession 取得,傳入要查的伺服器名稱:

Dim session As New NotesSession
Dim dbdir As NotesDbDirectory
Set dbdir = session.GetDbDirectory("Mail01/Acme")

server$ 傳空字串 "" 代表本機 / 當前電腦。它只有兩個唯讀屬性:Name(你建立時指定的那台伺服器名)跟 Parent(所屬的 NotesSession)。(New NotesDbDirectory(...) 也能建,但在 COM 下不支援,用 GetDbDirectory 最保險。)

走訪:GetFirstDatabase + GetNextDatabase

走訪是經典的「先 First、再迴圈 Next」模式。GetFirstDatabase 的參數決定你要列哪一類檔案:

常數選的是
DATABASE任何 Notes 資料庫(.nsf / .nsg / .nsh)
TEMPLATE任何範本(.ntf)
REPLICA_CANDIDATE沒有停用複寫的資料庫/範本
TEMPLATE_CANDIDATE任何資料庫或範本
Dim db As NotesDatabase
Set db = dbdir.GetFirstDatabase(DATABASE)
Do Until db Is Nothing
' 處理 db(注意:此時 db 還是關閉的,見下)
Set db = dbdir.GetNextDatabase()
Loop

GetNextDatabase 不帶參數 —— 它沿用 GetFirstDatabase 當初指定的 file type。還有一個官方提醒值得記:「Each time you call this method, the database directory is reset and a new search is conducted.」 每呼叫一次 GetFirstDatabase,目錄就會從頭重新搜尋。所以一趟走訪只 GetFirstDatabase 一次,後面全用 GetNextDatabase,別在迴圈裡重複呼叫 First。

最重要的坑:拿到的 db 是「關閉」的

這是 NotesDbDirectory 最常害人 debug 半天的地方。GetFirstDatabase / GetNextDatabase 回傳的 NotesDatabase預設是關閉的。官方 GetFirstDatabase 文件寫得很白:「The database is closed. To open it, use the Open or OpenIfModified method in NotesDatabase.」

關閉狀態下,少數幾個屬性(如 TitleFileNameFilePath)讀得到,但大部分操作(讀 ACL、跑 search、開 view…)都要先打開:

Set db = dbdir.GetFirstDatabase(DATABASE)
Do Until db Is Nothing
If db.Open("", "") Then ' 先開,回傳 True 才繼續
' 這裡才能安全地讀 db.ACL、db.Size 等
End If
Set db = dbdir.GetNextDatabase()
Loop

忘了 .Open 就去讀 ACL,是這個類別最典型的「為什麼報錯/拿到空值」來源。

不只走訪

NotesDbDirectory 也能直接開/建資料庫,不必先走訪:

方法作用
OpenDatabase(file$)直接開指定檔名的資料庫
OpenDatabaseByReplicaID(replicaID$)用 replica ID 開(檔名不確定時很有用)
OpenDatabaseIfModified(file$, since)只有自某時間後有改動才開
OpenMailDatabase()開當前使用者的郵件資料庫
CreateDatabase(server$, file$)在指定位置建立新資料庫

OpenDatabaseByReplicaID 特別實用 —— 同一個邏輯資料庫在不同伺服器上檔名可能不同,但 replica ID 一致。

最小的官方範例(逐字)只示範了取第一個:

Sub Initialize
Dim dbdir As New NotesDbDirectory("Snapper")
Dim db As NotesDatabase
Set db = dbdir.GetFirstDatabase(DATABASE)
Msgbox db.Title, , db.FileName
End Sub

(注意這裡只讀 Title / FileName,所以沒先 Open 也沒事 —— 但真要操作內容就得 Open。)

同類別在其他語言

語言對應類別取得方式
Java(lotus.domino.*DbDirectorysession.getDbDirectory(server)
SSJS / XPagesDbDirectorysession.getDbDirectory(server)

三邊概念一致:getFirstDatabase / getNextDatabase 走訪、回傳的 db 一樣是關閉的、一樣得先 open。寫 Java 批次掃 server 上資料庫時,這篇的流程跟那個「先開再用」的坑完全照搬。

參考來源

← 回到文章列表