表で合計行の表示

最近 Oracle ADF を使ってます。古き良きC/S時代のVisualBasicみたいなデータバインディング付きのUIコンポーネントなんかがあったり、コンポーネントIDEのデザイナ上でペタペタ貼って画面を作ったりと、おじさんにはすんなり理解できそうな感じがよいです。まあ、JDeveloperが生成するXMLの山や、「動かしてみないとわからない」感が非常に危なっかしいという面もありますが。

ただ、テキトーに書くとうまく動いてくれず、情報も少ないので、ちょっとしたことでも実装方法を探すのに余計な時間を食わされるのが辛いところ。

ということで、しょーもないプラクティスをメモ代わりに書いていこうという次第。

で、一回目は、データバインディングした表(af:table)に合計行を表示する手順。VBのグリッドコントロールならプロパティ一発なんですけどもねえ。

  1. データ元となる View Object に属性を追加する。属性の編集ダイアログ「ビュー属性」で、「値のタイプ」を「式」にし、「object.getRowSet().sum("(集計したい属性名)")」を設定。ここの集計関数は、sum 以外に count, avg, min, max が標準で用意されてる模様。
  2. 表示するページのデータバインディング定義を開き、1で追加した属性をバインディングに追加する。
  3. 表示するページのデザイナを開き、ADF表の集計したいカラムを選択し、右クリック→「ファセット - Column」→「Footer」をクリック。すると、フッタ行が表示され、選択したカラムの下にFooterファセットが追加される。
  4. Footerファセットに出力テキスト(af:outputText)を追加し、value属性にEL式「#{binding.(1で追加した属性名).inputValue}」を設定する。

この際、 データコントロールから属性をドラッグ&ドロップすると、value属性が「#{row.(属性名)}」となり、フッタでは row が取れないのでうまく表示されない。

以上。

Footerファセットにはalignの設定ができないので、右寄せにしたい場合は出力テキストをJSFコンポーネントのPanel Grid(h:panelgrid)でラップして、Grid Panelのstyle属性にtext-align:right;を追加してあげましょう。

また、集計元のカラムが編集可能で、編集したら即座に再計算したい場合は、4 で追加した出力テキストのPartialTriggers属性に、集計元フィールドのidを設定してあげるとよいです。

ちなみに、View Object の属性の初期値欄に入力する式は、Oracleのドキュメントで「Groovy Expression」と説明されていて、Groovyの書式に従って解釈されるようですよ。

別解としては、集計関数込みのSQLで新たな View Object を定義して、元のView Objectとリンクするという方法も。グルーピング単位が固定になってしまうのと、DBにコミットするまで再計算されなくなりますが、件数が多い場合はこっちのほうがパフォーマンスはよいかと思います。