出直し!! ヘルプ

連載中

連載 終了

2023/03/31

Notes - Excel 連携:#5)列とフォーマット設定

前回、ノーツ文書の値を Excel のワークシートに出力するサンプルをご紹介しました(#4)。

ただ、出力された Excel シートは、小数点の位置がバラバラになったり、いまひとつ美しくないですよね。これは、出力したワークシートの各セルの書式設定が、”標準”となっているからです。

今回は出力される Excel シートの体裁を改善することを目的に、列ごとにフォーマットを指定する方法を整理します。


フォーマットの設定

セルのフォーマット(書式設定)を指定するには、Range オブジェクトのプロパティである NumberFormat プロパティか NumberFormatLocal プロパティを使用します。

指定できる同じ書式はどちらのプロパティもほぼ同じです。書式を表す文字列は、Excel のセルの書式画面で、ユーザー定義を選択し、『種類(I):』に指定できる文字列となります。

ただし、"G/標準" や "[赤]"、 "\" 記号など日本語(ローカル)環境に依存する指定には、NumberFormatLocal プロパティを使用します。


列のアクセス

今回の要件では、列全体に対して同じ書式を設定することになります。そのためには、列全体を表す Range オブジェクトの取得が必要です。

以前紹介した Worksheet オブジェクトの Range プロパティを使用して、以下のように記述できます。

oSheet.Range("A:A")

また、列にアクセスするための専用のプロパティである Columns を使用して、記述することも可能です。Columns プロパティの場合、列番号(数値)で指定できます。

oSheet.Columns(1)

どちらの記述でも、ワークシート上の1列目(A列)を表す Range オブジェクトが取得できます。


サンプルプログラム

前回のコードにフォーマット設定を追加しました(赤字部分)。

1列目の日付時刻データは 年月日と時分、2列目の数値データは3桁ごとのカンマ区切りと小数点以下を1桁で固定、3列目は文字列としています。

Sub Initialize
   Dim ns As New NotesSession
   Dim ndb As NotesDatabase
   Dim ndc As NotesDocumentCollection
   Dim nd As NotesDocument
  
   Dim oXls As Variant
   Dim oSheet As Variant
  
   Dim i as Integer
  
   '選択文書取得
   Set ndb = ns.CurrentDatabase
   Set ndc = ndb.UnprocessedDocuments
  
   'Excel の準備
   Set oXls = CreateObject("Excel.Application")
   Call oXls.Workbooks.Add
   Set oSheet = oXls.Workbooks(1).WorkSheets(1)
  
   '列フォーマットを設定
   oSheet.Columns(1).NumberFormatLocal = "yyyy/m/d hh:mm"
   oSheet.Columns(2).NumberFormatLocal = "#,##0.0_ "
   oSheet.Columns(3).NumberFormatLocal = "@"

  
   '文書を Excel に出力
   For i = 1 to ndc.Count
      Set nd = ndc.GetNthDocument(i)
      oSheet.Cells(i, 1).Value = nd.Fld_DT(0)
      oSheet.Cells(i, 2).Value = nd.Fld_Num(0)
      oSheet.Cells(i, 3).Value = nd.Fld_Text(0)
   Next
  
   oXls.Visible = True
End Sub


まとめ

今回は、セルのフォーマット(書式設定)を指定するプロパティと列全体のアクセス方法について記載しました。

オブジェクトの関連図に追加すると以下のようになります。

前回 Notes - Excel 連携 次回

2023/03/30

ドメイン検索 と 運用上の注意点

Notes/Domino には、ドメイン検索のという機能があります。”ドメイン”というだけあって、複数の Domino サーバにまたがり、複数のノーツデータベースをまとめて検索できます。

もちろん、Notes/Domino の機能として構築されていますので、検索したユーザが参照できる文書のみを返してくれます。ACL や 作成者/読者フィールドを考慮して、結果を返してくれる優れものです。

このように素晴らしい機能なのですが、利用にはいくつか注意点があります。私が過去に担当した環境で、懸案事項となった点を列挙します。


検索対象は管理者が指定

検索対象となるデータベースはDBのプロパティで指定が必要です。機能的に、カタログDBを使用することもあり『[アプリケーションを開く]ダイアログに表示』と『サイト検索に含む』のチェックが必要です。

横断検索する必要のないログやマスタDBなどを対象から外すことができます。半面、どれを対象とするのか判断が必要となります。


インデックスサーバを設定

検索対象のDBはドメインカタログに記録され、サーバが順にクロールして索引を作成します。インデックスサーバでは、domidx というタスクが実行されインデックス作成を担当します。

インデクスサーバはすべての文書が参照できる必要があります。ACL や読者フィールドの扱いが雑であったり、単一サーバで運用されている場合は気が付きにくいので要注意です。


索引作成は時間がかかる

アクセス権を配慮した検索ができるせいか、インデクスの作成には時間がかかります。

ただし、一度インデックスができると、以降は差分更新となります。更新頻度の低いDBの場合は特に短くなります。


メールは対象にできない

設定できないわけではありませんが、仕様上メールは対象外となっています。また、メールは、全文索引を利用して、そのメールだけを検索する前提となっています。

メールは個人的なものですから、他人が検索する必要はないので当たり前かもしれません。

ただ、ユーザの立場ではメールとアプリ両方を一度に検索したいときもあるとは思うのですが...


削除文書が反映されない

インデックスの更新は、新規と変更が対象で削除は対象ではありません。インデックスを再作成しないと削除文書が検索にヒットすることになります。

回避策としては、定期的にインデックスを削除して、リセットすることとなります。先に記載した通り、初回のインデックスの作成は時間を要します。再作成の所要時間、検索対象のDBで発生する削除の量などを勘案し、運用計画を立てる必要があります。


索引が作れない添付ファイルがある

当たり前なのですが、対応していないファイル形式の索引は作成されません。また、パスワード付きのファイルも対象外となります。

また、社内で利用しているファイル形式が対応しているかの確認も重要です。

2023/03/29

Notes - Excel 連携:#4)ノーツ文書をワークシートに出力

前回は、ワークシートのセルに対してアクセスする方法を記述しました。今回は、実際の利用例として、ノーツ文書の値をExcelシートに出力する方法を記載します。


サンプルコード

サンプルアプリには、以下のフィールが配置されたフォームがある前提としています。

フィールド名
Fld_DT 日付/時刻
Fld_Num 数値
Fld_Text テキスト

また、このフォームを使って作成した文書が複数存在し、それを表示するビューが作成済みとします。

最後に、『すべての選択文書』に対して実行するエージェントを作成し、ビューから実行できる状態にします。

エージェントのプログラムは下記の通りです。

Sub Initialize
   Dim ns As New NotesSession
   Dim ndb As NotesDatabase
   Dim ndc As NotesDocumentCollection
   Dim nd As NotesDocument
  
   Dim oXls As Variant
   Dim oSheet As Variant
  
   Dim i as Integer
  
   '選択文書取得
   Set ndb = ns.CurrentDatabase
   Set ndc = ndb.UnprocessedDocuments
  
   'Excel の準備
   Set oXls = CreateObject("Excel.Application")
   Call oXls.Workbooks.Add
   Set oSheet = oXls.Workbooks(1).WorkSheets(1)
  
   '文書を Excel に出力
   For i = 1 to ndc.Count
      Set nd = ndc.GetNthDocument(i)
      oSheet.Cells(i, 1).Value = nd.Fld_DT(0)
      oSheet.Cells(i, 2).Value = nd.Fld_Num(0)
      oSheet.Cells(i, 3).Value = nd.Fld_Text(0)
   Next
  
   oXls.Visible = True
End Sub


サンプルの実行

実行すると、ビューで選択した文書の中身がワークシート内に1行1文書で出力されます。これでノーツ文書を Excel に書き出しできるようになりましたね。

前回 Notes - Excel 連携 次回

2023/03/28

Notes - Excel 連携:#3)セルのアクセス

前回は、ワークシートオブジェクトを取得する方法をまとめました。今回のテーマは、ワークシートのセルにアクセスして、値を操作する方法です。

セルにアクセスする方法は複数あります。例えば、

oSheet.Cells(2, 3).Value = "出直し!! ドミノ塾"
 
oSheet.Range("C2").Value = "出直し!! ドミノ塾"

という感じです(oSheet は、前回からの流れで、Worksheet オブジェクトが入っている前提です)。実行すると、どちらも以下のような結果になります。


Cells プロパティ

このプロパティはワークシート内のセルを表すオブジェクトです。Cells 単独で使用するとワークシート内のすべてのセルの集合を表します。特定のセルを指定するのが、上記サンプルです。セルの位置(行, 列)を数値で指定でき、単独のセルを表します。

Worksheet.Cells プロパティ (Excel)

このプロパティの戻り値は、Range オブジェクトで、1つ以上のセルのブロックを表します。上記サンプルでは、1つのセルをだけを表すオブジェクトとなります。


Range プロパティ

プロパティ名称の通り、Range オブジェクトにアクセスします。上記サンプルの通り、Range プロパティではセルの位置の指定は A1 スタイルとなります。

Worksheet.Range プロパティ (Excel)

また、Range プロパティでは、"C2:C5" のように記述すると2つのセルの範囲を指定をすることができます。例えば、

oSheet.Range("C2:C5").Value = "出直し!! ドミノ塾"

を実行すると、

のように複数のセルにまとめて値をセットできます。


Range オブジェクト

Cells プロパティ、Range プロパティとも、Range オブジェクトを返します。この Range オブジェクトがセルに対してアクセスするインターフェースとなります。

Range オブジェクト (Excel)

このオブジェクトに上記サンプルで使用した Value プロパティがあり、値をセットできます。また、セルに対するプロパティなので、Font や数式を表す Fomula などがあります。メソッドとしては、値をクリア(Clear)したり、クリップボード経由でコピー(Copy)などが存在します。

Range オブジェクトは、Notes - Excel 連係において頻繁に登場するので、中心的なオブジェクトといえます。プロパティやメソッドを一通り確認しておくと良いかと思います。

前回に倣って、オブジェクトを関連図で表すと、以下のようになります。


前回 Notes - Excel 連携 次回

2023/03/27

ノーツ名変換 早見表

ノーツ名はメッセージやメールに表示する場合は、省略形で表示しないとすっきりせず、美しくないですよね。

ですが、文字列の比較などプログラム処理する場合では、階層付き(CN= や O= の識別子)が付いた状態で処理するべきと考えています。これは、名前(作成者 / 読者を含む)フィールドが自動で付加することもあり、階層付きで処理するほうがノーツ的にお作法が良いと感じるからです。

ということで、名前の形式変換は、@関数、LotusScript を問わず頻繁に行うことになるのですが、微妙にキーワードが異なります。ややこしいですね。

しかも、なぜか私は "ABBREVIATE" のスペルが覚えられないんです... その対策として、私は以下の表をディスプレイのそばに貼っています。

名前の形式 @関数 LotusScript
省略形 ABBREVIATE Abbreviated
階層付き CANONICALIZE Canonical
共通名 CN Common

統一してほしいと思うのは私だけでしょうか??

2023/03/26

REST API とおまじない

Notes/Domino V10 以降、REST API が利用できるようになりました。

HCLSoftware の以下のページに詳しくわかりやすい解説があります。しかも、サンプルコード付きです。

技術資料: 連載 Domino V10 アプリ開発 #鬼わか 解説 第 6 回「NotesからREST APIを呼んで郵便番号検索をしてみよう #鬼わか 解説」

私も実際に試し、成功して理解を深めました。ただ一点、以下のコードの存在価値がわからなかったのです。

' 返ってきたJSONに改行コードが入っていれば消去する
json = Replace(Replace(returnValue, Chr(13), ""),Chr(10),"")

私がチャレンジした環境ではこのコードを省略して、

json = returnValue

としても、正常に動作したんです。

何のおまじないだろうと思い、技術者仲間に質問したところ、返答がありました。

SPR # ASHEB95LFR

私がテストした、12.0.2 では修正されているこの問題に配慮したコードだったのです。
これですっきりしました!!

ちなみに、このノーツDB、ノーツ担当者なら頻繁に出くわす、FixList というデータベースです。これまでの問題の修正履歴が確認できます。


コミュニティって素晴らしい

ちょっとだけ蛇足です。

私はノーツコンソーシアムに参加して、地域ごとの研究会のうち、大阪研究会に所属して、日々活動しております。

今回の情報はこのコミュニティのメンバーから情報提供を受けました。たまたまかもしれませんが、今回は一瞬で答えが出てきました。コミュニティには、有人なりの良いところがありますね。ネット検索とは違い、あーだこーだと説明できるので、意図が明確に伝わりますし...

それに、質問に絡めての楽しい会話、おいしい食べ物やお酒は、Google 先生や AI Chat では味わえないですからね。今のところ...

よろしければ、大阪研究会 ご参加ください。いろんな情報交換をやっていますよ!

ノーツコンソーシアム

あ、ノーツコンソーシアムに関してですが、私はいろいろとお世話になっており、大変感謝しております。大阪で研究会が始まった1997年(?)ぐらいからの長いお付き合いです。ですが、回し者ではありません... 仲間が増えたらいいなと思ってご紹介したまでです。

2023/03/25

Notes - Excel 連携:#2)ブックとシート

前回は、ノーツから Excel に接続する方法についてまとめました。

実際に Excel とデータ連携するとなると、Excel のワークシートに対して入出力することになります。そこで、連携したデータを記録する基本となるオブジェクトであるワークシートの取り扱いについてまとめます。


まずはサンプル

以下のコードをエージェントに記述して実行すると、Excel のオブジェクトを新規作成した後、新しいワークブックを開き、最初のワークシートの名前をメッセージボックスで表示します。

Sub Initialize
   Dim oXls As Variant
   Dim oSheet As Variant
  
   Set oXls = CreateObject("Excel.Application")
   Call oXls.Workbooks.Add
   Set oSheet = oXls.Workbooks(1).WorkSheets(1)
   
   oXls.Visible = True
   MsgBox oSheet.Name, 64
End Sub

これを題材に、Excel のワークシートにアクセスするまでの方法を確認しましょう。


Workbooks オブジェクトのふるまい

LotusScript に慣れ親しんだ方からすると、Workbooks オブジェクトのふるまいに違和感を感じませんか?

オブジェクトとして、Add メソッドをコールした後、配列のように添え字をつけてアクセスもしています。

前回紹介した Microsoft Learn で、Application オブジェクトの Workbooks プロパティを調べてみました。

Application.Workbooks プロパティ (Excel)

どうやら、このオブジェクトはコレクションのようです。続いて、このプロパティで取得できる Workbooks オブジェクトです。

Workbooks オブジェクト (Excel)

メソッドを確認すると、使用した Add メソッドが存在します。また、コレクションぽく Count プロパティの存在が確認できます。

ただ、配列のようにアクセスし、コレクションの1要素である Workbook オブジェクトが取得できるとは、どこにも記載されていません。唯一、近しいプロパティとして、Item というのがありました。引数にインデックス番号を指定すると単一のオブジェクトが取得できるようです。

Workbooks.Item プロパティ (Excel)

LotusScript の NotesDocument クラスの拡張構文で、フィールドにプロパティとしてアクセスできるような特殊な機能で実現されていると、勝手に解釈しました。

GetNthWorkbook のようなメソッドがあると、LotusScript 屋にはわかりやすいのですが...


ワークシートにアクセスする経路

一部勝手な解釈は含みつつ、Application オブジェクトからシートオブジェクトを取得するまでで使用するオブジェクトを整理してみました。反転部分がクラス名で、太枠の上段がプロパティ、下段がメソッドです。


Application クラスでは、Workbooks プロパティでコレクションにアクセス、Workbooks(n) で配列のようにアクセスし、Workbook オブジェクトが取得できることを表してみました。

Workbooks オブジェクトの Add メソッドは新規のワークブックを作成、Open が既存のワークブック(Excel ファイル)を開くメソッドです。Close はヘルプによると、すべてのワークブックを閉じるようです。

Workbook オブジェクトは、1つのワークブックを表すオブジェクトなので、保存(Save)や名前を付けて保存(SaveAs)メソッドが存在し、このブックだけを閉じることができます(Close メソッド)。

そして、Workbook オブジェクトにワークシートにアクセスするためのプロパティが存在します。ワークシートもワークブックと同様の構成で、コレクションである Worksheets オブジェクトが存在し、配列的なアクセスで単一のシートを表す Worksheet オブジェクトを取得できます。

Worksheet オブジェクトでは、シート名を表す Name プロパティや シートを表示/非表示するための Visible プロパティが存在します。

最初に記述したサンプルでは、

   Set oSheet = oXls.Workbooks(1).WorkSheets(1)

となっており、一気にワークシートオブジェクトを取得し、oSheet 変数に代入していました。

ここに記載した範囲のプロパティやメソッドで、複数のワークシートがあっても、構造の理解に困ることはないかと思います。

前回 Notes - Excel 連携 次回

2023/03/23

ロールを持っているユーザだけに表示

フォームやビューのアクションボタンで、ロールを持っている場合に表示したいって要望はよくありますよね。

接続したユーザのロールを取得するには、@UserRoles を使用します。この関数は、保持しているロールをリスト値で返します。

ボタンの表示/非表示ををコントロールするには、このリストに含まれるか判定する必要があります。

例えば、[Admin] というロールを持っている場合、ボタンを表示する、非表示式は以下の通りとなります(表示する条件を記述して、全体を否定して”非表示式”を表しています)。

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

@IsMember は、1つ目の値が2つ目のリストに含まれていた場合、True を返します。

また類似の関数である、@Contains を使用すると以下のようになります。

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

ポイントは、@IsMember と @Contains では引数の並びが逆になることです。この点がいつも混乱して、ついついヘルプを見てしまいます...

また、@IsMember は完全に一致する要素がリスト値内にある場合に限られ、@Contains は要素ごとに部分一致となる点も注意が必要です。

2023/03/22

Notes - Excel 連携:#1)Excel オブジェクトの作成

ノーツは1つの製品で非常に幅広いエリアをカバーする素晴らしい製品ですが、苦手とする部分も存在します。

例えば、帳票の出力やグラフ表示です。ノーツの機能拡張を期待するところですが、現時点では他のアプリケーションの力を借りる必要があります。今の時代、1製品に頼るのではなく、組み合わせて課題解決する方が一般的かもしれません。情シス部門の腕の見せどころといえますね。

今回のシリーズでは、ノーツから Excel の機能を利用して、ノーツの機能を補いより活用する方法を検討していきます。

初回は、ノーツから Excel を操作する方法について整理します。

実現には、LotusScript の CreateObject 関数を使用します。

例えば、エージェントで以下のように作成し、実行すると新しい Excel のワークブックがデスクトップに表示されます。

Sub Initialize
   Dim oXls As Variant

   Set oXls = CreateObject("Excel.Application")
   Call oXls.Workbooks.Add
   oXls.Visible = True
End Sub

CreateObject 関数は、指定されたクラスの OLE Automation オブジェクトを作成します。引数の"Excel.Application"が、Excel を表すクラス名で、生成するオブジェクト毎にあらかじめ定義されています。Windows では、ProgID と呼び、レジストリ内に登録されているらしいです。

オブジェクトが生成されると、oXls 変数に代入されます。オブジェクトなので、Set が必要となります。


コーディング時の注意

オブジェクト生成以降は、そのオブジェクトが持つプロパティやメソッドをコールして、プログラムを完成させます。Domino Designer にしてみると、そのオブジェクトは海のものとも山のものともわかりませんので、プロパティやメソッド、引数のチェックはできません。タイプミスしても Notes Class のようにコンパイルエラーはでません。実行して初めてエラーとなるので、記述には十分注意してください。

同じ理由で、デバッグ時もオブジェクト内のプロパティは参照できません。


オブジェクトの管理

続いて、CreateObject 関数利用時の挙動の確認と注意です。

先のサンプルを実行すると、デスクトップに Excel が起動しました。エージェントの実行が終了しても、Excel は起動したままとなっていました。これは、Excel がノーツのエージェントとは別プロセスで実行していることになります。

試しに、「oXls.Visible = True」をコメントアウトして実行してみてください。Windows のタスクマネージャを開くと Excel のタスクが残ったままとなります。そして、UI に表示できないので、タスクマネージャから強制終了するしかありません。

これを回避するためには、以下のように、コードでオブジェクトを終了します。ここでは、Excel をクローズして、オブジェクト変数に Nothing を代入しています。

Sub Initialize
   Dim oXls As Variant

   Set oXls = CreateObject("Excel.Application")
   Call oXls.Workbooks.Add
   'oXls.Visible = True

   Call oXls.Workbooks(1).Close(True)
   Set oXls = Nothing

End Sub

このように終了処理を確実に行うと、実行後 OS にゴミが残りません。また、うまくコントロールできるようになると、UI に一切表示することなく Excel の操作ができるようになります。


Excel オブジェクト構造の調べ方

先述した通り、CreateObject した Excel では、Domino Designer からプロパティやメソッドは参照できません。それらを調べるためには、Microsoft Learn の力を借りることになります。

https://learn.microsoft.com/ja-jp/office/vba/api/overview/excel

CreateObject("Excel.Application") で作成されるオブジェクトは、引数の通り Excel の Application オブジェクトとなります。Microsoft Learn の『オブジェクト モデル』より、Application オブジェクトを探してみてください。ありましたか?

この記事を書いている時点では、”Application オブジェクト” ではなく ”アプリケーション オブジェクト”と表示されていました。

このサイトは機械翻訳されているようで、不必要に日本語化されていることがありますので、注意して参照ください。


UI表示は遅い?

今回のサンプルで、Application クラスの Visible プロパティを True に設定することにより、Excel を UI に表示できることを紹介しました。

オブジェクト生成時に、UI に表示すると、プログラムの実行状況が目に見えるので、挙動が確認できて面白いです。

ただ、UI に表示する分、処理速度は下がります。こんな時は、UI の表示を処理の最後に変更すれば、少しは改善できます。

Notes - Excel 連携 次回

2023/03/21

よく使う MessageBox

LotusScript でコーディングしていると、処理の確認や情報の表示するために MessageBox 関数を頻繁に使用します。

この関数は、2つ目の引数でボタンの配置やアイコンなどを柔軟に設定できるようになっています。ただ、柔軟に設定できる分、いざ使うとなるとうろ覚えで、ヘルプを確認しがちです。

そこで今回は、通常の開発で必要な3パターンだけを抽出してみました。これだけは覚えておくと、素早く開発できるかと思います。

これ以外のパターンが必要なときは、ヘルプを確認しましょう。パラメータの設定値ぐらいであれば、英語のポップアップヘルプでも、読み取れますね。

なお、アプリの統一感を出すため、アイコンは必ず表示する前提としております。


ただの情報は 64

情報を表示するだけのメッセージボックス。インフォメーションアイコン+[OK]ボタンを表示。

Call MessageBox(message, 64, title)


確認は 366

処理の実行確認するメッセージボックス。疑問符アイコン+[はい][いいえ]ボタンを表示。

iReturn = MessageBox(message, 36, title)

戻り値の iReturn は、[はい]のクリックで 6 を返します。

また、[いいえ]ボタンをデフォルトボタンにする場合、+ 256 とします。これもたまに使うので覚えておきましょう。


エラーは 16

エラーを表示するメッセージボックス。ストップアイコン+[OK]ボタンを表示。

Call MessageBox(message, 16, title)

2023/03/20

日本語のグループ名はサポート外と再認識した話

ノーツサーバに日本語のグループを作成し、メールを送信した場合の挙動に関して、過去の経験の記録も兼ねて整理します。

はじめに言っておきたいことは、ドミノディレクトリでは、全角文字のグループはそもそもサポート外です。以下はその前提でご参照ください。

この記事を読んで、日本語グループは動くんだ!と判断しないでくださいね。

事の発端

ある時、クライアントとサーバを 9 に上げた時でした。全ノーツユーザ(約1500名)にアナウンスするため全ユーザが所属するグループを宛先に選択しメール送信すると、『フィールドが大きすぎる(32K)、またはビューの列と選択式が大きすぎます。』とエラーが発生し送信できない現象が発生しました。

現在は、クライアントとサーバとも 11 なのですが、送信できない症状は継続しています。発生するエラーは、『エントリを追加するとテキストリストが 64K を超えてしまいます。エントリを追加できません。』と少し変化はしましたが、相変わらずです。

この日本語のグループは、ノーツ全社導入時点から存在し、ノーツではない人事システムから全従業員の所属をもとに自動生成していました。

現象発生以前のサーバはR4.5、R4.6、R5、6.0、8.5、クライアントは、R4.5、R4.6、6.0と推移していました。

このような環境において一度も今回のような現象は発生しませんでした。

そんな事情もあり、途中からこの環境を担当した私は、日本語グループ名は、問題なく動くと思い込んでおりました...

症状と挙動の確認

さて、今回の現象と Notes/Domino の挙動を整理しましょう。

まず、正常な動作です。メールを送信すると、メールがサーバの mail.box に転送されます。このタイミングで、グループが展開されるようです。

同様のグループを半角英数だけで作成した環境で、Router タスクを止め送信したところ、あて先が展開された10通強のメールが mail.box に作成されました。この処理が、32K や 64K の制限を回避しているのだと思われます。

続いて、日本語グループの場合です。

メール送信ボタンを押すとクライアント上にエラーメッセージが表示され、サーバの mail.box には1通もメールが届きません。

この症状からクライアント上でグループが展開され、送信前にエラーが発生したと判断できます。

勝手な想像ですが、グループがドミノディレクトリに存在するかのチェックでは”ない”と判定され、個人アドレス帳を含めたクライアントでのグループ展開のタイミングで、サーバ上のグループを展開しちゃったと考えています。

同じ”グループを展開する”という処理でも、機能により少し挙動が違うようです。ちなみに、ACL設定でも日本語グループを使用していますが、こちらは Domino 9 でも Domino 11 でも正常に動作しています。

Notes/Domino では、内部的な文字の管理は、LMBCS(Lotus Multi Byte Character Set)というもので管理されています。日本語の全角文字列は、日本語を示す 0x10 + Shift-JIS の 3 バイトで構成されます。(私にはできませんが)Notes API を使ったアプリを開発する場合、この LMBCS の変換が甘いと、正常に動かないんだそうです。

身近に確認できるのは、@SetEnvironment で日本語を出力したときですね。notes.iniをメモ帳で開くと、各文字の前に”・”のごみがつきます。これが 0x10 で、残りの 2 バイトが Shift-JIS なので読める文字で表示されることになります。

今回の現象は、Notes クライアントのアップデートの過程で、グループ展開のコードの更新があり、LMBCS の処理が一部省略されたのではないかと想定します。

もちろん、そもそもサポート外なので、”バグ”ではないのですが...

蛇足の思い出話

ということで、今回は日本語グループの話でした。

繰り返しますが、”日本語グループはサポート外”なので、ご使用は避けてください。たとえ、今は大丈夫でも、将来何が起こるかわかりません。

そういえば、R4.6 ぐらいまでの Notes 黎明期のころいろんな環境がありました。

DJXはなかったので公開アドレス帳に姓名に漢字を入力してユーザ名を発行したり、DBファイル名を”サンプル.nsf”としたり、フィールド名を全角文字で書いたり...

知ってか知らずかは別にして、それでもそれなりに動いていました。サポートしていないと言いながら動くのが、ノーツのすごいところといえますね。

はるか昔、五反田のロータス社で DJX に関する説明会?ベンダーの意見集約?の機会がありました。この時に、日本語グループの要望を出しておけばよかったと悔やまれます。

2023/03/19

コード → 名称変換 を汎用的に!

Notes では、ダイアログリストフィールドなどのキーワードフィールドを中心に別名を使用します。 

フォームの場合、フィールドの設定で別名を名称に変換してくれて便利なのですが、ビューの場合はそうはいきません。ビューの列式で変換するか、文書内に別名のほかに表示用の名称を持たせる必要があります。 

こんな時によく使い方法を紹介します。

区分(Type)という名称で『ダイアログ』形式の選択のフィールドを作成するとします。

まず、準備作業として、選択肢と別名を保持するフィールド、Type_Lst を作成し、フィールドの値としてセットします。

"質問|1":
"要望|2":
"障害|3"

続いて、Type フィールドの選択肢の設定を『式で選択肢を設定』にし、以下の式を設定します。

@GetField(@ThisName + "_Lst")

最後に、選択した区分の名称を保存する、Type_Name フィールドを『計算結果』として作成、以下の式をセットします。

REM {ベースフィールド名取得};
xFld := @LeftBack(@ThisName; "_");

REM {変換したいコードをセット};
xCD := @GetField(xFld);

REM {変換する値を別名形式のリスト値で指定};
xLst := @GetField(xFld + "_Lst");

REM {--------------------------------};
REM { ※ 以下は変更しないこと!};

REM {CDと名称を準備};
xFm := @Trim(@Right(xLst; "|"));
xTo := @Trim(@Left(xLst; "|"));

REM {CDを名称に変換};
@Replace(xCD; xFm; xTo)

例によって、内部のコードは可能な限り改変無用のにしています。フィールド名のコントロールと選択肢フィールドの式の調整だけで、応用が可能です。

選択肢フィールドについて将来選択肢の変更を考えた場合、作成当時の選択肢を保持ておきたいなら『作成時の計算結果』、変更を反映し新しい選択肢を有効にしたければ『計算結果』にすればよいかと思います。

2023/03/18

表示用の計算結果フィールドの式を統一しよう

ノーツの日付フィールドで『日付/時刻制御』を指定するとカレンダから選択して入力することができますよね。

ただ、このフィールドの形式、読み込みモードの場合、背景がグレーで表示されます。ある時、少しだけ目が不自由な方から、これが見づらいとご意見をいただきました。

それ以降、日付フィールドは、読み込み時は『Notes スタイル』の『表示用の計算結果』フィールドで入力した日付を表示するようにしています。

この表示用の計算結果フィールドの式には、入力用のフィールド名を設定することとなります。フィールドの数が多数あると、フィールドをコピペを多用しますが、更新し忘れ別のフィールドの値が表示されていたなんてことがたまにあります。
(そもそもコピペして更新し忘れることが問題なのですが...)

こんな時に私が使用している方法を紹介します。

まず、表示用のフィールド名をもとの名前+"_D"としています。その上で、フィールド式を次のようにし設定します。

xFldName := @ThisName;
xFldName := @LeftBack(xFldName; "_");

@GetField(xFldName)

このようにすれば、式はどの表示用フィールドでも同じとなります。フォームをチェックする際もフィールド名を確認するだけになりますので、少し楽になります。

ちなみにリスト値を使って記述することもできます。

xFldName := @ThisName;
xFldName := @Explode(xFldName; "_");
xFldName := @Subset(xFldName; @Elements(xFldName)-1);
xFldName := @Implode(xFldName; "_");

@GetField(xFldName)

余計めんどくさい、レスポンスに影響ないの?などご意見はありそうですが、大目に見てくださいませ...


2023/03/16

Join と Split に相当する@関数

LotusScript では、配列を区切り文字で連結した文字列を返す関数を Join、その逆の機能を実現する関数として Split があります。

これに相当する@関数は、@Implode と @Explode となります。

似た名前なので、どっちがどっちかすぐに忘れます。私はいつまでたっても覚えられず、毎回ヘルプを見ています。

整理すると、

  • @Implode → Join
  • @Explode → Split

となります。辞書で単語を調べると、

  • Implode → 内側に破裂する、崩壊する 
  • Explode → 爆発する、破裂する、急上昇する

だそうです。

  • @Implodeは、内側に崩れてつながり、ひとつの文字列になる
  • @Explodeは、爆発してバラバラになるから、配列になる

って感じでしょうか?

@Join や @Split を作ってくれたら、絶対使うんですけどねぇ...

2023/03/15

非表示にする条件って考えにくくない?

非表示設定。

アクションボタンやアウトラインなど、ユーザやステータスなどの状況に応じて表示/非表示を切り替える場合に頻繁に使用します。

読み込みモードでは非表示、編集時には非表示など、表示したくない場合にチェックするだけなので非常に便利です。

ちょっと気になるのが、一番下の非表示式。

複雑な条件を設定することができるのですが、非表示にする条件ってわかりにくいと感じたことはありませんか?

これが一般的なのかはわかりませんが、私はつい表示する条件を考えてしまいます。

例えばあるボタンを”ステータスが1で、かつ、タイプがA以外の時、表示したい”などです。

これを式で表現すると、

Status = "1" & Type != "A"

となるのですが、非表示式で表すと

Status != "1" | Type = "A"

となります。

肯定と否定が入れ替わり、”かつ”という条件が ”or” で表現されたりと、こんがらがります。

私がいつもやる対策は、非常に簡単です。

”全体をカッコでくくって否定する”だけです。

!(
  Status = "1" &
  Type != "A"
)

こんな感じです。

また、条件が長くなっても、式が見通せるよう、改行やインデントを使っています。

これだけでずいぶん可読性は上がると思いますよ。

2023/03/14

ブログ始めます!

みなさま。
はじめまして。

就職してから、ずっと Notes/Domino だけを担当しています。今となってはかなり特異な技術者といえますね...

Notes/Domino に関する情報は、ネット上には少ないですよね。微力ながら少しでも補完できればと思い、ブログをはじめることにしました。

日々の業務で発見したこと感じたこと、イベントやセミナーの参加記録、参照頻度の高いヘルプやコードなど、記録しておきたいことを思いつきで記載いたします。

記載する内容によってはプログラムや設定に関して掲載することもあるかと思います。

ご参考にしていただければ幸いに思います。ただ、ご利用にあたっては、十分ご検証の上、ご自身の責任でお願いいたします。

今後とも、どうぞよろしくお願いいたします。