今日は2015年8月13日です。夏休み中という方も多いかと思いますが、私は仕事してます。

可哀そうに・・・と思ったら、上のボタンを押してください。
さて、今日もXPagesの話です。
そして、私の嫌いな?日付データの取り扱いについてです。
ノーツには「日付/時刻」型というフィールドタイプがあります。
このフィールドは「日付のみ」とか「時刻のみ」という形でデータを保存できます。
しかし、XPagesでは、そういった形式での保存が難しいです(できないわけではない)。
格納方法については、IBM ChampionのKazunori Tatsukiさんのブログに
XPagesでフィールドに”年月日のみ”、”時刻のみ”の値を設定する方法という形で掲載されています。
さて、これで一安心だ!と喜んでいたのですが、思わぬところで躓いてしまいました。
日付を格納しているフィールドを"複数値可"にしていたのです。
上記のブログにある日付フィールドの取得方法はNotesXSPDocumentのgetItemValueDateTimeという命令です。
これは、複数値の形式に対応していません。
困りましたね。そこで、NotesXSPDocumentではなく、バックエンドクラスのNotesDocumentクラスの命令を使ってみることにしましょう。
NotesDocumentクラスには日付フィールドの値を取得するためのgetItemValueDateTimeArrayという命令があります。
こちらは、文書内の日付フィールド(アイテム)をjava.util.Vectorという配列のオブジェクトで返してくれます。
配列の一つ一つの要素はNotesDateTime型もしくはNotesDataRange型になります。
今回は、日付の範囲ではなく、単なる複数値なので、NotesDateTime型の配列になります。
取得できたら、iterator命令とwhile命令で配列の分繰り返し処理を行います(LotusScriptでいうところのForall関数と考えてください)。
フォームに「Hiduke1」という複数値を許可した日付/時刻フィールドがある場合の保存時の処理を書いてみました。
try { var notesDoc:NotesDocument = document1.getDocument( true ); var hidukeArray = []; var dtArray:java.util.Vector = notesDoc.getItemValueDateTimeArray( "Hiduke1" ); var iterator = dtArray.iterator(); while (iterator.hasNext()) { var dt = iterator.next(); if ( dt!= null ) { dt.setAnyTime(); hidukeArray.push( dt ); } } notesDoc.replaceItemValue( "Hiduke1", hidukeArray ); notesDoc.save(); } catch ( e ) { print ( "エラー:" + e.toString() ); } finally { if ( dt != null ) dt.recycle(); if ( notesDoc != null ) notesDoc.recycle(); } context.redirectToPage( "viewDateTime" );
これを使ってXPagesで文書を保存した後、ノーツクライアントで文書のプロパティを確認した結果が下図です。
![]() |
日付の複数値 |
確かに日付だけの複数値(リスト)として格納されています。
めでたしめでたし・・・
と思っていたのですが、新たな問題が発生しました!!
そもそも日付フィールドに値を入力しなかった場合にエラーになってしまうのです。
同じXPagesを使って日付を入力しないで保存したときのエラー画面です(面倒だったので、Dominoコンソールに吐き出すようにしました)
![]() |
getItemValueDateTimeArrayでエラー発生 |
エラーは「Exception occurred calling method NotesDocument.getItemValueDateTimeArray(string)」となっています。どうやら例外として扱われたようです。
try ~ catch で組んでいるのでエラーをcatchしてくれたという事でしょう。
どうやら、値がnullは許可してくれないようです。
念のため、try ~ catch を外したソースで実行してみましたが、例外が発生するのは変わらずでした。
むしろ、エラーページが表示されてバグだろ!感が丸出しになりました。
![]() |
try ~ catch なしでもエラーはエラー |
どうしましょう・・・
ホントに困りました。
仕方なしに、ヘルプをもう一度よく読んでみました。
すると、NotesDocumentクラスで日付フィールドの値を取得する方法として、もう一つある事に気が付きました。
getItemValue命令です。
こちらは、指定したアイテムの値によって返してくれる値のデータ型を自動的に変更してくれるという賢い命令です。
日付の場合は、getItemValueDateTimeArrayと同じ、NotesDateTimeもしくはNotesDateRangeのjava.util.Vector型の配列で返してくれます。
うん、日付/時刻に至ってはまったく同じじゃないか。ダメだな、こりゃ・・・と思いましたが、モノは試し!ということで、ソースを変更してみました。
try { var notesDoc:NotesDocument = document1.getDocument( true ); var hidukeArray = []; var dtArray:java.util.Vector = notesDoc.getItemValue( "Hiduke1" ); var iterator = dtArray.iterator(); while (iterator.hasNext()) { var dt = iterator.next(); if ( dt!= null ) { dt.setAnyTime(); hidukeArray.push( dt ); } } notesDoc.replaceItemValue( "Hiduke1", hidukeArray ); notesDoc.save(); } catch ( e ) { print ( "エラー:" + e.toString() ); } finally { if ( dt != null ) dt.recycle(); if ( notesDoc != null ) notesDoc.recycle(); } context.redirectToPage( "viewDateTime" );
ホントに、
var dtArray:java.util.Vector = notesDoc.getItemValueDateTimeArray( "Hiduke1" );
を
var dtArray:java.util.Vector = notesDoc.getItemValue( "Hiduke1" );
にしただけです。
しかし!
なんとまぁ、うまくいってしまいました。
つまり、
1.日付を入力しなくても正常に保存できる。
2.日付を一つだけ入力しても正常に保存できる。
3.日付を複数入力しても正常に保存できる。
のです。
当然、日付は日付のみの形で保存されています。
なんなんでしょう・・・
ヘルプをもう少し詳しく見てみると、
getItemValueの場合、「アイテムに値がない場合、このメソッドは空のベクトルを返します。」とあります。
どうやら、最初から値がない(null)を想定したつくりになっているようです。
getItemValueItemDateTimeArrayの説明には、そういったことは書いていませんので、値がないことは想定していなかったのかもしれません。
っていうか、それくらい想定しておけや!
と思いましたが、解決できたので、良し。としておきます。
あー、悩んだ悩んだ。
ということで、XPagesを使いましょう!
では、今日はこの辺で。
【PR】ノーツ/ドミノに関するお問い合わせは下記まで【PR】
単純なDBのカスタマイズから他アプリケーションとの連携までご要望にお応えします!
