2025/10/02

共通部品にチャレンジ:#10)LotusScript 実行ログ - ACL の取得

今回は LotusScript を実行しているユーザの ACL 情報を取得します。想定外のエラーの場合、権限に起因する場合もあります。この情報があればトラブル対応の時間短縮になるかもしれませんね。


フォームの修正

ログに ACL 情報を表示するためのフィールドを作成します。

新しいタブを追加(タブ表に 1 行追加)してタイトルに ”ACL” を指定します。そのタブ内にカスケード表を作成して、フィールドを配置します。

作成するフィールドは次の通りです。

項目 フィールド名 種類 補足
アクセスレベル AccessLevel ダイアログリスト 編集可能 キーワードは後述
ロール UserRole テキスト 複数値も可、改行区切り
オプション AccessOption チェックボックス キーワードは後

項目 種類 補足
アクセスレベル 選択肢を入力 なし|0
投稿者|1
読者|2
作成者|3
編集者|4
設計者|5
管理者|6
オプション 文書の作成|CreateDocuments
文書の削除|DeleteDocuments
個人エージェントの作成|CreatePersonalAgents
個人フォルダ/ビューの作成|CreatePersonalFoldersAndViews
共有フォルダ/ビューの作成|CreateSharedFoldersAndViews
LotusScript/Javaエージェントの作成|CreateLotusScriptJavaAgents
パブリック文書[読者]|ReadPublicDocuments
パブリック文書[作成者]|WritePublicDocuments
文書を複製またはコピー|ReplicateOrCopyDocuments

アクセスレベルとロールは重要な情報なので、基本情報のタブにも表示します。


項目 フィールド名 種類 式 / 補足
アクセスレベル AccessLevel_D ダイアログリスト 表示用の計算結果 AccessLevel
キーワードは 
AccessLevel と同じ
ロール UserRole_D テキスト UserRole
複数値も可、カンマ区切り


ライブラリの修正

続いて、追加したフィールドに値をセットするプログラムの作成です。ACL 情報は実行につき一度だけの取得でいいので、初期化処理に追加します。

Private Function xInitLog(ByVal vsLogTitle As String)
         ・・・
   'DB情報
   xndLog.DBTitle = xndbCur.Title
   xndLog.Server = xndbCur.Server
   xndLog.FilePath = xndbCur.FilePath

   'ACL 情報
   Dim lOpt As Long
   xndLog.AccessLevel = CStr(xndbCur.QueryAccess(sName))
   'アクセスレベル
   lOpt = xndbCur.QueryAccessPrivileges(sName)
   xndLog.AccessOption = xGetACLOptionName(lOpt)
                   'ACL オプション
   xndLog.UserRole = xndbCur.QueryAccessRoles(sName)
          'ロール

   'リッチテキスト準備
   Set xnrti = xndLog.CreateRichTextItem("Body")
         ・・・
End Function

QueryAccessPrivileges メソッドで取得した値は、フォームで利用するのは少し複雑です。そこで新しい関数 xGetACLOptionName で値を選択肢の文字列に変換しています。

End Function Private Function xGetACLOptionName(ByVal vlOpt As Long) As Variant
   Dim asOpt() As String
   Dim asReturn() As String
   Dim i As Integer
   Dim j As Integer

   '一度だけ実行なので定数化しない
   ReDim asOpt(8)
   asOpt(0) = |CreateDocuments|
   asOpt(1) = |DeleteDocuments|
   asOpt(2) = |CreatePersonalAgents|
   asOpt(3) = |CreatePersonalFoldersAndViews|
   asOpt(4) = |CreateSharedFoldersAndViews|
   asOpt(5) = |CreateLotusScriptJavaAgents|
   asOpt(6) = |ReadPublicDocuments|
   asOpt(7) = |WritePublicDocuments|
   asOpt(8) = |ReplicateOrCopyDocuments|

   'ビットごとに確認
   j = 0
   ReDim asReturn(j)
   For i = 0 To UBound(asOpt)
      If vlOpt And (2 ^ i) Then
         'ビットが立っているので戻り値の配列に追加
         ReDim Preserve asReturn(j)
         asReturn(j) = asOpt(i)
         j = j + 1
      End If
   Next

   xGetACLOptionName = asReturn
End Function

なお、ACL 情報の取得については、『アクセス権限とロールの取得 - LotusScript』と『QueryAccessPrivileges の判定と演算子の活用』で紹介しているので参照ください。


前回 共通部品にチャレンジ


2025/10/01

共通部品にチャレンジ:#9)LotusScript 実行ログ - 経過時間の測定と出力

作成中のLotusScript 実行ログ出力ライブラリに処理時間を測定する機能を追加します。

まず、ログ出力の開始から終了までの経過時間を測定して記録します。

ついでに、ログ出力間の経過時間も測定し、閾値を越えるとログの先頭に表示する機能も作ります。この機能があれば簡易的にボトルネックを探すことができますね。


経過時間の測定方法

Now で取得できる時間の最小単位は秒のため経過時間測定には少々おおざっぱです。そこで、今回は Timer を使ってミリ秒単位で測定することとします。


◇ フォームの修正

まず、経過時間を表示するフィールドを実行時間欄に追加します。


項目 フィールド名 種類 補足
経過時間 LogElapsedTime 数値 編集可能 少数 2 桁


◇ スクリプトライブラリの修正

まず、(Declarations) に開始時点の Timer 値を記録する変数宣言を追加します。

         ・・・
'カウンタ
Private xlMessage As Long      '通常ログ出力件数
Private xlError As Long             'エラーログ出力件数

'経過時間管理
Private xsgST As Single            '実行開始時の Timer 値

初期化関数である LogOpen で Timer 値を代入します。

Public Function LogOpen(ByVal vsLogTitle As String) As Boolean
         ・・・
   If xbIsOpen = True Then Exit Function


   '時間管理
   xsgST = Timer()

   'ログ文書の作成
         ・・・

最後に終了処理で経過時間を記録します。

Private Function xLogClose() As Boolean
         ・・・
      xndLog.LogEndTime = Now

      '経過時間
      xndLog.LogElapsedTime = Timer() - xsgST


      xndLog.LogMessageCount = xlMessage
         ・・・

これで、実行時間欄に経過時間が表示されます。


ログ間の経過時間の記録

続いては、ログの出力間隔の経過時間を記録する機能を作ります。この作業はスクリプトライブラリの修正だけで対応します。


◇ 初期設定

この処理で使用する変数を(Declarations) に追加します。経過時間は紫色で表示するのでそのフォント変数と経過時間等の変数を 2 つ追加します。

         ・・・
'フォント定義
Private xnrtsDT As NotesRichTextStyle        'ログ時刻
Private xnrtsMsg As NotesRichTextStyle     '通常のメッセージ
Private xnrtsErr As NotesRichTextStyle       'エラーメッセージ
Private xnrtsET As NotesRichTextStyle        '経過時間
         ・・・
'経過時間管理
Private xsgST As Single             '実行開始時の Timer 値
Private xsgPrev As Single         'ひとつ前のログ出力時の Timer 値
Private xsgET_TH As Single    '経過時間の閾値(秒)

         ・・・

経過時間用のフォント設定を初期化に追加します。

Private Function xInitFont(vnrti As NotesRichTextItem)
         ・・・
   '経過時間
   Set xnrtsET = xns.CreateRichTextStyle()
   xnrtsET.NotesColor = 11     '濃い紫
   xnrtsET.FontSize = 10
   xnrtsET.NotesFont = vnrti.GetNotesFont(sFont, True)
   xnrtsET.Bold = False

End Function

経過時間は一番左に小数点揃え表示するため、段落の設定を調整します。

Private Function xInitParagraphStyle()
   '通常のメッセージ
   Set xnrtpsMsg = xns.CreateRichTextParagraphStyle()
   xnrtpsMsg.FirstLineLeftMargin = 1 * RULER_ONE_INCH
   xnrtpsMsg.LeftMargin =
8.5 * RULER_ONE_CENTIMETER
   Call xnrtpsMsg.SetTab(3.5 * RULER_ONE_CENTIMETER, TAB_DECIMAL)
   Call xnrtpsMsg.SetTab(8.0 * RULER_ONE_CENTIMETER, TAB_RIGHT)

End Function

この設定を行うことにより段落は次のように設定されます。

初期化処理である LogOpen で経過時間に関連する変数を初期化します。次のログ出力までの経過時間を知るために、開始時間を xsgPrev に保管しておきます。

Public Function LogOpen(ByVal vsLogTitle As String) As Boolean
         ・・・
   If xbIsOpen = True Then Exit Function


   '時間管理
   xsgST = Timer()
   xsgPrev = xsgST
   xsgET_TH = 0.5     ' 処理時間出力閾値

         ・・・

なお、処理時間を出力する閾値は、とりあえず 0.5 秒としておきます。


◇ 経過時間の算出と出力

ログ間の経過時間の計算は単純です。現在の Timer 値と前回の Timer 値 xsgPrev の差をで算出します。算出後は次のログに備えて xsgPrev に現在の値をセットします。

Private Function xPrintLog(ByVal vbIsError As Boolean, ByVal vsMessage As String) As Boolean
   Dim sgET As Single
   Dim sgNow As Single

   '経過時間
   sgNow = Timer()
   sgET = sgNow - xsgPrev
   xsgPrev = sgNow


   '通常ログのスタイル適用
   Call xnrti.AppendParagraphStyle(xnrtpsMsg)

   '経過時間を次を右寄せにするためのダミータブ
   Call xnrti.AddTab(1)


   '経過時間
   If sgET >= xsgET_TH Then
      '閾値を越えているので出力
      Call xnrti.AppendStyle(xnrtsET)
      Call xnrti.AppendText(Format(sgET, "#.00"))
   End If
   Call xnrti.AddTab(1)

         ・・・

経過時間は、閾値を超えた場合に出力します。出力項目である経過時間、時刻、メッセージの間にはタブをセットします。段落設定と合わせると、次のように体裁よく表示されます。

なお、経過時間の検証を行うにはスクリプトを一時停止する必要があります。デバッガでステップ実行するか Sleep 関数を使うと確認できます。

      If i = 5 Then Sleep 5     ' 5 秒停止


まとめ

今回は経過時間の測定と出力に対応しました。

ミリ秒単位の測定に使用した Timer 関数については過去の記事『実行時間の計測(Timer 関数)』を参照ください。また、ログの出力では少々細かいタブの設定を利用しました。タブの設定と動作については『リッチテキスト:#9)タブの設定』を参考にしてください。


前回 共通部品にチャレンジ


2025/09/27

共通部品にチャレンジ:#8)LotusScript 実行ログ - 日付順ビューの作成

ログ出力ができるようになったので、ログを見やすく表示するビューが必要ですね。


使用するフィールド

ビューの作成で利用できるフィールドをまとめます。

項目 フィールド名 種類 補足 / 式
開始時刻 LogStartTime 日付/時刻  
DB 名 DBTitle テキスト  
タイトル Title テキスト 処理の名前、または、エージェント名
エラーフラグ IsError テキスト 1 = エラーあり
エラー LogError テキスト  最後のエラーメッセージ
実行サマリー LogSummary テキスト  最後のサマリーメッセージ
実行ユーザ名 UserName  名前  

エラーと実行サマリは出力関数をコールするたびに上書きしますので ”最後” に出力されたメッセージとなります。


ビューの作成

サンプルとして最初に掲載した画像のビューを作成します。年/月/日でカテゴライズして、日付順に表示します。

ビューの各列と設定をまとめました。列名に ( ) が付いているのは非表示列です。また、設定の ↓ は降順、▼ はカテゴリ列を表します。

列名 設定 補足 / 式
1 (背景色)   @If(
   IsError = "";
      (-1):(-1):(-1):(-1):(-1):(-1);
      255:255:240:(-1):(-1):(-1)
)
2 (年) @Year(LogStartTime)
3   ↓▼ @Text(@Year(LogStartTime)) + " 年"
4 (月) @Month(LogStartTime)
5   ↓▼ @Month(LogStartTime)
6 (日) @Day(LogStartTime)
7   ↓▼ @Text(@Day(LogStartTime)) + " 日"
8 開始 LogStartTime
9 DB名 DBTitle
10 タイトル Title
11 (背景色&文字色) @If(
   IsError = "";
      (-1):(-1):(-1):(-1):(-1):(-1);
      255:255:240:255:0:0
)
12 エラー / サマリ @If(
   IsError = "";
      LogSummary;
      LogError
)

エラーのログは目立つように背景を黄色、エラーメッセージを赤で表示します。列番号 1 と 11 でコントロールしています。この設定方法については『ビューで条件に応じて色を設定する方法』を参照してください。

今回はサンプルとして、ログを日付順に表示するビューを作成しました。実際に利用する際には、DB 別、ユーザ別、エラーのみのビューなどがあると便利です。必要に応じて作成しましょう。


次回予告

基本的な機能が完成したので、今後はログ出力であったらいいな的な機能を順に追加していきます。次回は、処理時間を測定する機能を追加します。スクリプト全体の処理時間だけでなく、ログ出力間の処理時間が閾値を越えると表示機能も作ります。


前回 共通部品にチャレンジ


2025/09/26

共通部品にチャレンジ:#7)LotusScript 実行ログ - 基本機能のテスト

前回までに作成したスクリプトライブラリの動作確認をします。簡単なサンプルプログラムを作成して、ライブラリの使い方と実行結果を確認しましょう。


エージェントの作成とテスト

新規でエージェントを作成します。名前には別名を付けた方がテストになりますね。トリガーはアクションメニューから実行として、対象は ”なし” とします。

サンプルで作成するプログラムは、1 ~ n までの総和を求めるプログラムです。計算の経過をログに出力します。

Option Declare
Use "StdLog"    '実行ログ の組み込み

Sub Initialize
   Dim i As Integer
   Dim iMax As Integer
   Dim iSum As Integer
   Dim s As String

   On Error GoTo ErrProc

   '初期化
   iMax = 10

   'ログの開始
   Call LogOpen("StdLog のテスト")
   Call PrintLog("1 ~ " & CStr(iMax) & " までの総和を求めます...")

   '1 ~ iMax までの総和を計算
   For i = 1 To iMax
      s = CStr(i) & ") " & CStr(iSum) & " + " & CStr(i) & " = "
      iSum = iSum + i
      '計算経過の出力
      Call PrintLog(s & CStr(iSum))
   Next

   Call PrintSummary("1 ~ " & CStr(iMax) & " までの総和は " & CStr(iSum) & " です。")

   'ログの終了
   Call LogClose()

   Exit Sub

ErrProc:
   Call PrintError(Error$ & " (Err = " & CStr(Err) & ", Erl = " & CStr(Erl) & ")")
   End
End Sub

ライブラリの使い方は、

  1. ライブラリ StdLog を Use で呼び出す
  2. LogOpen 関数でログ出力を開始
  3. PrintLog など Print* 関数でログを出力
  4. 最後に LogClose をコールしてログ出力を終了
となります。

実際に実行すると次のような文書が作成されます。


エラーログの出力のテスト

サンプルプログラムでは、不測の事態に備え On Error でエラー処理を記述しており、エラー発生時には PrintError 関数でそのエラー情報を出力しています。

その動作確認のため、For ループ内の最後の行にエラーを強制的に発生させます。

      Error 1000, "検証のために発生させたエラー"

実行結果を確認するとログ内では赤字でラーメッセージが表示され、エラーの箇所が一目瞭然ですね。

なお、エラーが発生した場合、End 命令でスクリプトを終了しています。LogClose をコールせずに終了しているのですが、『StdLog: LogClose() が実行されずに終了しました...』と出力されています。Terminate の設定が正しく動いていることが確認できます。


次回の予定

テスト実行できるようになり、ログがたまってくるとビューが欲しくなります。そこで、次回はログを見やすく表示するビューを作成します。


前回 共通部品にチャレンジ 次回


2025/09/25

共通部品にチャレンジ:#6)LotusScript 実行ログ - ログの終了(LogClose 関数)

#3 から開始したライブラリ作成作業の続きです。今回はログの終了処理について紹介します。これで基本機能が完成です。


◇ ログの終了(LogClose 関数)

ライブラリ利用者とのインターフェースとなる関数はシンプルです。終了処理を行うサブ関数 xLogClose をコールするだけです。

Public Function LogClose() As Boolean
   Call xLogClose()
End Function


◇ ログ終了の本体

ログが初期化され出力中であるかをはじめに確認します。その後、ログの終了メッセージを記録し、終了時間、通常ログとエラーの件数を記録して文書を保存します。

Function xLogClose() As Boolean
   If xbIsInit = False Then Exit Function

   '終了処理
   If xbIsOpen Then
      '処理終了メッセージの出力
      Call PrintLog(|ログ出力の終了|)
      xndLog.LogEndTime = Now      '処理時刻
      xndLog.LogMessageCount = xlMessage      '通常ログの件数
      xndLog.LogErrorCount = xlError      'エラーログの件数
      Call xndLog.Save(True, True)

      'フラグリセット
      xbIsOpen = False
      Set xndLog = Nothing

      xLogClose = True
   End If
End Function

ログ文書の保存後は、xbIsOpen を False に設定、文書を開放して Private 変数を整えます。これでログの終了は完了です。


◇ Terminate の定義

不測の事態に備えて、スクリプトライブラリの Terminate を記述します。ライブラリが閉じるときログが記録中だった場合、ログを強制的に終了させます。

Sub Terminate
   If xbIsOpen Then
      'Close できていない
      Call xPrintLog(True, xcsLibName & ": LogClose() が実行されずに終了しました...")
      Call xLogClose()
   End If
End Sub

これで LogClose() をコールし忘れた場合でも、ログが保存されます。また、Ctrl + Break で強制終了した場合にも対応できます。『LogClose() が実行されずに終了しました...』メッセージはエラーのフォントで表示させているので気づきやすくしています(エラー扱いではない)。


まとめ

このような共通部品では、安定性が重要となります。内部でエラーが起きないことはもちろんですが、想定外の使用に備えて、インターフェースとなる関数の最初でステータスのチェックを行っています。また、Terminate を活用して異常終了時でも、できる限りリカバリする点がポイントとなります。

これで、LotusScript 実行ログ出力の基本機能は完成です。次回は、このライブラリを利用して動作確認をします。


前回 共通部品にチャレンジ 次回


2025/09/24

共通部品にチャレンジ:#5)LotusScript 実行ログ - ログの出力(Print* 関数)

#3 から開始したライブラリ作成作業の続きです。今回はログを出力する関数 3 つを紹介します。


◇ 通常ログの出力(PrintLog 関数)

最初は通常のログを出力する PrintLog 関数です。xPrintLog 関数でログの出力を行っているのですが、この関数の役割は、エラーチェックと出力した通常ログのカウンタのインクリメントとなっています。

Public Function PrintLog(ByVal vsLogText As String) As Boolean
   If xbIsInit = False Then Exit Function
   If xbIsOpen = False Then Exit Function

   '通常ログとして、引数の文字列を出力
   If xPrintLog(False, vsLogText) Then
      PrintLog = True

      'カウンタインクリメント
      xlMessage = xlMessage + 1
    End If
End Function


◇ エラーログの出力(PrintError 関数)

通常ログと違い、エラーログの出力は、エラーメッセージを記録するフィールド LogError にエラーメッセージを記録して、エラーフラグ IsError に "1" をセットしています。

Public Function PrintError(ByVal vsErrorMessage As String) As Boolean
   If xbIsInit = False Then Exit Function
   If xbIsOpen = False Then Exit Function

   'エラーログとして、引数の文字列を出力
   If xPrintLog(True, vsErrorMessage) Then
      'エラーメッセージを記録
      xndLog.LogError = vsErrorMessage
      'エラーフラグを記録
      xndLog.IsError = "1"

      PrintError = True

      'カウンタインクリメント
      xlError = xlError + 1
   End If
End Function


◇ サマリーの出力(PrintSummary)

「8 件の文書を処理しました。」というような処理結果を出力する機能がサマリーです。エラーと同様に専用のフィールド LogSummary にメッセージを記録します。それ以外の処理は通常ログと同じです。

Public Function PrintSummary(ByVal vsLogSummary As String) As Boolean
   If xbIsInit = False Then Exit Function
   If xbIsOpen = False Then Exit Function

   '通常ログとして、引数の文字列を出力
   If xPrintLog(False, vsLogSummary) Then
      'サマリを記録
      xndLog.LogSummary = vsLogSummary

      vsLogSummary = True

      'カウンタインクリメント
      xlMessage = xlMessage + 1
   End If
End Function


◇ ログ出力の本体

この関数がログメッセージを出力する本体で、上記 3 つの関数からコールされています。引数 vbIsError が True の場合はエラー、False の場合は通常ログを表します。

Private Function xPrintLog(ByVal vbIsError As Boolean, ByVal vsMessage As String) As Boolean
   '通常ログのスタイル適用
   Call xnrti.AppendParagraphStyle(xnrtpsMsg)

   '日時
   Call xnrti.AppendStyle(xnrtsDT)
   Call xnrti.AppendText(Format(Now, "yyyy/mm/dd hh:nn:ss"))

   'ログ(メッセージ)
   If vbIsError Then
      '通常ログ
      Call xnrti.AppendStyle(xnrtsErr)
   Else
      'エラーログ
      Call xnrti.AppendStyle(xnrtsMsg)
   End If
   Call xnrti.AddTab(1)    '日付とログの間
   Call xnrti.AppendText(vsMessage)

   xPrintLog = True
End Function

処理の流れは、段落スタイルをセットして、日付とログメッセージを出力しています。文字色を変えるため出力前に AppendStyle であらかじめ定義したフォントを指定しています。メッセージの出力ではエラーかどうかに応じてフォントを切り替えています。


前回 共通部品にチャレンジ 次回


2025/09/23

共通部品にチャレンジ:#4)LotusScript 実行ログ - ログの開始(LogOpen 関数)

前回から開始したスクリプトライブラリ作成作業の続きです。今回はログ出力を開始する処理に関して記載します。


◇ ログの開始(LogOpen 関数)

まず、ライブラリ利用者とのインターフェースとなる LogOpen 関数です。初期化できていない場合とすでに Open 済みの場合はキャンセルするエラーチェックをしてから、処理を行います。

ログ DB に新規文書を作成し、ログ文書の初期化(後述)を行い、フラグや戻り値を整えています。

Public Function LogOpen(ByVal vsLogTitle As String) As Boolean
   Dim s As String

   On Error GoTo Err_General

   If xbIsInit = False Then Exit Function
   If xbIsOpen = True Then Exit Function

   'ログ文書の作成
   Set xndLog = xndbLog.CreateDocument()
   xndLog.Form = "fStdLog"

   'ログ文書の初期化
   Call xInitLog(vsLogTitle)

   '終了処理
   xbIsOpen = True
   LogOpen = True

   '処理開始メッセージの出力
   Call PrintLog(xcsLibName & |: ログ出力の開始 (| & xcsLibName & | | & xcsLibVersion & |)|)

   Exit Function

Err_General:
   s = "LogOpen でエラーが発生しました。" & Chr(10)
   s = "問題を解決するまでログ出力はできません。" & Chr(10)
   s = s & Error$ & " (Err = " & CStr(Err) & ", Erl = " & CStr(Erl) & ")"
   MsgBox s, 16, xcsLibName
   Exit Function
End Function

最後に PrintLog をコールして、ログの開始とライブラリのバージョンを記録します。この関数はログを出力する関数なのですが、これについては次回紹介します。


◇ ログ文書の初期化

xInitLog はログの基本情報を文書にセットする関数です。ログの開始時刻、エージェントの情報、ユーザ名や DB の情報を記録しています。

Function xInitLog(ByVal vsLogTitle As String)
   Dim na As NotesAgent
   Dim sTitle As String
   Dim v As Variant
   Dim sName As String

   '初期化
   sTitle = vsLogTitle
   sName = xns.UserName

   '開始日時
   xndLog.LogStartTime = Now

   'エージェント情報
   Set na = xns.CurrentAgent
   If Not(na Is Nothing) Then
      'エージェントと別名を分離
      v = Split(na.Name, "|")
      xndLog.AgentName = xRemoveFirst(v)    'エージェント名
      xndLog.AgentAlias = v                                     'エイリアス名

      'タイトルの指定がない場合、エージェント名をセット
      If sTitle = "" Then
         sTitle = xndLog.AgentName(0)
      End If
   End If

   'ログタイトル
   xndLog.Title = sTitle

   'ユーザ名
   xndLog.UserName = sName

   'サーバエージェント
   If xns.IsOnServer Then
      xndLog.IsOnServer = "1"
   End If

   'DB情報
   xndLog.DBTitle = xndbCur.Title
   xndLog.Server = xndbCur.Server
   xndLog.FilePath = xndbCur.FilePath

   'リッチテキスト準備
   Set xnrti = xndLog.CreateRichTextItem("Body")

   'フォントの準備
   Call xInitFont(xnrti)
End Function

また、リッチテキストフィールドを作成して、ライブラリ内の Private 変数に格納しています。このフィールドは、さまざまなシーンで利用するのでライブラリ全体からアクセスできるようにしています。


◇ エージェント名と別名を分離

NotesAgent クラスの Name プロパティは別名を含めて "|" 区切りで返します。そこで Split 関数で配列化した後、xRemoveFirst 関数でエージェント名と別名を分離しています(前述の xInitLog  関数の下記部分)。

Private Function xInitLog(ByVal vsLogTitle As String)
   Dim na As NotesAgent
         ・・・
   'エージェント情報
   Set na = xns.CurrentAgent
   If Not(na Is Nothing) Then
      'エージェントと別名を分離
      v = Split(na.Name, "|")
      xndLog.AgentName = xRemoveFirst(v)    'エージェント名
      xndLog.AgentAlias = v                                     'エイリアス名
         ・・・
 End Function

xRemoveFirst 関数は、引数の配列から最初の要素を削除(引数の配列を更新)し、削除した要素を戻り値として返します。

Private Function xRemoveFirst(rvArray As Variant) As Variant
   Dim i As Integer

   '最初の要素を戻り値にセット
   i = LBound(rvArray)
   xRemoveFirst = rvArray(i)

   '各要素を1つ前に詰める
   For i = LBound(rvArray)+1 To UBound(rvArray)
      rvArray(i-1) = rvArray(i)
   Next

   '最大要素番号を1つ減らす
   If LBound(rvArray) = UBound(rvArray) Then
      '要素が一つなので初期化
      ReDim rvArray(UBound(rvArray))
   Else
      ReDim Preserve rvArray(UBound(rvArray)-1)
   End If
End Function


◇ フォントの準備

ログ文書の初期化の最後でコールしている xInitFont 関数はログ出力で利用するフォント情報を初期化する関数です。今回のログ出力では、項目ごとにフォントを切り替える仕様としています。頻繁にアクセスするので、フォント情報もライブラリ内の Private 変数に格納します。

Private Function xInitFont(vnrti As NotesRichTextItem)
   Dim sFont As String

   sFont = "メイリオ"

   '通常のメッセージ
   Set xnrtsMsg = xns.CreateRichTextStyle()
   xnrtsMsg.NotesColor = 0     '黒
   xnrtsMsg.FontSize = 10
   xnrtsMsg.NotesFont = vnrti.GetNotesFont(sFont, True)
   xnrtsMsg.Bold = False

   'ログ時刻
   Set xnrtsDT = xns.CreateRichTextStyle()
   xnrtsDT.NotesColor = 15    '薄いグレー
   xnrtsDT.FontSize = 10
   xnrtsDT.NotesFont = vnrti.GetNotesFont(sFont, True)
   xnrtsDT.Bold = False

   'エラーメッセージ
   Set xnrtsErr = xns.CreateRichTextStyle()
   xnrtsErr.NotesColor = 2     '赤
   xnrtsErr.FontSize = 10
   xnrtsErr.NotesFont = vnrti.GetNotesFont(sFont, True)
   xnrtsErr.Bold = True    ’太字
End Function

通常のメッセージは黒、エラーは太字の赤字として目立たせています。また、ログの出力時刻はさほど重要ではないのでグレーとしています。

なお、フォントをセットする(NotesFont プロパティ)ためにリッチテキストフィールド(NotesRichTextItem オブジェクト)が必要です。文書を作成してからでないと利用できないため LogOpen 関数コール時に初期化しています。


前回 共通部品にチャレンジ 次回


2025/09/22

共通部品にチャレンジ:#3)LotusScript 実行ログ - ライブラリの使い方と作成

LotusScript 実行ログ出力機能作成の 3 回目です。いよいよスクリプトライブラリの作成を始めます。ライブラリの使い方を整理してから、ライブラリのコーディングを始めます。


ライブラリの使い方

LotusScript 実行ログを出力する機能は、スクリプトライブラリにまとめます。アプリの開発者は、自身が作成するエージェントやフォームのボタンなど、アプリケーション内でこのライブラリを利用して、処理状況や実行結果をログ DB に残します。開発者は、ログ管理に関しては部品を利用するだけとなるため開発効率が上がるというのが狙いです。

ライブラリのインターフェースとなる関数と機能は以下の通りとなります。

LogOpen ログの記録を開始
PrintLog ログ(通常のメッセージ)を記録
PrintError エラーログを記録(赤字で目立つように記録)
PrintSummary 処理結果のサマリを記録
LogClose ログの記録を終了し、ログ文書を保存

LogOpen でログの記録を開始、Print* でログの中身を出力、LogClose でログ DB に文書として保存して終了します。NotesLog クラスとメソッド名は違いますが、使い方の流れは同じですね。


ライブラリの作成と初期化

新規で LotusScript のライブラリを作成します。

名称 StdLog

まずは、ライブラリの初期化に関連する部分を紹介します。


◇ ライブラリの定義

ライブラリの定義にあたる (Options)、(Declarations) は次の通り記述します。

Option Declare

Private xns As NotesSession
Private xndbCur As NotesDatabase
Private xndbLog As NotesDatabase
Private xndLog As NotesDocument
Private xnrti As NotesRichTextItem

'ライブラリ情報
Private Const xcsLibName = "StdLog"
Private Const xcsLibVersion = "1.0.0"
Private Const xcsFilePath = "LS_Log.nsf"    'ログDBのパス

'段落スタイル
Private xnrtpsMsg As NotesRichTextParagraphStyle     '通常ログ

'フォント定義
Private xnrtsDT As NotesRichTextStyle        'ログ時刻
Private xnrtsMsg As NotesRichTextStyle     '通常のメッセージ
Private xnrtsErr As NotesRichTextStyle       'エラーメッセージ

'ステータス管理
Private xbIsInit As Boolean         '初期化したか?
Private xbIsOpen As Boolean     'ログDBが取得済みか?

'カウンタ
Private xlMessage As Long    '通常ログ出力件数
Private xlError As Long           'エラーログ出力件数


◇ ライブラリの初期化

続いては、ライブラリの初期化です。ログ DB の取得を行い、取得できたら初期化できたことを xbIsInit に設定します。

Sub Initialize
   'ログDB取得
   Set xns = New NotesSession
   Set xndbCur = xns.CurrentDatabase
   Set xndbLog = xns.GetDatabase(xndbCur.Server, xcsFilePath, False)

   '取得成功なら初期化は OK
   If Not (xndbLog Is Nothing) Then
      xbIsInit = True
   End If

   '段落スタイル
   Call xInitParagraphStyle()
End Sub


◇ 段落スタイルの準備

初期化関数からコールしている xInitParagraphStyle は段落スタイルを設定準備する関数です。ログを出力する際に都度利用するので、あらかじめ準備しておき、いつでも利用できるようにします。

Private Function xInitParagraphStyle()
   '通常のメッセージ
   Set xnrtpsMsg = xns.CreateRichTextParagraphStyle()
   xnrtpsMsg.FirstLineLeftMargin = 1 * RULER_ONE_INCH
   xnrtpsMsg.LeftMargin = 6.5 * RULER_ONE_CENTIMETER
End Function

この設定を利用した段落は、1 行目の左マージンが 1 インチ(2.54cm)、2 行目以降が 6.5cm となります。これで、ログメッセージが長く右端で折り返しても日時の下には表示されません。


次回の予定

今回はライブラリの作成と初期化について紹介しました。次回以降はインターフェースとなる関数を順に紹介します。


前回 共通部品にチャレンジ 次回


2025/09/21

共通部品にチャレンジ:#2)LotusScript 実行ログ - フォームの作成

まずはログを表示するフォームを作成します。フォームのイメージは次の通りです。

現時点ではログ出力機能として最低限必要な項目のみ配置しています。その他項目は、関連機能追加のタイミングで追加することとします。なお、フォーム上の の部分は非表示の項目です。

作成に必要な情報を順に記載します。


フォーム情報

新規 DB を作成して、次の新規フォームを作成します。

フォーム名 1.LotusScript実行ログ
別名 fStdLog
ウィンドウタイトル @Text(LogStartTime; "D1T1S3") + " - " + Title

作成するフィールドは下記の通りです。このフォームは開発者やアプリの運用担当だけが見る前提にしていますので、理由がない限り ”編集可能” としています。


◇ 管理者([Admin] ロール)セクション

フォームにセクションを作成して、その中に管理用のフィールドを作成します。

項目 フィールド名 種類 補足
エラーフラグ IsError テキスト 編集可能 1 = エラーあり
通常ログ件数 LogMessageCount 数値 編集可能
エラー件数 LogErrorCount 数値 編集可能

セクションは [Admin] ロールを持っている人のみ表示させるよう非表示式を指定します。

!(
   @IsMember("[Admin]"; @UserRoles)
)

なお、セクションは初期状態を閉じておきましょう。これだけでロールを持たないユーザには、セクション丸ごと非表示にできます。


◇ ヘッダ情報

ログのタイトルや実行時間などの基本的な情報を表示するエリアです。次のフィールドを配置します。

項目 フィールド名 種類 補足 / 式
  Title テキスト 編集可能  
実行時間 LogStartTime 日付/時刻 編集可能  
LogEndTime 日付/時刻 編集可能  
エージェント AgentName テキスト 編集可能
AgentAlias テキスト 編集可能  複数値も可
IsOnServer チェックボックス 編集可能  
エラー LogError テキスト 編集可能  
LogErrorCount_D 数値 表示用の計算結果  LogErrorCount - 1
実行サマリー LogSummary テキスト 編集可能  

なお、エージェントの項目は、LotusScript がエージェントから実行された場合のみ出力されるように作成していきます。よって、AgentName に値があるときだけ表示させます。

!(AgentName != "")

エラーについては、エラーがあった場合だけの表示とします。

!(IsError != "")

ただし、エラー件数は、2 件以上の場合のみ表示とします。

!(LogErrorCount >= 2)


◇ 実行環境の情報

スクリプトを実行する DB とユーザの情報、ACL、実行環境を表示するエリアです。ACL と実行環境については、追って作成します。それに備えて、[基本情報]タブだけが存在するタブ形式の表にフィールドを配置します。

項目 フィールド名 種類 補足
DB 情報 DBTitle テキスト 編集可能  
Server テキスト 編集可能  
FilePath テキスト 編集可能  
 実行ユーザ名 UserName テキスト 編集可能  


◇ 実行ログ

フォームの下部には LotusScript 実行ログを記録するリッチテキストフィールドを配置します。

項目 フィールド名 種類 補足
 実行ログ Body リッチテキスト 編集可能  


前回 共通部品にチャレンジ 次回