当ブログに掲載しているサンプルは、すべて利用者の自己責任という形でお願いします。
ただし、明らかな不具合がある場合、ご連絡いただければ、訂正記事を出します。
また、こちらのサンプルは、別のサイト等への公開、転載は一切禁止しています。
どうしてもと言う場合は、筆者にあらかじめご連絡ください。

テクてく Lotus 技術者 Slack に参加しよう!

2016年10月24日月曜日

フォームというアイテム名について

皆さん、こんにちは。

Notes/Domino、使ってますか?
11月はNotes/Dominoに関するイベントが多数開催されます。
ちょっと整理してみてみましょう。

11月9日(水) ノーツコンソーシアム オープンセミナー2016 ノーツでワークスタイル変革を!
11月10日(木) IBM Connect Japan 2016 福岡
11月18日(金) ノーツ・しこく・フェスタ 2016 AI×IoT×クラウドの衝撃!
11月21(月)~22日(火) XPagesDay 2016
11月22日(火) テクてく Lotus 技術者夜会

私が把握しているだけでこれですので、各企業様の個別開催等を考えるとものすごい数ですね!!
是非、都合をつけて参加するようにしましょうね。


さて、今日の話題に進みましょう。
qa9 for ICS Developer
でちょっと気になる質問を見つけたので、調べてみたところ、あまりにも奥が深かったので、ブログの記事にしてみます。

質問はこちらです。
ノーツDBのフォーム名に関しての質問

Notes DBで文書を作成すると、どのフォームで開くのかを決めるためのフォームフィールド(アイテム)が自動で作成されます。
それが"Form"になったり、"form"になったりと固定でないのがなぜなのか?ということですね。
Notesクライアントの中だけの話と考えると、ほぼ影響はないのですが、外部連携やJava、JavaScript等を利用する場合には大文字、小文字の判定が行われてしまい、思った通りの結果が得られないことがあります。
ですので、"Form"だったり"form"だったりと不定では困るということです。


では見ていきましょう。

まず、既存のNotes DBをいくつか確認してみました。
すると、確かに"Form"になっているものと"form"なっているものがあるのを発見しました。
フォームフィールド名が"form"になってる


ということで、質問者が言っていることは確かに起こりうるというのがわかりました。
このNotes DBの文書を確認してわかったことがあります。
  1. フォームは複数ある。
  2. 全文書のフォームフィールド名は"form"になっている。
  3. フォームの設計要素に「form」というフィールドは作成していない。
そこで、他にも確認したNotes DBについても同様の確認をしてみましたが、
やはり同じでした。
つまり少なくとも設計の段階では、"Form"なのか"form"なのか、どちらになるかはわからないということです。

既存のNotes DBに手を加えるのはちょっとためらったので(破損してしまったら困りますから(笑))、新規にテスト用のNotes DBを作成しました。
なるべくシンプルにするために以下のような設計にしました。
  1. フォームは「MainTopic」(文書)と「Response」(返答)の2つを作成 
  2. 各フォームには「Subject」フィールドのみを作成
  3. ビューは「($All)」を作成、列情報はデフォルト設計(1列目に@DocNumber関数があるだけ)

念のため、このDBをコピーして複数(5個くらい)作成しておきました(毎回作るのが面倒なので)。

次に、このNotes DBに対して文書を作成してみました。
文書の作成方法はいくつかあります。
  1. Notes DBを選択して[作成]メニューからフォーム名を選択
  2. @Command([Compose];"フォーム名")関数を実行
  3. LotusScriptのNotesUIWorkspace.ComposeDocumentメソッドを実行
  4. LotusScriptのNotesDocumentクラスを使ってバックエンドで作成

実はこのうち、1~3は同じことをやっています。
すなわち、実質フロントエンドで作成するか、バックエンドで作成するかの二択になります。
フロントエンドの場合、フォームフィールド名は設定のしようがありませんので、設計要素に委ねられます。
バックエンドの場合、以下のようなソースを作成してみました。
Sub Click(Source As Button)
    Dim session As New NotesSession
    Dim db      As     NotesDatabase
    Dim doc     As     NotesDocument
    Dim uiws    As New NotesUIWorkspace
    
    Set db  = session.CurrentDatabase
    Set doc = db.CreateDocument
    
    Call doc.ReplaceItemValue( "Form", "MainTopic" )
    Call doc.ReplaceItemValue( "Subject", "テスト:"+Cstr(Now) )
    Call doc.Save( True, True, True )
    
    Call uiws.ViewRefresh
End Sub


ここでは、"Form"という名前にしているので、このソースをコピーして
    Call doc.ReplaceItemValue( "form", "MainTopic" ) 




に変更したものも同時に作成しておきました。


では、実際に文書を作成してみましょう。
まず、フロントエンドで文書を作成してみました。
出来上がった文書のプロパティを見てみると、フォームフィールド名は"Form"になっています。
フォームフィールド名は"Form"になっている

続けて、バックエンドで文書を作成してみます。
"Form"でセットしているもの、"form"でセットしているものの順番で作成しました。
さて、"Form"で作成した方は確かにフォームフィールド名は"Form"になっていました。
問題は"form"で作成した方です。
プロパティを見ると・・・"Form"になっています!
"form"で作成したけど、"Form"になってる

最初に確認した発見の中の法則に当てはまっていますね(全文書のフォームフィールド名は統一される)。
つまり、このNotes DBで今後、文書を作成する場合は、どんなに頑張っても(*1)、フォームフィールド名は"Form"になるということになります。

では、Notes DB作成時にコピーしておいた別のNotes DBを使ってやってみましょう。
今度は最初に作成する文書はバックエンドで"Form"でセットするものにしてみます。
この文書のプロパティを見ると、フォームフィールド名は"Form"になっていました。
バックエンドで文書を作成したら"Form"になった

ということは、この後文書を作成しても"Form"になるだろうと予想して、"form"でセットする法を実行してみましたが、やはり結果は"Form"になりました。


最後にもう一つコピーしておいたNotes DBを使って、最初に"form"の値でバックエンドで作成する法を実行してみました。
この文書のプロパティを見てみると・・・
フォームフィールド名が"form"になっています!
フォームフィールド名が"form"になっている

やりました!故意に"form"というフォームフィールド名の文書を作成することができました。
念のため、フロントエンドで文書を追加してみましたが、やはり"form"になっていました。
これはフロントエンドで文書を作成した

"form"という名前のフィールドが作成される条件のうち、少なくとも1つは発見することができました。
でも、本当にこれで全部でしょうか?
ここで、こぴーしておいた4つ目のNotes DBの設計を修正して、「Form」という名前でフィールドを作成してみましょう。計算結果にして、値はそれぞれのフォーム名である"MainTopic"、"Response"にしておきます。
フォームに"Form"というフィールドを追加


このNotes DBに対して、フロントエンドで文書を作成してみましょう。
文書のプロパティを見ると、"Form"になっています。
文書のプロパティは"Form"になっています

これでこのNotes DBでは、フォームフィールド名は"Form"になることが予想されます。

このことから、5つ目のNotes DBの設計を修正して、"form"フィールドを作成した場合は
文書のフォームフィールド名は"form"になるでしょう(実際、そうでした)。


最後に、すでに文書が作成してあるNotes DBに対して、フォームに"Form"というフィールドを作ったらどうなるのか?を見てみましょう。
文書のフォームフィールド名が"form"になっている3つ目のNotes DBの設計を修正して、フォームに「Form」というフィールドを追加します。値はそれぞれ"MainTopic"、"Response"にします。
この状態で文書を作成してみると・・・
フォームフィールド名は"form"のままでした。
フォームフィールド名は"form"のまま

すでに文書があり、そのフォームフィールド名が"form"なので、そちらに準じるようです。

なお、文書をすべて削除してから、設計に「Form」フィールドを追加して、再度文書を作成しても、フォームフィールド名は"form"でした。
どうやら、Notes DB内のどこかにフォームフィールドを記憶しているようです。


ということで、
Notes DBに最初に文書を作った時のフォームフィールド名の値がそのまま引き継がれる
というのが今のところの回答です。

他にも、新規DBで「forM」というフィールド名でフォームを作成してから文書をみたところ、フォームフィールド名は"forM"になりました。

つまり、フォームフィールド名は大文字小文字を問わず、「form」となっていればなんでもよい。
ということなんでしょう。





*1 実際には、次の方法でクリアすることができますが、事実上不可能と言っていいでしょう。
  Notes DB内の全文書を削除して、compactを「-c」もしくは「-r」オプションで実行する。
  または、このNotes DBを設計要素のみで新しくコピーする。



上記でテストした以外にもXPagesを使った場合やC APIを使った場合など、色々な状況が想像されます。
よって、
大文字小文字の判別をしないといけないような作りにするのではなく、フォームフィールド名は一度大文字なり小文字なりに変換してから取得するといったような工夫をすることが必要といえるでしょう。



では、今日はこの辺で・・・




Notes/Dominoで困ったことがあれば、弊社にお問い合わせください。
IBM Championの私が承ります!
お問い合わせはこちらから→Lotus Notes/Domino カスタマイズとセキュリティ強化 - 株式会社エフ