所有文章
目前累積 151 篇- XPages 存檔衝突:為什麼「只有你一個人」還會跳存檔衝突
「Document has been saved by another user」——奇怪的是根本沒別人在動這份文件,存檔衝突卻偶爾自己冒出來。這篇講一個 XPages 老坑:在同一份文件上混用 dominoDocument 資料來源的存檔與後端 Document 的存檔,會讓 Domino 的衝突判定誤判、生出一份 conflict 文件。從官方的衝突機制($Revisions)講起、拆解 assono 那個經典重現,並在 Domino 12.0.2 與 14.5.1 各自實測看這個 2013 年的坑現在還在不在。
2026.09.16 - NotesView AutoUpdate=False:迴圈裡改文件為什麼越跑越慢、還跳「Entry not found in index」
一個 agent 迴圈跑 view、順手改文件,結果越跑越慢,甚至偶爾拋「Entry not found in index」。罪魁是 NotesView 預設會自動刷新:當你的迴圈改動的正是這個 view 索引的文件,view 就在你腳下一直重整,效能爛掉、導覽位置也可能失效。解法一行——迴圈前 view.AutoUpdate = False。這篇講清楚機制、正確的「先抓下一個再改」寫法,以及三個要知道的副作用(快照、只管當前程式、要 Refresh 才看得到更新)。
2026.09.15 - NoteID、UNID、@DocumentUniqueID:Domino 文件的三個 ID 到底差在哪
要指涉一份 Domino 文件,你可能會抓 NoteID、UniversalID(UNID),或在 Formula 用 @DocumentUniqueID——三個長得像、行為卻天差地遠。NoteID 只在單一資料庫檔內有意義、換個 replica 就變了;UNID 是 32 字元、跨所有 replica 都一樣的真身分;@DocumentUniqueID 回的就是 UNID(但不加 @Text 會變成 doclink)。這篇把三者的範圍、穩定性、該用哪個講清楚,含「改 UNID 會變新文件」「存重複 UNID 噴 4000」等雷,以及 web URL 那個 /0/UNID 的由來。
2026.09.14 - XPages 附件多選批次刪除:官方只能一次刪一個,自己補上「勾選多個、存檔一次刪」
XPages 的 File Download 控制項只給你一列一個、一次刪一個附件,沒有「勾選多個、一次刪」的原生做法——連做得很完整的生產表單也缺這塊。這篇先實測澄清一件事:原生刪除其實是「存檔才生效」、很守規矩;再用同樣 save-bounded 的官方 API(NotesXspDocument.removeAttachment)自己補上多選批次刪,在測試環境(Domino 12.0.2)做出一個可勾選、可反悔、存檔一次落地的實作。
2026.09.13 - XPages 檔案上傳失效:xspupload 暫存夾被 Windows cleanmgr 清掉的根源與解法(含 14.0 修復)
XPages 的檔案上傳控制項按了沒反應、使用者端沒錯誤、server console 卻報 IOFileUploadException「The system cannot find the path specified」。根源是 Domino 上傳用的暫存夾 xspupload 不見了——常常是 Windows 的磁碟清理 cleanmgr 在 Domino 執行中把它連同 temp 檔一起清掉。這篇把官方 KB 與實務串起來:症狀與根源、暫存夾為什麼會消失、以及從「每晚上下 http」這種 band-aid 到 notes_tempdir、程式化檢查重建、升級 14.0(defect 已修)的幾種解法。
2026.09.12 - 傳統 Domino web 附件 UI 的眉角:用 $V2AttachmentOptions 藏掉陽春預設,自己畫下載清單與刪除
在 Domino web form 放個 File Upload Control、加個儲存鈕,功能是通了——但畫面很陽春:附件被 Domino 倒在頁尾、編輯時還多出一排沒法美化的「標記要刪除」勾選框。這篇講傳統 Domino web 開發者的老手法:用 $V2AttachmentOptions="0" 把預設附件區藏掉、用 passthru HTML 配 @AttachmentNames 自己畫下載清單、以及那個很少人講清楚的刪除機制 %%Detach(自訂勾選框、或走 WebQuerySave)。含 $V2AttachmentOptions 只有 0/1、文字不是數字等踩雷點。
2026.09.11 - 把 Domino 附件用 REST 拋出去:DRAPI 與 DAS 都有附件端點,差在現代 vs 舊版
前幾篇都是使用者從 UI 上傳附件;但有時你要用 REST 把附件程式化地拋進拋出。Domino 有兩套 REST API:DRAPI(現代、KEEP)與 DAS(舊版、Extension Library)。常見的誤解是「DAS 只能讀」——其實不然,DAS 一樣有專屬的附件端點可以新增/讀取/更新/刪除。真正的差別是現代 vs 舊版,加上一個 DAS 特有的陷阱:別把內嵌附件資料的整份文件拿去 create/update(會回 400),要走專屬附件端點。這篇把兩者的端點與差異對照清楚。
2026.09.10 - Domino 多檔上傳與依條件刪附件:傳統 web、XPages 14.5.1
上一篇講怎麼在三種情境各附一個檔;這篇進到「一次很多個」:傳統 web form 靠 HTML5 的 multiple 屬性一次選多檔、XPages 到 14.5.1 才終於預設支援多選(在那之前是 OpenNTF 社群方案的天下),以及實務上最常遇到、參考卻最少的「依條件挑著刪」——迭代 EmbeddedObjects、依 .Source 檔名條件逐一 Remove(附可照跑範例)。附一張圖說明多選的檔怎麼落到同一個富文本欄位。
2026.09.09 - Domino 附件的三種上傳法:Notes client、傳統 web form、XPages
在 Notes client 附一個檔案,把它拖進富文本欄位就好,簡單到不像個功能。但同樣的需求搬到 web、或搬進 XPages,「怎麼讓使用者上傳檔案」就變成三個不同的答案:client 靠富文本欄位、傳統 web form 用 File Upload Control 這個內嵌元素、XPages 用 xp:fileUpload 搭 xp:fileDownload。這篇把三種前端上傳機制擺在一起對照,並點出讓人安心的一件事——三者最後都落在文件的同一個富文本欄位裡,所以後端撈檔、抽取、刪除的程式碼是共用的。
2026.09.08 - Domino IQ 逾時的 Java 解法:LLMReq.completionStream,以及 XPages SSJS 怎麼調用它
昨天那篇用 LotusScript 的 CompletionStream 突破了 Domino IQ 的 5 分鐘逾時;如果你的程式是 Java(agent、bean)或 XPages(SSJS),撞到的是同一個逾時。這篇給 Java 版:LLMReq.completionStream 搭配 CompletionStreamCallback 介面(回傳 Continue/Stop 控制串流),以及一個關鍵事實——SSJS 沒有原生的 LLM class,但 SSJS 的 session 就是 lotus.domino.Session,所以你可以直接調用 Java API,或把串流包成 Java class 再從 SSJS 引用。附三種語言一張對照表。
2026.09.06 - Domino IQ 請求 5 分鐘就逾時?沒有設定可調——改用串流突破
用 Domino IQ 做長文摘要,測試時 prompt 短、秒回;一上正式環境餵進一大串內容、GPU 又普通,就撞上「網路處理未在適當時間內完成」的逾時。你去找可以加大的 timeout 設定——沒有這個東西。Domino IQ 的請求約 5 分鐘逾時、而且設計上寫死不能調。這篇用一個真實情境走一遍:為什麼會逾時、怎麼把 Completion 換成 CompletionStream 串流突破它,以及一個很重要的但書——串流讓你「不逾時」、但不會讓它「變快」。
2026.09.05 - 把 CA 放進 certstore 就到處都信任了?DRAPI 對外其實走 JVM truststore、不是 certstore
把憑證放進 certstore.nsf 之後,開發者還有兩個實際問題:我的服務(尤其 Domino REST API)怎麼直接用它發 HTTPS?還有——我自己的程式對外呼叫 HTTPS 時,是不是也靠 certstore 驗對方憑證?答案會戳破一個常見誤會:同一台 server 上,憑證的信任其實分散在三個不同的地方。這篇(certstore 系列第三篇)以在 Domino 12.0.2 上的親手實測,講 DRAPI 的 keepconfig.d TLSCertStore 設定、certstore trusted roots 的真正用途,並把 certstore/Domino Directory/JVM cacerts 三個信任庫一次分清楚。
2026.09.04 - Domino CertMgr 串接 Let's Encrypt:用 ACME 協定自動申請與續期 TLS 憑證
手動匯入憑證還是得每 90 天換一次、還是會忘。這篇(certstore 系列第二篇)講 CertMgr 真正的殺手級功能:透過 ACME 協定跟 Let's Encrypt 自動申請、配置、續期免費且受信任的 TLS 憑證。從兩個 ACME account profile(Staging/Production)與 Global Settings 設起,走一遍申請流程與 submit 後 CertMgr 自動做完的六件事,講清楚 HTTP-01 與 DNS-01 challenge 的差別,最後點出 micro CA 只該用在測試、ECDSA 與 key rollover。
2026.09.03 - Domino 憑證管理入門:用 CertMgr 與 certstore.nsf 取代滿地的 kyr keyring 檔
從 Domino 12 起,TLS 憑證不再是散在每台 server 磁碟上的 .kyr keyring 檔——一個 CertMgr server task 加一個 certstore.nsf 資料庫就統一管起來:憑證存在 TLS Credentials 文件裡、私鑰用 256-bit AES 加密、由 ACL 保護、還能挑哪幾台 server 讀得到。這篇是 certstore 系列第一篇,講清楚這個模型、怎麼把 certstore.nsf 立起來、TLS Credentials 文件的組成,以及把既有第三方 CA 憑證匯入的完整步驟。
2026.09.02 - Formula 的 @For 迴圈:什麼時候該用它,以及一個「反轉組織階層」的實例
上一批清單函式(@Transform、@Explode…)能一行處理整串,但有些事還是得用真正的迴圈——累積狀態、依順序組字串、反轉一個 list。這篇深入 @For:四個部位(初始化/條件/遞增/主體)、一個很多人會愣的重點(@For 回傳的是 1 而不是你累積的值,所以要另起一行回傳變數),並用一個真實需求走一遍——把 A\B\C 的組織階層反過來顯示成 C\B\A。順帶講 @While/@DoWhile 的差別,以及無限迴圈保護。
2026.09.01 - Formula 的錯誤處理與求值:@IfError、@Eval,以及公式在哪裡跑很重要
系列收尾。前六篇講 formula 能做什麼;這篇講兩件不管你寫什麼都會遇到的事:公式出錯時怎麼辦,以及公式到底在哪裡、什麼時候跑。錯誤用 @IfError 接住、給備援值,@IsError 判斷是不是錯誤——但別忘了 @IfError 會把真正的錯誤訊息藏起來、debug 時要先拿掉。@Eval 能在執行期把字串當公式跑。而「公式跑在哪個情境」正是整個系列一堆坑(@DbLookup 不能用在欄公式…)的根源。Formula @function 系列第七篇(完結)。
2026.08.31 - Formula 控制流與變數:暫存變數 :=、@If、@Do、@For/@While
一條真正的公式會分支、會存中間值、偶爾要迴圈。這篇講怎麼把公式結構化:暫存變數 x := ... 是現代寫法的骨幹(分號分隔、最後一句是回傳值);@If 可以串到 99 組條件/動作、就是 formula 的 switch;@Do 依序求值回最後一個;真正的迴圈 @For/@While/@DoWhile 存在,但因為 formula 是清單導向的,多數時候根本用不到。Formula @function 系列第六篇。
2026.08.30 - Formula 的日期運算:@Adjust 加減、@Now/@Today 取現在、@Modified 的兩個版本要分清
在 formula 裡算日期沒有什麼日期函式庫,就是幾個 @function。加減用 @Adjust(年月日時分秒七個位置、正負皆可);取現在用 @Now(完整時戳)或 @Today(只到日);文件時間用 @Created/@Modified。這篇也點兩個坑:@Now 每次都重算、放進 column/selection 公式會拖效能;還有 @Modified(初次修改)和 @ModifiedInThisFile(本檔最後修改)在有 replica 時是兩回事。Formula @function 系列第五篇。
2026.08.29 - @Name 是處理 Notes 名稱的瑞士刀:三種格式互轉、抽出任一段
在 formula 裡常要處理 Notes 名稱——比對、顯示、抽出 OU。@Name 是那把瑞士刀:[ABBREVIATE]/[CANONICALIZE]/[CN] 在 canonical/abbreviated/common 三種格式間互轉,[O]/[OU1]/[S] 抽出任一段。取當前使用者用 @UserName(canonical)或 @V3UserName(abbreviated),但有個坑:在 server agent 裡「當前使用者」其實是簽署者,也不能拿來當安全機制。Formula @function 系列第四篇。
2026.08.28 - Formula 字串處理:@Left/@Right/@Middle、@Word、@ReplaceSubstring
在 formula 裡切字串,很多人只知道 @Left(s; 3) 這種數字元版本——但 @Left/@Right/@Middle 同時也吃「分隔字串」:@Left(email; "@") 就是取 @ 之前的全部。@Middle 更是有四種簽章,「取 X 和 Y 之間」一行就成。這篇把 formula 的字串工具講清楚:@Middle 的四形態、@Left/@Right 的雙形態、@Word 按分隔取第 n 個(-1 取最後、抓姓氏)、@ReplaceSubstring 平行清單多重取代。Formula @function 系列第三篇。
2026.08.27 - 在 formula 裡處理一串值,為什麼幾乎不用寫迴圈?
從 LotusScript/Java 過來,你會想用迴圈處理一串值。但 formula 幾乎沒有迴圈——因為一條公式本來就是對「整串 list」一次作用的。這篇把 formula 當成函數式清單語言來看:套在多值欄位上的運算自動逐元素跑(隱式 map)、@Transform 是明確的 map(還能用 @Nothing 當 filter、回傳 list 當 flatMap)、@Explode/@Implode 切字串接清單、@Sort 排序(含 [CUSTOMSORT] 用 $A/$B 自訂)。原本十行迴圈,常常一行公式就完。Formula @function 系列第二篇。
2026.08.26 - Formula 跨 View/跨資料庫取值:@DbColumn 與 @DbLookup 一次搞懂
在 formula 裡要讀另一個 view 或另一個資料庫的資料,九成的情況就靠兩個函式:@DbColumn 抓一整欄(做關鍵字清單、下拉選單),@DbLookup 按 key 找一個值(把代碼換成標籤、拉一個關聯欄位)。這篇講兩者的語法、cache 關鍵字(空字串/NoCache/ReCache)、以及那幾個一定要知道的規矩——第一欄要排序、只能相等比對、64KB 上限、還有它們在哪些地方不能用。Formula @function 系列第一篇。
2026.08.25 - Domino REST API 上線前:安全模型、rich text 單向、CORS 與 admin port
系列收尾。你已經會認證、開 scope、CRUD、查詢了;把它交給真實使用者之前,Domino 開發者最該問兩件事:它會不會繞過我的 Readers 欄位安全?以及上正式環境會踩到什麼。答案:DRAPI 是分層安全(JWT + scope + 底層 Domino 的 ACL/Readers 照算),不會漏;但有幾個很實在的限制——rich text 只能單向轉出、沒配置的欄位碰不到、同名 form/view 選哪個沒保證——加上 CORS、port 這些上線前要收的口。DRAPI 系列第六篇(完結)。
2026.08.24 - DQL 明明沒寫錯,卻一筆都查不到?因為那個 form 少了 dql mode
上一篇是用 unid 拿單一份文件。真正常見的是「符合條件的一批」——所有未完成的 todo、某區的所有客戶。DRAPI 給兩條路:GET /lists/{view} 讀一個 view/folder,或 POST /query 跑 DQL。DQL 還支援參數化查詢(?VAR + variables,防注入)。但有個接續上一篇的坑:一個 form 若沒有 dql mode,DQL 就完全看不到它。這篇把兩條查詢路徑、分頁、mode 陷阱與 DQL 存取控制講清楚。DRAPI 系列第五篇。
2026.08.23 - 在 Domino REST API 建文件,為什麼一定要帶 Form 欄位和 dataSource?
門開好了(schema + scope),這一篇做真正的活:用 REST 對 NSF 裡的文件增刪查改。建立是 POST /document、body 帶一個必填的 Form 欄位,回來的 @meta 裡有 unid;讀取是 GET /document/{unid}/{mode}。每個 CRUD 呼叫都帶 dataSource——而那個值就是你上一篇建的 scope 名字。這篇也講兩個 Domino 開發者會愣一下的點:Form 欄位為什麼必填、mode 是什麼。DRAPI 系列第四篇。
2026.08.22 - Domino REST API 的 scope 與 schema:一個 NSF 怎麼變成 REST 端點(而且預設什麼都不開)
把一個 NSF 開上 REST,不是打開開關就全部曝露。DRAPI 是 secure-by-default:你要先寫一份 schema(白名單,決定哪些 form、view、folder、agent、欄位對外),再建一個 scope(把 schema 活化成 REST mapping 的那層)。scope 的名字就是上一篇 JWT 裡 scopes claim 認的那個名字,而底下 Domino 的 ACL、Readers 欄位一樣還在算。這篇把 schema 與 scope 拆清楚。DRAPI 系列第三篇。
2026.08.21 - 呼叫 Domino REST API 一直 401?先搞懂它的 JWT 認證與 scope
DRAPI 幾乎每個呼叫都要證明你是誰。它不用傳統的 session/LTPA,而是 JWT bearer token:先 POST 到 /api/v1/auth 用 Domino 帳密換一個 token,之後每個請求都在 Authorization header 帶著它。這篇講怎麼登入拿 token、token 裡的 scopes/aud claim 在管什麼、token 從哪來(Domino 自簽 JWT、外部 OIDC、idpcat.nsf 三條路)、以及重啟金鑰會變之類的坑。DRAPI 系列第二篇。
2026.08.20 - Domino REST API 上手:把 NSF 資料變成任何語言都能呼叫的 REST 端點
想讓一個現代前端、一支 Python 服務、或一條 Power Automate 流程讀寫 Domino 資料,傳統答案(XPages、DIIOP、自己寫 LotusScript web agent 吐 JSON)都得讓對方遷就 Domino。Domino REST API(DRAPI,KEEP 專案)把它反過來:在你的 NSF 之上架一層標準的 REST/JSON API,任何會講 HTTP 的語言都能呼叫。這是 DRAPI 系列的第一篇——它是什麼、跟傳統存取差在哪、三個要先懂的積木(scope/schema、JWT、OpenAPI/Swagger),以及怎麼開始。
2026.08.19 - 跨 DB 的 embedded view 搬到測試區就「無法啟動」?問題出在 DXL 裡綁死的抄本 ID
一個 form 上的跨 DB 嵌入視圖,在開發區好好的,交到客戶測試區就顯示「無法啟動」。翻遍 Designer 的嵌入視圖 UI 也沒有地方換來源資料庫。把 form 匯出成 DXL 才發現:embeddedview 元素用來源庫的抄本 ID(replica ID)綁死來源,換了環境那個 ID 就對不上。這篇是實測記錄:怎麼診斷、怎麼用一支 NotesDXLExporter/Importer 的 agent 批次換掉,以及後來才發現的更快解法——Designer 直接「以 DXL 編輯」。
2026.08.18 - Java 的 NotesException:.id、.text 與 try/catch/finally
LotusScript 的錯誤處理是 On Error Goto、Err.Number、Resume 那一套。搬到 Java,幾乎每個 lotus.domino 方法都會丟一個受檢的 NotesException——編譯器逼你處理,而它身上帶著 .id(Notes 錯誤碼)與 .text(錯誤訊息)。這篇講 Java 版的例外處理:NotesException 的欄位、怎麼用 .id 比對 NotesError 常數做針對性處理,以及把這整個 Java 資料層系列收在一起的那條規則——recycle 要放進 finally,這樣連拋例外時也收得乾淨。
2026.08.17 - 在 Java 裡迴圈跑 DocumentCollection:先拿下一份,再 recycle 這一份
LotusScript 裡跑一個 DocumentCollection,你 Set doc = coll.GetNextDocument(doc) 一路跑到底,從不想記憶體的事。搬到 Java,同一個迴圈跑上萬份文件會把 agent 記憶體吃垮——除非你在迴圈裡 recycle 每一份,而且順序不能錯:得先用當前這份拿到下一份、再 recycle 當前這份。這篇講 Java 版的正確迭代寫法:DocumentCollection 的 getFirstDocument/getNextDocument、刪除標記的 isValid、什麼時候該改用更省的 ViewNavigator,以及那個 LotusScript 從不需要煩惱的 recycle 順序。
2026.08.16 - 在 Java 裡處理 Notes 日期,為什麼不能直接用 java.util.Date?
在 Java 裡處理 Notes 的日期,你不能直接用 java.util.Date——中間隔著一個 lotus.domino.DateTime。它是個背後連著 handle 的重量級後端物件,在迴圈裡不 recycle 就漏記憶體;它用字串在存日期、壞值會丟例外;而 toJavaDate() 是你把它換成 Java 自家時間型別、再接上 java.time 的那座橋。這篇講 Java 版 DateTime 怎麼建、怎麼讀寫、怎麼跟 Java 的時間世界互轉,以及那個從 LotusScript 帶不過來的 recycle 負擔。
2026.08.15 - Java 讀寫 Notes item:getItemValue 回的是 Vector,不是你熟的那種陣列
LotusScript 裡 doc.GetItemValue 回一個 Variant 陣列,你 For 一圈就完事。搬到 Java,同一個呼叫回的是 java.util.Vector,元素型別要自己認、缺欄位不丟例外只回空的、裡面若是 DateTime 還會漏記憶體。這篇把 Java 版 Document 的讀寫 item 講清楚:getItemValue 與那幾個型別化 getter 的回傳與缺欄位行為、replaceItemValue 接受哪些 Java 型別又會自動建 item、appendItemValue 為什麼會默默建出重複 item,以及三個 LotusScript 帶不過來的雷。
2026.08.14 - Domino 14.5.1 FP1 有什麼:RAG 能接遠端模型、49 個修正、JVM 更新
Domino 14.5.1 的第一個 Fix Pack 在 2026-07-16 悄悄上線,官方一句「建議所有客戶安裝」帶過。這篇把它對開發者與管理者最有感的幾點整理出來:RAG 多了 Remote 模式(LLM 可接遠端、向量庫仍在本機)、約 49 個修正裡不少是修回 14.5.1 自己的 regression、JVM 更新到 Semeru 21.0.11+10、兩個 OIDC 安全修正,以及幾個藏在 notes.ini 的小開關。
2026.08.13 - XPages/SSJS:直接用 java.util.Vector 操作多值欄位
LotusScript 沒有 removeElementAt、刪一個多值元素得重建陣列;SSJS 剛好相反——它跑在 Java 上,多值欄位讀進來就是一個 java.util.Vector,addElement/removeElementAt/insertElementAt 整套 API 現成可用,改完用 replaceItemValue 寫回。這篇拆解怎麼用 Vector 操作多值、倒著刪的原理、以及兩個一定會踩的雷(空欄位的 [""]、getValue 的型別)。
2026.08.12 - LotusScript 沒有 removeElementAt:從陣列、List、多值欄位刪一個元素
在 SSJS/XPages 裡刪一個多值元素很順——java.util.Vector 有 removeElementAt,倒著跑迴圈依 index 刪就好。搬到 LotusScript 卻卡住:沒有 Vector、沒有 removeElementAt,而 Erase 對陣列是「整個清空」不是「刪一個」。這篇拆解 LS 的實際選項——先分清你的集合是什麼,再用 Split/Join、陣列重建、List 的 Erase(tag)、或 Evaluate + @Replace。
2026.08.11 - Java agent 的骨架:觸發、權限、輸出、除錯
前三篇都假設「agent 已經在跑」——會 recycle、拿到 Session、跑 DQL。但一個 Java agent 到底怎麼被觸發、用誰的權限執行、System.out 跑去哪、怎麼 debug?這篇補上最前面那一步:AgentBase/NotesMain 骨架、Trigger 與 unprocessedDocuments、agent signer 決定的權限、restricted/unrestricted,以及 System.out 進 log.nsf 的除錯路徑。
2026.08.10 - 在 Java 裡跑 DQL:DominoQuery 與 QueryResultsProcessor
站上的 DQL 三部曲教你寫查詢,但那是從 LotusScript 或 console 跑的。搬到 Java,DQL 走兩個類別:DominoQuery 負責編譯、調校、執行,QueryResultsProcessor 負責排序、彙總、跨庫 join、輸出 JSON。還有一個容易錯的地方——這兩個都從 Database 取得,不是 Session。這篇拆解 Java 端怎麼把 DQL 跑起來。
2026.08.09 - 在 Java 裡拿到 Session:NotesFactory、local 與遠端
LotusScript 的 session 是個你從來不必建立的全域變數;Java 沒有它。碰任何一份文件之前,你得自己先取得一個 Session——而怎麼拿,取決於你的 code 跑在 agent、獨立程式,還是遠端。這篇拆解 NotesFactory 的三條取得路徑、local(JNI) 與遠端(DIIOP) 的差別、誰建誰收的 recycle 規則,以及位元數與每執行緒一個 session 這兩個常見地雷。
2026.08.08 - LotusScript 改寫 Java 後記憶體爆掉?你可能忘了 recycle()
同一段邏輯,LotusScript 跑一輩子都沒事,搬到 Java 版的 lotus.domino 卻會在幾萬份文件的迴圈裡把 agent 記憶體吃垮。原因是每個 Java 物件背後都連著一個垃圾回收看不到的後端 handle。這篇拆解機制、四條官方規則、迴圈洩漏樣式與安全寫法、NotesThread 的角色,以及 local 與遠端 session 的差異。
2026.08.07 - 為什麼同一個 Notes 使用者卻比對失敗?搞懂 NotesName 的三種名稱格式
你拿一個名字去比 session.EffectiveUserName,永遠不相等——明明是同一個人。或者你把某個使用者寫進 Readers 欄位,他還是看不到文件。這兩個都是同一個根因:一個 Notes 名字有三種寫法(canonical、abbreviated、common),而你不小心比到、或存到了不同的兩種。這篇筆記講三種格式各是什麼、Notes 內部存的是哪一種,以及為什麼每次比名字前都該先用 NotesName 正規化。
2026.08.06 - 別再用平行陣列硬刻:LotusScript List 就是內建 HashMap,幾行搞定計數、去重、查表
你要依分類統計文件、把一串名字去重、或建一張「代碼→標籤」對照表,好不用每次都開 view。Domino 開發者的直覺是兩條平行陣列加線性掃描,或臨時開個 view——但 LotusScript 老早就內建一個鍵值集合、卻幾乎沒人用:List。這篇實測筆記講它的鍵值存取、ForAll + ListTag 走訪、Erase,以及兩個雷:讀取要用 IsElement 守著、tag 大小寫跟著 Option Compare 跑。
2026.08.05 - OpenNTF Domino IQ RAG webinar 筆記:30 字元的坑、向量化三步驟,與 FP1 修好的 Readers 安全
OpenNTF 請到 HCL 的 Brian Arnold 做了一場 Domino IQ RAG 深入 webinar。站上已寫過這條管線的技術原理,這篇補上「實戰層」——把短欄位資料 RAG 化的 30 字元限制與 concat 欄位解法、向量化的三個步驟、三個要調的旋鈕、Readers/Authors 欄位安全在 Domino 2026 FP1 才真正修好,以及開發中的 citations、側邊面板與 MCP。
2026.08.04 - @DbLookup 與 @DbColumn:你沒在傳的那個 cache 關鍵字,與 64K 那道牆
有人改了一份 keyword 文件、重載表單,下拉還是顯示舊值。或者一份 keyword 清單長到幾千筆就悄悄不再長,直到某筆查不到才有人發現。這兩個都不是 Domino 隨機出包,而是 @DbLookup / @DbColumn 兩個有文件記載的行為,藏在多數公式忽略的地方:cache 關鍵字,與 64KB 上限。一篇關於這兩者的實測報告 —— 三種 cache 選項(預設/NoCache/ReCache)、以及這些函式回傳量的硬上限 64KB,配上 classic web 各自踩雷的情境。
2026.08.04 - 你的 agent 是用誰的身分在跑?signer、effective user,與 Error 201/Readers 欄位的雷
你的 agent 跑得好好的 —— 因為是你這個 admin 簽的。把它部署成 web agent、或用服務帳號 ID 簽了排程,它就壞了:Error 201,或者更糟 —— 一份文件都沒處理卻不報錯。原因是身分:Domino agent 是用某個人的身分在跑,而那個人不一定是你。一篇關於 signer 對上 effective user 的實測報告:session.EffectiveUserName 怎麼隨「run as web user」翻轉、Error 201 背後的 runtime security level、以及那個讓文件憑空消失的 Readers 欄位雷。
2026.08.03 - NotesUIScheduler:用 LotusScript 驅動內嵌的 free/busy 排程格
一張自訂的會議室預約或會議表單上有內嵌排程控制項 —— 那個你放進與會者、看大家 free/busy 的忙碌時間格。NotesUIScheduler 就是你用程式驅動那個控制項的方式:從 UI 文件用名稱取得它、加或移除與會者、刷新排程資料、讀回使用者選的時段。一篇關於唯一那個前端排程類別的實測報告 —— 它的 GetScheduleData 刷新、以及你會掛的兩個事件。
2026.08.02 - Button、Field、Navigator:三個沒有屬性、沒有方法的 LotusScript 類別
打開 Button 的 LotusScript 說明,你以為會有屬性和方法 —— 一個都沒有。Field 一樣、Navigator 也一樣。三個都是故意做空的:它們只作為事件的進入點存在,也就是那個「告訴前端事件 handler 是誰觸發了它」的具名 Source 參數。一篇關於「你永遠不會對它呼叫任何東西」的三個類別的實測報告 —— 它們的事件是什麼(Click、Entering/Exiting/OnChange),以及為什麼真正的工作永遠是透過 NotesUIDocument。
2026.08.01 - LotusScript web agent 的 I/O 模型:Print 是你的回應,DocumentContext 是你的請求
一個 LotusScript web agent 沒有 request 物件、也沒有 response 物件 —— 它有 Print,輸出變成 HTTP body,還有 DocumentContext,一份裝著 CGI 變數的特殊文件。一篇兩半模型的實測報告:第一行 Print 怎麼設 Content-Type、讓你回 JSON 而不是 HTML,怎麼從 DocumentContext 讀 query string 與 POST body,那個讓它們變空的 CGI-欄位陷阱,以及這一切怎麼跟一個頂層錯誤 handler 兜起來。
2026.07.31 - DXL round-trip 陷阱:為什麼匯出再匯入給你的是重複文件、不是同一批文件
你把文件匯出成 DXL、把 DXL 匯入另一個資料庫,結果拿到的是一批帶著全新 UNID 的副本、而不是同一批文件在原地更新 —— 因為匯入器預設是「建立」,只有在你明講時才按 UNID 比對。一篇 DXL round-trip 的實測報告:決定 create 還是 replace 的 DocumentImportOption、為什麼預設的 rich text 不是位元一致(以及何時該切到 RAW)、還有那個把整件事藏起來的 stale-handle 陷阱。
2026.07.30 - LotusScript 錯誤處理:On Error 是逐程序的,Resume Next 不是「忽略錯誤」
兩個習慣毀掉了多數 LotusScript 錯誤處理:把 On Error 當成全域的(它是逐程序的,沒被接住的錯誤會往呼叫堆疊上爬),以及把 On Error Resume Next 當成一鍵「忽略所有錯誤」的開關(它藏起 bug、不是處理它)。一篇刻意做對的實測報告 —— 逐程序的作用範圍、Err/Error$/Erl 的生命週期、Resume 與 Resume Next 與 Resume label 的差別,以及一個 web agent 真正需要的乾淨錯誤樣式。
2026.07.29 - NotesUIDatabase:攔下一個刪除的唯一地方
在 Notes client 裡,使用者可以從任何 view、用 Delete 鍵、用剪下、或拖進垃圾桶刪掉一份文件 —— 你沒辦法一條路一條路去守。NotesUIDatabase 是看得見全部路徑的單一 chokepoint:它的 QueryDocumentDelete 事件在任何東西被標記刪除之前,整個資料庫觸發一次。一篇前端資料庫類別的實測報告 —— 通往後端的 Database 橋、刪除/封存事件,以及你掛在「那個攔得住每條路的事件」上的軟刪除守衛。
2026.07.28 - Save(True, False) 還是 Save(False, True):決定誰的資料會不見的兩個布林值
兩個程序動到同一份文件 —— 一個 web agent 和一個開著表單的使用者,或一個排程 agent 和一個 replica。一邊的儲存贏,另一邊的編輯要嘛消失、要嘛變成一份沒人發現的 $Conflict。發生哪一種,完全由你傳給 NotesDocument.Save 的那兩個布林值決定。一篇關於 force 與 createResponse 的實測報告:last-write-wins 對上 replicator 產生的衝突文件、為什麼 Save(True, False) 會靜默丟資料、以及怎麼刻意地選對。
2026.07.27 - NotesUIView:唯一知道使用者選了什麼的類別
view 上的動作按鈕理應對使用者反白的那幾列作用 —— 但後端的 NotesView 根本沒有「選取」這個概念。那道缺口,正是 NotesUIView 填的。一篇前端 view 類別的實測報告:它的 Documents 屬性(活的選取狀態)、通往後端 View 的橋、你用來攔截使用者的 QueryOpenDocument/QueryClose 事件,以及那條把這一切擋在 web 與 agent 之外的硬邊界。
2026.07.26 - 你永遠不會 new 出來的 NotesDOM 節點:唯讀的 DTD 角落
NotesDOM 實作了完整的 W3C 節點模型,這代表有四種節點型別存在於多數 XML 開發者從不碰的 DTD 角落:DocumentType、Entity、EntityReference、Notation。一份簡短地圖 —— 它們是什麼、哪一個你真的能建立(EntityReference)、哪些是已解析 DTD 的唯讀反映、以及為什麼在 2026 年你多數時候可以直接走過它們,外加那個「知道它們存在能省下一個下午」的情境。
2026.07.25 - NotesDOM 你略過的那些節點 —— 直到一次 round-trip 把註解吃掉
你用 NotesDOMParser 建好了處理 element 與 text 節點的流程。然後來了一份帶註解、CDATA 區塊、processing instruction 的 XML,你改一個值、序列化回去 —— 註解和 PI 不見了,CDATA 變成被跳脫的純文字。一篇 NotesDOM 節點家族長尾的實測報告:NodeList 那個 1-based 的 GetItem(不是 W3C 的 0-based item())、用來批次插入的 DocumentFragment,以及你得自己建立、才留得住的 CDATA/註解/processing instruction 節點。
2026.07.24 - Domino Web View 翻頁的真相:Start 不是流水號,是階層座標
「我以為 Start=31 就是第 31 列,然後我錯了。」一篇 classic view ?OpenView Start 參數的除錯實測報告:純數字跳到第 N 個最上層分類、像 1.1.1.1.6 的點號值是階層座標、末段會 clamp 但中段不會、而你沒辦法用一個 URL 跳到絕對最後一頁。外加三個實用應用 —— 分類內序號、@DocNumber("")(含必須單獨使用的地雷)、以及用 ReadViewEntries 做麵包屑。
2026.07.23 - 你的 Domino view 表頭為什麼永遠歪一格:passthrough HTML 黑魔法考古
接手一個老 classic-web Domino view,你常會發現直欄標題整體往右偏一格 —— 而且沒人知道為什麼。一篇實測報告,挖出藏在二十年前 view 設計裡的 passthrough HTML 把戲:直欄值與標題裡的方括號 HTML、間隔欄、每列 checkbox,以及真正的元兇 —— 一個故意不閉合的 <input 標籤吞掉 </td><td> 欄界線、把兩個直欄合併成一格,讓它之後的每個表頭都往右偏。
2026.07.22 - DQL 跳「Domino Query 執行時錯誤」怎麼辦:三層診斷階梯
一個 DQL 查詢失敗,你看到「Domino Query 執行時錯誤:」後面接一大串文字。一篇讀懂這個訊息的實測報告:你在 Err 裡找到的 4854 對診斷毫無用處(每個 DQL 失敗都回它),答案永遠在「詳細原因」那一行。涵蓋四段訊息結構、三層階梯(catalog / view 沒建 / partial TIMEDATE)、讓查詢時好時壞的 design catalog 半殘、以及「0 筆且無錯誤」的排查清單。
2026.07.21 - DQL view 日期直欄查詢:型別與時區怎麼無聲吃掉你的結果(三個成因)
「直欄轉成日期反而有些抓得到有些沒抓到,蠻怪的。」一篇實測報告:一個 DQL view 直欄日期查詢結果不一致,拆開來發現有三個獨立成因。DQL 從不自動轉型(所以直欄的輸出型別要跟查詢詞相符)、底層欄位存了文字與日期混型、而 @dt 不帶時區位移就是 UTC——它會在不改變總筆數的情況下弄壞邊界文件。兩個解法皆實測 6/6 全中。
2026.07.20 - NotesXSLTransformer:用 LotusScript 以 XSLT 轉換 XML 與 DXL
NotesXSLTransformer 把 XSLT stylesheet 套到 XML 或 DXL 上、寫出轉換結果 — 是 Domino XML 工具組裡繼 DOM 與 SAX parser 之後的最後一塊。本文說明 session.CreateXSLTransformer 與它的三種來源、stylesheet 必須是 stream 的規則、把 DXL export → 轉換 → import 串起來而不落暫存檔的 pipelining 模型、以及那個透過 Log 屬性與 On Error(而非事件)運作的錯誤處理。
2026.07.19 - NotesJSONNavigator:LotusScript 原生 JSON 解析,不必再做字串手術
在 Domino 10.0.1 之前,用 LotusScript 解析 JSON 意味著 Evaluate 花招或手刻的字串手術。NotesJSONNavigator 用一個真正的 parser 取代了那些:session.CreateJSONNavigator 給你一棵可用 GetElementByName、GetNthElement、JSON Pointer 路徑導覽的型別化樹。本文說明 navigator、element/object/array 類別、型別常數,以及命名上的意外(是 GetFirstElement 不是 GetFirstItem;AppendElement 是 value 在前 name 在後)。
2026.07.18 - 用程式管理全文索引:CreateFTIndex、UpdateFTIndex,與本機 vs 伺服器的分界
FTSearch 要快、要能用萬用字元與相關性排序,就需要全文索引 — 而 NotesDatabase 能用 LotusScript 建立、更新、移除索引。陷阱是一個幾乎沒人料到的分界:CreateFTIndex / UpdateFTIndex / RemoveFTIndex 只對本機資料庫有效,而 FTIndexFrequency 只對伺服器有效,伺服器索引其實是由 Updall 工作管理的(updall -X 是重建、不是建立)。本文說明 options bitmask、create 與 update 的差別、以及那個分界。
2026.07.17 - LotusScript 的文件鎖定:Lock、LockProvisional,與每個人都忘記的前置條件
Domino 能鎖定一份文件、讓兩個使用者不會同時編輯它 — NotesDocument 上的 Lock、LockProvisional、UnLock、LockHolders。但這些方法會拋錯,除非資料庫啟用了鎖定(IsDocumentLockingEnabled)而且設好了 master lock server;persistent 與 provisional 鎖取決於那台伺服器是否可達;而鎖在 web 應用裡根本不能用。本文說明 API 與每個前置條件。
2026.07.16 - NotesDocument.ComputeWithForm:用程式跑表單驗證 — 以及為什麼它擋不住你的 Save
ComputeWithForm 把表單的預設值、輸入轉換、輸入驗證公式跑在後端文件上 — 相當於使用者在表單上按存檔時觸發的驗證。但三件事會讓人意外:它回一個它從不強制執行的通過/失敗旗標(它照樣讓你把無效文件存進去)、輸入轉換公式可能改寫你的欄位值、而且除非你釘住 Form item、它會悄悄退回預設表單。
2026.07.15 - LotusScript 的回應文件:MakeResponse、ParentDocumentUNID,與遍歷整棵串
Domino 的父子文件階層 — 主文件、回應、回應之回應 — 用幾個 NotesDocument 成員就能建立與遍歷。本文說明 MakeResponse(以及你必須在它之後呼叫的 Save)、用 ParentDocumentUNID 往上走到父文件、以及 Responses 屬性那個關鍵限制:它只回傳直接子文件 — 所以完整的樹需要遞迴。
2026.07.14 - NotesDateTime 與時區:GMTTime、ConvertToZone,與那個絆倒每個人的正負號慣例
一個 NotesDateTime 是單一個瞬間,你可以用三種方式讀出來 —— GMT、機器的本地時間、以及轉換後的時區。本文說明 GMTTime vs LocalTime vs ZoneTime、TimeZone 整數那個反直覺的 Notes 正負號慣例(正值代表 GMT 以西)、ConvertToZone 與它的 DST 陷阱、用 LSGMTTime 做原生日期運算,以及為什麼 GMTTime 是唯一能跨機器安全儲存與比較的形式。
2026.07.13 - 用 LotusScript 簽章與加密文件:Sign、Encrypt,與 Save 的順序規則
Domino 能簽章一份文件以證明是誰寫的、能加密 item 讓只有持金鑰的人讀得到 —— 兩者都能用 LotusScript 做、也都有陷阱。本文說明 NotesDocument.Sign 與它在伺服器 agent 需要的權限、Encrypt 那個必要的「標記 item / Encrypt / Save」順序、逐 item 選擇性加密,以及為什麼 EncryptOnSend 跟「加密儲存的副本」是完全兩回事。
2026.07.12 - Profile documents:Domino 的快取式設定儲存區,以及那個快取為什麼會咬人
profile document 是一份隱藏、在 view 裡看不到、以名稱(與可選的使用者)為鍵的文件 —— 很適合放應用設定與個人偏好,而且因為有快取所以很快。本文說明 GetProfileDocument、IsProfile / NameOfProfile / Key 屬性、透過 unique key 做個人化 profile,以及快取造成的陷阱:另一個程序的寫入可能對你已開啟的 session 看不見,而且沒有 refresh API 能強制重讀。
2026.07.11 - 用程式做 Readers 與 Authors 欄位:靠一個 NotesItem 旗標設定的文件層級安全
Domino 的文件層級存取控制不是什麼特殊 API —— 它就是一個帶旗標的普通 item。本文說明怎麼在 LotusScript 用 ReplaceItemValue 加上 NotesItem.IsReaders / IsAuthors 建立 Readers 與 Authors 欄位、安全模型(沒有 Readers item = 所有人可見;有 Readers item = 只有列出的人)、以及鎖死陷阱:把自己和 agent 漏在清單外,你會把一份文件對所有人藏起來,包括產生它的那段程式。
2026.07.10 - 多層分類 view 裡的 GetAllDocumentsByKey:為什麼你的 count 悄悄就錯了
在單層分類 view,GetAllDocumentsByKey('Belgien', True) 正確回傳那個分類下的 2 筆文件。但加上第二層分類 — Form 再 Country — GetAllDocumentsByKey('Customer', True) 回傳 3,不是全部。它停在第一個子分類就不走了。本文記錄這個實測驗證過的陷阱與繞法。
2026.07.09 - NotesStream 與文字編碼:字元集、BOM,與位元組 vs 字元的陷阱
NotesStream 讀寫檔案,但只要你的文字不是純 ASCII,三件事就會咬人:你用哪個字元集開的、有沒有寫進 BOM,以及 Position 是位元組位移、而且「不支援多位元組字元」。本文說明 Open 的字元集參數、EOL 常數、WriteText 到底何時寫 BOM(UTF-16 會、UTF-8 不會),以及為什麼 Bytes 永遠不等於 Len()。
2026.07.08 - LotusScript 處理附件:EmbedObject、NotesEmbeddedObject 與 GetAttachment 捷徑
附加一個檔案、列出附了什麼、把它抽取到磁碟、再移除它 —— 全部用程式做。本文說明 NotesRichTextItem.EmbedObject 搭配 EMBED_ATTACHMENT 常數、NotesEmbeddedObject 類別、ExtractFile,以及兩個絆倒人的陷阱:NotesDocument.EmbeddedObjects 不會回傳檔案附件(要用 GetAttachment 或 rich text item),而 ExtractFile 對非附件的東西會出錯。
2026.07.07 - HCL Sametime 12.0.3 帶來了什麼:已讀回條、會議逐字稿,與一個 Domino 授權包的變動
HCL Sametime 12.0.3 —— 2025 年發布 —— 是一個值得回頭看的 point release,尤其如果你的環境還沒升級:聊天已讀回條、行動裝置聊天搜尋、會議錄影自動轉逐字稿、一輪完整的無障礙改善,以及以 HCL Enchanted + React 重建的 UI。對 Domino 管理員最有份量的變化其實不是功能 —— 而是 premium 聊天能力被併進了標準的 Domino Complete Collaboration Bundle。
2026.07.06 - LotusScript 裡的 XML 宣告、DTD 節點與 SAX 錯誤
Domino DOM 裡很少見的那一層 —— XML 宣告、DOCTYPE、processing instruction、notation、entity —— 加上 SAX 那一側的 NotesSAXException。本文說明每個節點實際給你什麼(多半:沒什麼)、你必須先設好才看得到宣告的 AddXMLDeclNode 旗標,以及為什麼 NotesSAXException 是解析出錯時唯一能拿到含行列號豐富錯誤資料的地方。
2026.07.05 - 承載內容的 DOM 節點:LotusScript 的 TextNode、AttributeNode、Comment、CDATASection
當你開始巡覽解析後的 DOM,真正的資料住在內容節點裡 —— 文字、屬性、註解、CDATA。本文說明繼承關係(CharacterData 是 Text/Comment/CDATA 的基底;CDATA 衍生自 Text;AttributeNode 自成一格)、CharacterData 的編輯方法,以及最大的陷阱:LotusScript 繫結是透過 NodeValue 讀內容 —— 沒有 W3C 風格的 Data、Length、Name 或 Value 屬性。
2026.07.04 - 用 LotusScript 巡覽解析後的 XML DOM:DocumentNode、ElementNode、NodeList、NamedNodeMap
NotesDOMParser 把 XML 解析完之後,你用一組節點類別來導覽結果。本文說明怎麼從 domParser.Document 取得根、用 DocumentElement 抵達根元素、用 GetElementsByTagName 查詢(回傳 NotesDOMNodeList)、透過元素的 NamedNodeMap 讀屬性,以及 LotusScript 特有的眉角:GetItem 是 1-based、沒有 ChildNodes 屬性(用 FirstChild/NextSibling 走)、也沒有 GetItemByName。
2026.07.03 - NotesRichTextDocLink 與 NotesRichTextSection:用程式做 doclink 與摺疊區段
兩個你平常會在 Designer 裡手動插入的 rich-text 功能 —— 跳到資料庫/view/文件的 doclink,以及可摺疊區段 —— 都能用程式做。但這兩個類別都不是你 New 出來的:你透過 NotesRichTextItem(AppendDocLink、BeginSection/EndSection)建立元件,再透過 NotesRichTextNavigator 讀回來。本文說明這個「寫用一套 API、讀用另一套」的拆分、doclink 屬性、BeginSection/EndSection 規則,以及陷阱。
2026.07.02 - NotesRichTextParagraphStyle、NotesRichTextTab 與 NotesColorObject:用程式排版 rich text
用 LotusScript 產 rich text 不只是接字串 —— 邊界、對齊、行距、tab 停點、顏色都是你在「加文字之前」蓋上去的獨立物件。本文說明 NotesRichTextParagraphStyle(版面)、NotesRichTextTab(tab 停點,由 style 唯讀生出)、NotesColorObject(色彩運算)、twips 度量、「先蓋 style 再加文字」規則,以及那個不直覺的點:NotesColorObject 不會直接幫文字上色 —— 你是用它推算出一個 Domino 色值。
2026.07.01 - NotesInternational:別再寫死日期分隔符號和貨幣符號
NotesInternational 是一扇唯讀的窗,讓你看見程式所在那台機器的地區設定 —— 日期順序、分隔符號、上午/下午字串、貨幣符號與格式、時區、以及 DST 旗標。本文說明怎麼從 session.International 取得、值得知道的屬性分組、一段偵測地區日期順序的可跑範例,以及三個陷阱:它反映的是執行端 OS(不是終端使用者)、它是唯讀的、而它的 TimeZone 正負號是經典又反直覺的 Notes 慣例。
2026.06.30 - NotesAdministrationProcess:用 LotusScript 送出 AdminP 請求
改使用者名稱、乾淨地刪除一個使用者、重新認證、搬移郵件檔、改 Internet 密碼 —— 這些平常你會在 Administration 用戶端點來點去的 AdminP 工作,NotesAdministrationProcess 讓你用程式把同樣的請求送進 admin4.nsf。本文說明 session.CreateAdministrationProcess、各請求方法與它們回傳的 note ID、certifier 屬性,以及三個最常絆倒人的點:它需要 unrestricted 權限、它是非同步的、而 '*' 代表「不變更」。
2026.06.29 - NotesTimer:在 Notes client 裡每隔幾秒觸發一次事件
想在 Notes client 開著的畫面上每隔幾秒做一件事 — 自動刷新 view、輪詢有沒有新信、更新一個狀態顯示?NotesTimer 就是這個:建立時給一個秒數間隔,它就週期性觸發 Alarm 事件。本文拆解建立、Interval / Enabled / Comment 屬性、用 On Event 綁事件處理,以及四個一定要知道的限制:只能在 UI 不能在 agent、要宣告在全域、handler 必須在間隔內跑完、預設就是啟用。
2026.06.28 - NSF ODP Tooling:不開 Designer,把 NSF 變成可版控的原始碼
NSF ODP Tooling 是 OpenNTF 的專案,把二進位的 NSF 拆成檔案系統上的 On-Disk Project(ODP),讓你能把 Domino 應用放進 Git,再不靠 Domino Designer 就把 ODP 編譯回完整的 NSF —— 為 Domino 帶來真正的版本控制與 CI/CD。本文完整介紹它是什麼、Maven plugin 與容器化編譯怎麼運作,以及 4.1.0 這一版實際改了什麼。
2026.06.27 - NotesPropertyBroker / NotesProperty:Composite Applications 的元件溝通機制
Composite Applications 是 Notes 8.x 時代的功能 — 把多個元件(Notes 元件、Java/Eclipse 元件)拼在同一個畫面上、讓它們互相傳值。NotesPropertyBroker 就是中間那個傳遞層,NotesProperty 是被傳遞的單一屬性。本文老實交代這組類別的定位(偏 legacy)、GetPropertyBroker 怎麼取得、GetPropertyValue / SetPropertyValue / Publish / HasProperty 各方法、InputPropertyContext,以及它在今天的實際意義。
2026.06.27 - NotesViewColumn:用程式讀一個 view 有哪些欄、各自的公式與排序
你想盤點一個 view 有哪些欄、每欄是欄位還是公式、有沒有排序或分類、哪些被隱藏 — 不用開 Designer,用 NotesViewColumn 就能在程式裡讀出來。本文拆解從 view.Columns 取得、Title / ItemName / Formula / Position / IsSorted / IsCategory / IsHidden / IsField / IsFormula 等屬性,以及它跟先前 NotesViewEntry 的 ColumnValues 怎麼對應(同一個 Position 索引)。
2026.06.26 - NotesIDVault:用程式從 ID Vault 取 ID、同步、重設密碼
ID Vault 是 Domino 用 policy 集中保管使用者 ID 檔的機制。NotesIDVault 讓你用程式操作它 — 從 vault 取出某使用者的 ID 檔、把本機 ID 同步回 vault、檢查某人 ID 在不在 vault 裡、甚至重設 vault 密碼。本文拆解它的取得、GetUserIDFile / SyncUserIDFile / IsIDInVault / ResetUserPassword / PutUserIDFile 各方法、跟 NotesUserID 的關係,以及這些操作的權限前提。
2026.06.25 - NotesRichTextTable:在程式裡往 rich text 塞一個表格
你在程式裡用 NotesRichTextItem 組一封 rich text 信或文件,需要一個表格來排版摘要或報表 — NotesRichTextItem.AppendTable 建出來的就是 NotesRichTextTable。本文拆解怎麼建立、RowCount / ColumnCount、AddRow / RemoveRow、SetColor / SetAlternateColor 交替色、RightToLeft,以及怎麼用 NotesRichTextNavigator 走訪既有表格與一個關鍵限制:不知道 rich text 的確切結構,就讀不出儲存格內容。
2026.06.24 - NotesDXLImporter:把 DXL 灌回 Domino,設計元素 / 文件 / ACL 各有匯入策略
你用 NotesDXLExporter 把設計或文件匯出成 DXL(Domino XML)之後,怎麼把它灌回資料庫?NotesDXLImporter 就是反向那一半。本文拆解它的建立、三個關鍵匯入策略(DesignImportOption / DocumentImportOption / ACLImportOption 各自的 create / ignore / replace / update)、Import 方法與取回匯入 note 的方式,以及它跟 DXLExporter 怎麼組成完整的 DXL round-trip。
2026.06.23 - NotesViewEntry × NotesViewEntryCollection:不開文件就高效讀 view 的每一列
要把一個 view 裡每份文件的某些欄位值讀出來,很多人迴圈跑文件、逐筆 GetItemValue — 但那會把每份文件都打開,幾千筆就很慢。NotesViewEntry 讓你直接讀 view 已經算好的 ColumnValues、完全不開文件;NotesViewEntryCollection 是這些列的集合,還能跳過分類/總計列、做集合運算與 StampAll 批次蓋章。本文拆解這對「高效讀 view」的搭檔、ColumnValues 的效能關鍵、entry 的身份與階層屬性。
2026.06.22 - 開發者很少注意的 ODS:Domino 資料庫格式版本演進,與「什麼時候會升、由什麼決定」
你整天寫 LotusScript / XPages,大概從來沒在意過資料庫的 ODS(on-disk structure)版本 — 直到某個功能(像 LargeSummary)需要特定 ODS,或你把一顆舊 DB 在 server 之間搬動,搞不清楚 ODS 會不會跟著變。本文從開發者角度整理 ODS 的版本對應、最反直覺的一點(升 server 版本不等於升 ODS),以及 ODS 到底「什麼時候會變、由什麼決定」,最後回答一個具體情境:R9 的 ODS51 資料庫用 R12 client 新複製到 R12 server,ODS 會自動異動嗎?
2026.06.21 - 「Field is too large (32K)」在騙你:真正的牆通常是 64K summary buffer
一個 XPages 存檔錯誤:訊息寫「32K」,但你檢查每個欄位都沒破 32K(最大才 26K),照樣存不了。因為它指的數字常常不是你的問題 — 真正撞到的是「整份文件 summary 資料合計 64K」這道牆。本文先建立 summary / non-summary 與兩道大小限制的心智模型,再講 ODS 與 LargeSummary 為什麼是兩件事,最後用「這資料該不該是 summary」這個問題分流出兩種解法。
2026.06.21 - LotusScript 的 Evaluate:在程式裡直接跑 @formula
有時候你心裡那個剛好的工具是一個 @function — @Name、@Unique、@Explode、@DbLookup — 但你人在 LotusScript 裡。Evaluate 就是那座橋:把 @formula 當字串丟進去、在程式裡執行、拿回結果。本文拆解兩種呼叫形式(帶不帶 document context)、一個一定會踩的陷阱(回傳值永遠是陣列),以及哪些 @function 不支援(@Command、@Prompt、@PickList 等 UI 類)。
2026.06.20 - NotesRichTextStyle:在程式裡設定粗體、字級、顏色(兼談 STYLE_NO_CHANGE)
你在程式裡用 NotesRichTextItem 組 rich text,想讓某段變粗體、放大、換顏色 — 那個「樣式」就是 NotesRichTextStyle。本文拆解它怎麼建立、Bold / Italic / FontSize / NotesColor 等屬性、用 AppendStyle 與 SetStyle 套用,以及一個關鍵設計:新建的 style 所有屬性預設都是 STYLE_NO_CHANGE(不更動),你只需要設你想改的那幾個、其餘維持原樣。
2026.06.19 - NotesNewsletter:把一堆文件變成一封含 doclink 的摘要信
你想做一個「每日摘要」或「搜尋結果通知」 — 把符合條件的一堆文件,整理成一封信寄給使用者,信裡每一筆都能點回原文件。這正是 NotesNewsletter 的工作:吃一個 NotesDocumentCollection,用 FormatMsgWithDoclinks 產生一封含 doclink 的摘要信,或用 FormatDocument 逐筆渲染。本文拆解它的建立、DoScore / DoSubject / SubjectItemName 屬性、兩個 Format 方法的差別,以及搭配 FTSearch 的經典寄信範例。
2026.06.18 - NotesForm:用程式讀一個資料庫有哪些表單、欄位、誰能用
你接手一個沒文件的 NSF,想先搞清楚它有哪些表單、每個表單有哪些欄位、誰被允許建立文件 — 不用打開 Designer,用 NotesForm 就能在程式裡把這些設計資訊讀出來。本文拆解從 db.Forms / db.GetForm 取得表單、Name / Aliases / Fields / FormUsers / Readers 等屬性、GetFieldType 與 Remove,以及 ProtectReaders / ProtectUsers 跟複寫的關係。
2026.06.17 - 回顧 HCL Volt MX v10「Darwin」:Figma 直接變 App、AIAD、CarPlay
HCL 在 2025 年 8 月發佈了低程式碼平台 Volt MX 的 v10、代號「Darwin」。這不是最新消息、是一篇補課用的背景介紹 — 把這一版的重點整理給 Domino 開發者:用 GenAI 把 Figma 設計直接轉成 app、AIAD(AI Assisted Dev)讓 RAG 加持的 Volt IQ 幫你生程式與查文件、CarPlay / Android Auto 車機支援、Passkeys、iOS Live Activities 等。並說明它跟 Domino 的關係:Volt MX Go 是與 Domino 綁定的版本,而 Volt IQ 的 RAG 路線跟 Domino IQ 同源。
2026.06.16 - HCL Nomad web 1.0.20:Kiosk Mode 把 Domino app 鎖成單一應用
截至 2026-06 寫稿時,HCL Nomad for web browsers / Nomad server on Domino 的最新版是 1.0.20。最值得注意的新功能是 Kiosk Mode — 指定一個資料庫開機就跑、不准關閉、其餘介面可隱藏或鎖定,讓你把既有的 Domino 應用直接變成瀏覽器上的單一用途終端(接待櫃台、產線、自助機)。另外 1.0.20 也補上了 Firefox 的檔案匯出支援。本文整理 1.0.20 的重點,並把它放回 1.0.18→1.0.20 這段 Enchanted 設計改版的脈絡裡。
2026.06.15 - NotesDbDirectory:列出 server 上的每一個資料庫
想寫一支 agent 掃過伺服器上所有 NSF、檢查每個 db 的 ACL 或大小?那是 NotesDbDirectory 的工作 — 別跟先前介紹過的 NotesDirectory(查 Domino Directory 裡的人與群組)搞混,兩個都叫 Directory 但做的事完全不同。本文拆解 GetDbDirectory 建立、GetFirstDatabase / GetNextDatabase 走訪、四個 file-type 常數、Open / CreateDatabase / OpenDatabaseByReplicaID 等方法,以及最容易中的坑:走訪拿到的 NotesDatabase 預設是「關閉」的,必須先 Open 才能用。
2026.06.14 - OpenNTF 把首頁 app 搬出 Domino:純靠 DRAPI 跑在 Open Liberty 上
Jesse Gallagher 把 OpenNTF 的首頁 app 從 XPages 改寫成 Jakarta EE,資料層完全走 DRAPI(Domino REST API),最後把它打包成 WAR、部署到 Open Liberty — 跑在 Domino 之外。這件事的意義不是「又一個改寫」,而是它驗證了一條路:為 Domino 寫的 Jakarta EE app 可以是可攜的,資料留在 NSF、執行環境卻不綁 Domino。本文整理他做了什麼、技術堆疊、為什麼值得關注,以及他自己點出的幾個還很粗糙的地方。
2026.06.13 - NotesAgent:用程式呼叫另一支 Agent(Run vs RunOnServer)
你有一支很重的處理 agent,想讓另一支 agent、或一個按鈕在需要時觸發它 — 不是用排程、是用程式直接叫起來。NotesAgent 就是做這件事的類別:db.GetAgent() 拿到 agent,再用 Run 或 RunOnServer 跑它。本文拆解這兩個方法最關鍵的差異(在 client 跑還是在 server 跑)、怎麼用 noteID 把一份文件傳給被呼叫的 agent、IsEnabled / Trigger / Target 等屬性,以及四個限制:不能遞迴、不能 debug、使用者不能互動、輸出只進 Domino log。
2026.06.12 - NotesRichTextNavigator × NotesRichTextRange:用程式走訪與改寫 Rich Text
你有 500 份文件的 Body 欄位,要找出每一個 doclink、或把某個字串全部換掉 — 光靠 NotesRichTextItem 拿到整個欄位還不夠,你需要更細的工具。NotesRichTextNavigator 讓你依「元素型態」一個一個走訪 rich text,NotesRichTextRange 讓你選定一段、然後套樣式或刪除。本文拆解這兩個 Release 6 起的搭檔、element-type 常數、FindAndReplace 的選項與回傳值,以及一個踩了就 debug 半天的鐵則:FindAndReplace 之後所有 navigation marker 全部失效。
2026.06.11 - NotesUIWorkspace × NotesUIDocument:LotusScript 的前端自動化
站上前面拆過的 NotesDatabase、NotesDocument 都是後端類別 — 但當你要在使用者按下按鈕的當下、讀他「螢幕上還沒存檔」的欄位值、跳一個對話框問他、或把當前文件切到編輯模式,靠的是另一半:NotesUIWorkspace 與 NotesUIDocument。本文拆解這組前端雙人組、最關鍵的「前端值 vs 後端 Document」觀念、FieldGetText/FieldSetText、Prompt 與 PickList 對話框,以及一個最容易忘的鐵則:UI class 不能在背景 / 排程 agent 裡跑。
2026.06.10 - NotesName:別再用字串切 Domino 階層名稱
要從 CN=王小明/OU=Sales/O=Acme/C=TW 取出「王小明」,你還在用 Mid、InStr、@Name 硬切字串嗎?NotesName 是 Domino 內建的名稱解析類別 — session.CreateName() 一句,就能在 canonical、abbreviated、common、Internet(RFC 821/822)各種格式間互轉,並逐段拆出 O / OU / C / G / S 等元件。本文拆解全部唯讀屬性、三種格式互轉、flat name 與 Internet 名稱的行為差異、以及「abbreviation 會有歧義時不縮寫」這個容易忽略的規則。
2026.06.09 - Nomad 定位三件組:NotesGPS / NotesGPSPosition / NotesGPSCoordinates
傳統 LotusScript 沒有定位 API — 但跑在 HCL Nomad 上的 app 其實拿得到使用者的經緯度。NotesGPS 是 Domino 為 Nomad 補上的客戶端定位類別,從 NotesSession.CreateGPS() 起手,經 RequestAccess() 取得授權、GetCurrentPosition() 拿到 NotesGPSPosition、再從 Coordinates 讀出 NotesGPSCoordinates 的 Latitude / Longitude。本文拆解這條三類別鏈、官方範例逐行解說,以及 error 4508、iOS 首呼叫 Speed/Heading 為空、HighAccuracy 室內失準等幾個一定要知道的坑。
2026.06.08 - NotesLog:LotusScript Agent 的 Production Logging
LotusScript 的 Print 語句只在 Designer debug 視窗出現、production agent 跑完沒有任何紀錄。NotesLog 是 Domino 內建的 logging class — 可以把 action 跟 error 記到 agent log、指定 NSF、或寄郵件。本文拆解四種 Open 方式(OpenAgentLog / OpenFileLog / OpenMailLog / OpenNotesLog)、LogAction 跟 LogError 的呼叫格式、NumActions / NumErrors 計數、OverwriteFile 控制是否覆蓋、跟一個可以直接拿來用的 production agent logging 範本。
2026.06.07 - NotesReplication + NotesReplicationEntry:用 LotusScript 管理資料庫複製設定
Domino 的複製(Replication)是讓多台伺服器資料同步的核心機制,每個 NSF 都有一份複製設定。LotusScript 的 NotesReplication class 讓你用程式讀寫這份設定 — 暫停 / 恢復複製、調整優先等級、設定截止日期過濾、清除複製歷史。NotesReplicationEntry 則管理「這個 NSF 跟哪台伺服器之間的複製規則」。本文拆解取得方式(db.ReplicationInfo)、IsDisabled / Priority / Abstract 屬性、ClearHistory 清歷史、GetEntry 取特定伺服器對的規則、以及 Save 呼叫的必要性。
2026.06.06 - NotesDirectory + NotesDirectoryNavigator:LotusScript 查詢 Domino 目錄
Domino 目錄(Domino Directory)是整個 Notes 環境的使用者資料庫 — 人員、群組、伺服器都在裡面。LotusScript 的 NotesDirectory 提供高層次的查詢 API(不需要自己開 names.nsf 走 view)。本文拆解取得方式(session.GetDirectory)、LookupNames 依名稱查詢指定欄位、LookupAllNames 掃全部、GetMailInfo 取郵件伺服器資訊、CreateNavigator 建立 NotesDirectoryNavigator 走訪快取結果、以及 SearchAllDirectories / LimitMatches 兩個影響效能跟結果數量的屬性。
2026.06.05 - NotesMIMEEntity + NotesMIMEHeader:LotusScript 解析郵件 MIME 結構
Domino 收到的郵件是 MIME 多層巢狀結構 — HTML body、純文字備用、附件、inline image 各自是不同的 MIME entity。LotusScript 用 NotesMIMEEntity 代表每一個節點、NotesMIMEHeader 代表節點的 header 欄位。本文拆解取得方式(session.ConvertMIME = False 的必要性)、ContentType / ContentSubType 識別 MIME 類型、GetFirstChildEntity + GetNextSibling 走訪 MIME 樹、GetContentAsText 取出文字內文、GetNthHeader / GetSomeHeaders 讀取 header 值、CreateMIMEEntity 從頭建立 MIME 郵件、以及 body 跟 attachment 的實戰辨別方法。
2026.06.04 - NotesCalendar:LotusScript 讀寫 Domino 行事曆的三個 Class
Domino 行事曆資料不是放在一般文件裡、而是用結構化的 iCalendar 格式存在 mail.nsf。LotusScript 提供三個 class 處理這層結構:NotesCalendar(行事曆物件本身)、NotesCalendarEntry(單一行事曆項目)、NotesCalendarNotice(會議邀請通知)。本文拆解取得方式(session.GetCalendar 傳入 mail.nsf)、CreateEntry 寫入 iCalendar 格式的字串、ReadRange 批次讀取時間段內的項目、GetNewInvitations 取得未處理邀請、NoticeAction 接受/拒絕邀請、跟幾個一定會踩的坑(ConvertMIME 必須設 False、行事曆文件不能當一般 NotesDocument 操作)。
2026.06.03 - NotesDocumentCollection:LotusScript 文件集合的完整操作指南
幾乎每個 Domino agent 最後都會回傳一個 NotesDocumentCollection — 但多數程式碼只用到 GetFirstDocument / GetNextDocument 就停了。本文完整拆解這個 class:七種取得 collection 的方式、走訪四個方向(First / Next / Prev / Last / Nth)、集合運算三劍客(Intersect / Merge / Subtract 都是直接改原物件)、StampAll 批次寫值跟走訪中修改的陷阱、RemoveAll force 參數的並發語意、以及 FTSearch 縮減 + 集合運算的接力模式。
2026.06.02 - 實作筆記:DRAPI 透過 Keycloak OIDC 登入 — Domino 12.0.2 就能用、不必等 14
想把 DRAPI(Domino REST API)接到現代 IdP — 譬如 Keycloak、Azure AD、Okta — 通常以為要等 Domino 14 才有 OIDC、其實 12.0.2 用 DRAPI 的 oidc 模式就能跑通。本文是本機完整重現整套設定的實作筆記、聚焦 DRAPI 三個 OIDC 模式怎麼選、三層獨立認證架構(身份驗證 / 身份對應 / 授權)為什麼要分層除錯、跟 4 個會卡很久的踩雷 — 最大那個是 providerUrl 用 localhost 因為 Java IPv4 解析造成跨機器整個失敗。完整逐步流程在 GitHub repo + Pages 上、文章本身不重複設定步驟、聚焦關鍵判斷跟陷阱。
2026.06.01 - HCL Domino 14 跟前版的關鍵差異整理 — 管理員與開發者必看
從 V11 / V12 升級到 Domino 14.x、真正會讓既有部署失效的「結構性變動」其實有限、集中在幾個面向。本文用五個維度整理 14.0 / 14.5 / 14.5.1 跟之前版本的差異 — notes.ini 路徑、Java / jar 環境、XPages 編輯器(CKEditor → TinyMCE 6.7)、新模組(Domino IQ / DQL @FTSearch / AdminCentral / AutoUpdate)、跟一份完整的棄用 / 移除清單(iNotes UI、SNMP MIB、DCT、Server Load Utility 等)。每條都標版本起跑點跟官方來源、結尾附一份升級前的檢查清單。
2026.05.31 - NotesRegistration:用 LotusScript 自動化使用者註冊
Domino 管理員每天都會收到新人報到、離職、留停的通知 — 一筆一筆在 Admin Client 點滑鼠很快就成為時間殺手。NotesRegistration 是 LotusScript 內建解法、把使用者註冊 / 認證 / ID 檔管理整套搬進可程式化的世界。本文從人事系統觸發的實務場景切入、拆解 RegisterNewUser 的 14 個參數、必要的屬性 setup、跟伺服器權限的關係、跟批次處理的範例。
2026.05.30 - FTSearch / db.Search / DQL:Domino 三種搜尋機制怎麼選
Domino 14 之後、文件搜尋有三條技術路徑:FTSearch(文字索引)、db.Search(@Formula 全表掃描)、DQL(V12 引入、結構化 query、走 design catalog 跟 NIF 索引)。本文用一張多維對比表 + 一棵決策樹整理三者的差異 — index 需求、語法、效能、即時性、回傳順序、可組合性 — 並深入講 Domino 14 開始 DQL 支援 `@FTSearch()` term 把全文檢索整合進結構化 query 的意義。三個實戰場景(一次性查詢 / scheduled agent / 高頻 REST API)對應建議路徑、附 cross-link 整個搜尋系列跟 DQL 三部曲。
2026.05.29 - db.Search:用 @Formula 暴力搜尋 — 不需要 index 的那條路
NotesDatabase.Search 是 LotusScript 第二種搜尋機制 — 不靠 full-text index、靠 @Formula 在每一份文件上跑判斷式。本文拆解三個參數(formula / dateTime / maxDocs)跟 FTSearch 不一樣的語意、為什麼回傳 unsorted collection、dateTime 怎麼當作增量處理的 cursor、maxDocs=0 是真的「不限」(不像 FTSearch 預設 5000 上限)、formula 裡哪些 @function 不能用(UI 互動類 / lookup 類)、Stamp 改完 collection 不會 refresh 的陷阱、跟 production-ready 增量 agent 範例。三部曲第二篇、續篇會把這個跟 FTSearch / DQL 三選一比較。
2026.05.28 - FTSearch:Domino 全文檢索的三層 API(NotesDatabase / NotesView / NotesDocumentCollection)
FTSearch 是 Domino 三個 class 都有的方法 — 三個層級回傳不同型別、語意各異。本文拆解 NotesDatabase.FTSearch(回傳新的 collection)、NotesView.FTSearch(直接過濾 view 本身、回傳 Long 計數)、NotesDocumentCollection.FTSearch(直接縮減 collection 本身、無回傳)三者差異、sortopt 與 options 常數、query syntax operators 速查、CreateFTIndex 的 5 個 options bitmask、跟 `load updall -x` 的對應、沒建 index 時 method 還會跑(只是降速)、5000 doc 預設上限、wildcard `*` 只能放 term 結尾、operators 必須大寫等實戰陷阱。三部曲第一篇、後續會接 db.Search 跟三選一決策篇。
2026.05.27 - LotusScript 把 NotesView 匯出 Excel:四條路、CSV 預設、何時要升 POI
「把這個 view 匯出 Excel 給 user」是 Domino 圈最常被問的需求之一。四條路 — CSV via NotesStream(推薦預設)、HTML-as-xls(舊版格式技巧)、OLE Excel.Application(僅 client 端臨時用)、Apache POI via Java agent(正式環境級 .xlsx) — 各有適用場景。本文整理四條路的取捨表、CSV 完整實作(含 UTF-8 BOM、CSV escape、用 NotesViewNavigator 加速 5-10x)、HTML-as-xls / OLE / POI 的何時用何時不該用、Web download 模式、跟三個常見坑(BOM 漏寫、escape 不對、用 GetFirstDocument 而不是 ViewNavigator)。
2026.05.26 - NotesDateTime + NotesDateRange:LotusScript 日期時間處理的雙人組
Domino code 裡最常摸到的 utility class 之一 — NotesDateTime 代表單一時間點、NotesDateRange 代表一段時間區間。本文整理建立方式(New 跟 session.CreateDateTime 差別)、三組時區屬性(Local / GMT / Zone)的正確用法、6 個 Adjust 方法做日期算術、TimeDifference vs TimeDifferenceDouble 的精度差異、ConvertToZone 直接改物件本身、不是回傳新物件、NotesDateRange 的 4 個 property(沒有任何 method)、SetAnyDate / SetAnyTime 是搜尋 wildcard 用、跟 NotesItem.DateTimeValue 互動的 timezone 陷阱、跟兩個實戰範例(期限檢查 agent + 跨時區會議排程)。
2026.05.25 - NotesJSONArray / Element / Object:LotusScript parse + build JSON 的三個組成元件
之前發佈過的 lotusscript-http-json 介紹了 NotesHTTPRequest + NotesJSONNavigator 把『打 REST API 拿 JSON』完整收進 LS。本篇接續寫 navigator 下面的 3 個組成元件 — NotesJSONElement(name/value pair)、NotesJSONObject(物件節點)、NotesJSONArray(陣列節點)— 詳細 method、屬性、parse 時怎麼走整棵樹、反向 build JSON 怎麼用 Append* 系列 + Stringify、64K 限制版本敏感的三層解法(含 10.0.1 FP2 SPR# DCONB8VMAV / ASHEB95LFR 修補、跟 14.5 還活著的 element value > 64K 隱形地雷),跟一個完整 round-trip 範例(POST 出去 + parse 回應)。
2026.05.24 - NotesLLMRequest:4 行 LotusScript 把 LLM 接進 Domino app
Domino 14.5 引入 NotesLLMRequest / NotesLLMResponse 兩個 LotusScript class,把 LLM 推論能力以同步 API 形式給 app 開發者。本篇實戰:session.CreateLlmRequest() 工廠方法、Completion 三參數簽名、CompletionStream 串流模式、IsCommandAvailable / GetAvailableCommands 防禦性檢查、NotesLLMResponse 的 Content / FinishReason / Role 三個欄位。為什麼 API 設計用 commandName 而不是直接吃 prompt — Command document 抽離讓 admin 跟 dev 各自控制自己那層。附自動回信 + 摘要兩個實戰範例、跟 Java 對位 LLMReq / LLMRes。
2026.05.23 - 在 HCL 官方支援範圍外把 Domino 9.0.1 包進 Container — 社群可行性 PoC + 5 個一定會撞的坑
HCL 官方只發 Domino 10.0.1 FP3 起的 container image — 還在跑 9.0.x 想用容器做 dev/test、migration 預演、legacy server 保存的話官方沒路。本篇介紹一份社群可行性研究:RHEL UBI 7.9 base、兩階段 build、~1.48 GB image,跑得起 Domino 9.0.1 FP10、能加入既有 Domino domain、HTTP/NRPC/LDAP/IMAP/POP3/SMTP 全部正常。研究過程踩了 5 個 HCL docs 沒提的關鍵坑(Perl namespace bug / FP installer 不吃 -silent / J9 JVM heap 不夠 / setup 完成 marker 不對 / server.id 密碼 stdin block),每個都有實際 error message + workaround。完整 build script 跟 troubleshooting 在 bryanHsiao/build-hcl-domino9-container repo。
2026.05.22 - HCL Domino 容器化部署的兩條路 — 拉 pre-built image,或自己 build 客製版
把 Domino 包進 container 在 IBM 時代(V9)就有社群在做、HCL 從 V10 起正式提供官方 pre-built container image 下載。現在 HCL 雙管齊下:要快上線可以從 My HCLSoftware Portal 下載官方 pre-built image TAR 直接 docker load;要彈性可以用 HCL 在 GitHub 上開源的 domino-container 專案、跑互動式 build.sh menu 自己 build 客製 image,挑你要的模組(Domino / Traveler / Verse / Nomad / REST-API / Leap / Domino IQ / OnTime / C-API SDK / LP)+ add-on。這篇介紹兩條路怎麼選、build.sh 能客製到什麼程度、典型部署場景,跟想試試看的人怎麼起步。
2026.05.21 - NotesOutline / NotesOutlineEntry 全攻略 — Domino UI 導覽控件的程式化建構、4 種 entry type、24 個 property
NotesOutline 是 Domino 應用程式的左側 / 上方導覽控件,由 NotesOutlineEntry 條目以樹狀組成。透過 LotusScript 可以動態建立、修改、走訪 outline — 典型 use case 是多語切換(依 user locale 動態改 Label)、條件式 menu(依 role 顯示/隱藏)、動態使用者連結。本文整理 NotesOutline ↔ NotesOutlineEntry 關係、8 個 tree-walking 方法、6 個 manipulation 方法、24 個 entry property、4 個 Set* 方法、4 種 entry type 常數、9 個 EntryClass 常數、完整 CRUD 範例、五個踩雷點,跟 Java / SSJS 對照。
2026.05.20 - domino-container-lp-recipe — 為 HCL Domino Container 加上繁中 Language Pack 的社群工具(含他語言擴充範本)
HCL 官方 domino-container repo 內建支援 6 種 Language Pack(DE/ES/FR/IT/NL/JA)。Issue #55 討論過怎麼裝其他 LP,但官方基於「真要加就要承擔所有語言維護責任」的考量沒把更多 LP 收進 build.sh — 是合理的工程取捨。社群工具 domino-container-lp-recipe 補上這條擴充路線:用「動態修補」而不是「fork」的方式跑一個腳本就能加進繁中(end-to-end 已驗證),同時提供簡中 (SC) 跟韓文 (KO) 的擴充範本給社群當起點。結構小(~50 行 patch 跨 4 個檔)、跟著上游漂移成本低。本文介紹工具背景、三層整合、recipe-vs-fork 設計選擇、快速開始、加新語言流程、跟一個一定要先讀的 sync-trap 警告。
2026.05.19 - LotusScript 解析 XML 該選 DOM 還是 SAX — 五個問題決定走哪邊
LotusScript 處理 XML 有三條路:NotesDOMParser(整棵樹載入)、NotesSAXParser(事件驅動串流)、NotesXMLProcessor + NotesXSLTransformer(XSLT 規則式轉換)。本文整理三家本質差異對照、五個決策問題(檔案大小 / 是否修改 / 走訪方向 / 記憶體限制 / 轉換場景)、實務情境的選擇建議,附程式碼風格對照、效能比較跟踩雷集錦。讀完知道 LS 拿到一份 XML 該怎麼開動。
2026.05.18 - NotesDOMParser 全攻略 — XML 整棵樹載入記憶體、14 個 Node 類別、走訪/修改/序列化
NotesDOMParser 把 XML 整棵載入記憶體蓋成 DOM 樹、用 NotesDOMDocumentNode 當 root、配 14 個 Node 子類別代表不同 XML 元素(Element / Text / Attribute / Comment / CDATA 等)。可任意走訪、可修改、可 Serialize 回 XML。本文整理 DOM 樹結構概念、CreateDOMParser 初始化、14 個 Node class 關係表、NotesDOMNode 的 tree-walking API(FirstChild / NextSibling / NodeType)、完整 parse → walk → modify → serialize 範例、五個踩雷點,跟 Java/SSJS 對照。
2026.05.17 - NotesSAXParser 全攻略 — LotusScript 串流式 XML 解析、12 個 SAX 事件、On Event 綁定模式
NotesSAXParser 用 SAX(Simple API for XML)事件驅動模式處理 XML — 不把整份檔案載入記憶體、而是邊讀邊觸發 SAX_StartElement / SAX_Characters / SAX_EndElement 等 12 個事件。大檔案 / 只讀特定 element / 記憶體吃緊場景的首選。本文整理 SAX vs DOM 的本質差異、CreateSAXParser 初始化、On Event 綁定機制、12 個事件的觸發時機、NotesSAXAttributeList 怎麼拿 attribute、完整 LotusScript 範例、五個踩雷點,跟 Java / SSJS 對照。
2026.05.16 - NotesACLEntry 全攻略 — Domino 資料庫存取控制的程式化管理、7 個 access level、20 個 property、Roles 機制
NotesACLEntry 代表 Domino 資料庫 ACL 裡的單一條目(個人、群組或 server)。本文整理 NotesACL ↔ NotesACLEntry 容器關係、拿到 ACL 跟 entry 的三種途徑、7 個 access level 常數、UserType 跟 IsPerson/IsGroup/IsServer 三組旗標、20 個細粒度權限 property、Roles 自訂角色機制、acl.Save 的強制要求、五個踩雷點,跟完整 CRUD 範例。同時跟 14.5 NRPC encryption / trust store 系列文章連結,形成完整的 Domino security 圖譜。
2026.05.15 - NotesSession 全攻略 — LotusScript 的入口、單例規則、UserName 的三個變體、Evaluate 把 @Formula 拉進 LS
NotesSession 是每支 LotusScript 一定會碰到的入口 class — 它代表「當前 script 的執行環境」,提供 CurrentDatabase、UserName / EffectiveUserName / CommonUserName 三個 user 屬性、Evaluate 從 LS 跑 @Formula、CreateLog 寫 NotesLog、GetEnvironmentString 讀 notes.ini。本文整理 class 角色、一個 script 一個 session 的規則、核心 property / method、UserName 三變體在 On Behalf Of agent 的差異、server 端 vs client 端存取權限差異、五個踩雷點,跟完整範例。
2026.05.14 - NotesDocument 全攻略 — LotusScript 最核心類別的拿到、CRUD、五個踩雷點
NotesDocument 是 LotusScript 操作 Domino 文件最核心的類別 — 但它的細節很容易踩雷:GetItemValue 永遠回陣列、Save 的三個參數中 createResponse 常被誤解、Remove 的 force 不是軟刪除開關(軟刪除是 DB 層設定,要永久刪用 RemovePermanently)、direct property 跟 ReplaceItemValue 的微妙差別、漏 Save 是最常見的 silent bug。本文整理拿到 NotesDocument 的所有途徑、Item / Field 的觀念、CRUD 範例、五個必懂的坑、sibling methods 跟 Java/SSJS 對照。
2026.05.13 - Domino 14.5 Mandated Port Encryption 啟用實務 — CheckPortEncryption agent、portenc 指令、退路
續 5/11 概念篇,本文把 HCL 官方 10 步驟啟用流程拆開講:升級 server address book design、簽 CheckPortEncryption 排程 agent、Directory Profile 關鍵欄位、server ini(DEBUG_MANDATED_ENCRYPTION、MANDATEDENC_ACTIVE_REFRESH_TIME)、Desktop policy(DISABLE_MANDATED_ENCRYPTION)、portenc refresh / show 指令,以及啟用後出問題時的退路。Pre-14.5 server 的特殊行為也獨立講清楚。
2026.05.12 - Domino 14.5 那個 `?` icon 在說什麼 — Mandated NRPC Port Encryption 概念與啟用模式
升級到 Domino 14.5 後,Domino Directory 的 server view 最右欄會出現 `?` 圖示 — 不是 bug,是新功能 Mandated NRPC Port Encryption(強制端口加密)的合規狀態。本文整理:NRPC port encryption 的歷史、14.5 新增了什麼、`?` / 鎖頭等狀態 icon 怎麼解讀、預設行為跟三種啟用模式的差別。實務啟用步驟見隔日續篇。
2026.05.11 - Domino 14.5 NotesHTTPRequest 換了預設信任 CA 來源 — 升級前該知道的細節
Domino 14.5 起,server 端 LotusScript 跑 NotesHTTPRequest 時,預設從 Domino Directory 拿信任的 root CA,不再讀 data 目錄裡的 cacerts.pem。Notes client 不受影響、有 NotesHTTPRequest_Use_CACerts=1 這個 .ini 後門可以暫時退回舊行為,但長期該把自簽 CA 匯到 Domino Directory。本文整理這個改動的細節、影響範圍、過渡步驟,跟 5/7 那篇 NotesHTTPRequest 工具鏈深度文一起看。
2026.05.10 - NotesView.GetAllDocumentsByKey 全攻略:你以為簡單,但它有五個踩雷點
GetAllDocumentsByKey 是 LotusScript 開發中最常用的查詢方法 —— 給一個 key、拿回符合的所有 doc。但「key 對應 sorted column 不是 doc field」「exactMatch 預設 False 是前綴比對」「反斜線分類欄位讓查詢失效」這些細節,HCL 官方文件寫了但很多人沒讀完。本文整理 signature、整個 by-key 方法家族、五個常見踩雷點,附完整範例。
2026.05.09 - OpenNTF LotusScript Class Map:97 個類別一張圖,資料開源可拿
OpenNTF 在 2026 年釋出了基於 HCL Domino 14.5.1 的 LotusScript Class Map — 97 個 class、1001 個 property、997 個 method、72 個 event 全部攤在一張可互動的視覺地圖上,點任一節點就跳到 HCL 官方文件。本文介紹這個工具的功能、開源授權、底層 JSON 資料怎麼取,以及對開發者選題、學習、API 探索的價值。
2026.05.08 - LotusScript 的對外 HTTP / JSON 工具鏈:NotesHTTPRequest + NotesJSONNavigator
Domino V12 起 LotusScript 內建 NotesHTTPRequest 跟 NotesJSONNavigator 兩個 class,可以直接從 LS 打外部 REST API 拿 JSON 回來解析 — 不再需要 ActiveX 或 shell 出去呼叫 curl。本文整理兩個 class 的 method、屬性、PreferJSONNavigator 把兩者串起來的官方途徑、完整範例,跟 Java / SSJS 的對位差異。
2026.05.07 - NotesXMLProcessor 入門:LotusScript 處理 XML 的共同基底
NotesXMLProcessor 是 LotusScript 全部 XML 處理類別(DOMParser、SAXParser、DXLExporter、DXLImporter、XSLTransformer)共用的 abstract base class。本文整理它的角色、5 個衍生類別怎麼選、共通的屬性與 SetInput / SetOutput / Process 三個方法、以及 Release 6 起加入後的版本與 COM 限制。
2026.05.06 - Domino IQ RAG:把 NSF 直接掛上本地 LLM 的內建管線
Domino 14.5.1 在 Domino IQ 加入 RAG(Retrieval-Augmented Generation)支援,把 LLM 推論、Embedding 模型、向量資料庫全部跑在 Domino server 上,本地處理、原生繼承 ACL 與 Readers field 權限。本文整理啟用前提、dominoiq.nsf 兩階段設定、updall 向量化、LotusScript 怎麼呼叫 LLMReq,以及為什麼這跟「外接 OpenAI + Pinecone」是不同物種。
2026.05.05 - Domino IQ 入門:把 LLM 跑進 Domino server 是什麼概念
Domino 14.5 引入 Domino IQ — 把 AI 推論引擎內建到 Domino server 後台,從 LotusScript 用 NotesLLMRequest / NotesLLMResponse 直接送 prompt 給本地 LLM。本文整理架構、硬體需求、安裝流程、dominoiq.nsf 兩階段設定、Command 與 System Prompt 文件,並對比為什麼選這條路而非外接 OpenAI。
2026.05.05 - Domino REST API 目前最新版 v1.1.7:新端點與修正整理
HCL Domino REST API 目前最新版本是 v1.1.7(2026 年 4 月 7 日釋出),新增日曆設定、PIM 未讀狀態、Email 文件更新等端點,並修正附件下載、Microsoft Entra ID 認證、會議邀請等問題。
2026.05.04 - DQL Production-Ready:Catalog 維運、權限、與 sessionAsSigner
把 DQL 上 production 真正會撞牆的兩個問題:Design Catalog 怎麼自動維護(包含全新 NSF 的 bootstrap、設計變更後的 incremental refresh),以及為什麼一般使用者跑會噴「您沒有權限執行此作業」——以及對應的 sessionAsSigner / scheduled agent 解法。本文整理實測 Domino 12 驗證過的最終 pattern + Java production-ready 範例。
2026.05.03 - LotusScript NotesStream 實戰指南:把檔案讀寫做對
NotesStream 是 LotusScript 從 Notes/Domino 代理人讀寫檔案的標準抽象。本文整理 Open 真正的 signature、Truncate-before-write 的寫入慣例、文字與二進位 I/O 的差異,以及官方文件實際載明的陷阱。
2026.05.02 - DQL 踩雷集:寫 query 時 6 個官方文件不會明說的細節
Domino Query Language(DQL)的語法表面像 SQL,但實戰起來有一整套 Notes 特有的踩雷點 —— view selection 會默默限縮結果範圍、`'view'.column` 的 column 不是文件欄位名而是直欄程式名稱、比較運算子兩邊要空白、view 名稱含反斜線要 escape、`@formula` 內是獨立的 Formula Language parser、字串日期欄位要 `@TextToTime`。本篇用實測錯誤訊息對照逐個說明。
2026.05.01 - NotesRichTextItem 入門:用 LotusScript 操作富文本欄位
NotesRichTextItem(富文本項目)繼承自 NotesItem,所以 NotesItem 的全部屬性與方法都能用;但它另外有 22 個專屬方法處理段落、樣式、表格、嵌入物件、Navigator/Range 進階遍歷。本文整理建立方式、22 個方法分類、繼承關係,與寫程式時常踩的雷。
2026.04.30 - NotesNoteCollection 入門:操作 NSF 設計元素的瑞士刀
NotesNoteCollection(筆記集合)跟 NotesDocumentCollection 不同,它代表的是 NSF 裡所有「note」—— 包含資料文件、表單、視圖、ACL、代理程式、程式庫等設計元素。本文整理 32 個屬性、14 個方法、CreateNoteCollection 的 True/False 兩種起始模式,以及最常用的場景:DXL 匯出。
2026.04.29 - NotesViewNavigator 入門:用導航器走視圖,不要再 GetFirstDocument 硬撈
NotesViewNavigator(視圖導航器)是 LotusScript 走視圖的進階工具:能拿到 ViewEntry(視圖條目,含類別、總計、位置等視圖才有的中介資料)、能從子集合(單一類別、未讀、某層以下)建立、效能上比 GetFirstDocument 迴圈高,但使用之前要先把 AutoUpdate 關掉。本文整理 4 個屬性、約 36 個方法、7 個 CreateViewNav* 變體與重要注意事項。
2026.04.29 - Domino V12 起 notes.ini 支援多個 HTTPAdditionalRespHeader
舊版 Domino 的 notes.ini 只能塞一個 HTTPAdditionalRespHeader,第二行會把第一行蓋掉。HCL 在 V12.0.x 加了編號式的 HTTPAdditionalRespHeader01、02 寫法,讓你能用純 notes.ini 設好整套安全標頭——尤其是當網頁伺服器(HTTP task)起不來、Internet Site 文件也用不了的時候,這是唯一的後備路徑。
2026.04.28 - NotesQueryResultsProcessor 入門:DQL 之後的下一步
NQRP 是 Domino V12 引入的 LotusScript 類別,讓你把 DQL(或任何 NotesDocumentCollection)的結果重新排序、分類、加欄位、輸出成 JSON 或暫存 view。本文整理建立流程、所有方法簽名、官方範例與安全用法。
2026.04.28 - DQL 入門:用 SQL 風格的語法操作 Notes 文件
Domino Query Language(DQL)讓你用近 SQL 的語法直接查詢 Notes 文件,免再為每種查詢條件設計 view。本文是「DQL 三部曲」系列的 Part 1:介紹 DQL 的設計初衷、第一個 query 怎麼寫、從 LotusScript / Java / REST API 怎麼呼叫,以及常用語法速查。寫 query 結果不如預期的細節在 Part 2,上 production 的 catalog 維運與權限在 Part 3。
2026.04.28 - HCL Domino REST API 快速入門指南
本指南將引導您安裝、配置並開始使用 HCL Domino REST API,讓您能夠透過現代化的 RESTful 介面存取 Domino 資料庫。
2026.04.28 - HCL Domino 2026 發布亮點
HCL Domino 2026(版本 14.5.1)於 2026 年 3 月 19 日正式發布,帶來了多項新功能和改進,包括 Domino IQ、AutoUpdate、OIDC 支援等。
2026.04.27