2010年6月11日金曜日

JasperReportsでクロス集計を行う

データを分析する上で集計表にするというのは可読性も上がり有効的です。

今まではデータをExcel形式に出力して集計したりピボットテーブルでまとめていたのですが、JapserReportsでクロス集計(Crosstab)という機能があるようなので試してみました。
要点は以下の2点

・Summary領域に作成する
CrosstabをPageHeaderやDetailに配置して実行してみると以下のエラーが発生します。

  Error incrementing crosstab dataset

このフレーズで調べてみた所、以下のサイトで簡潔に答えが出ていました。
JasperForge Forum

・複数ページになるとレイアウトが崩れるので
  1ページにまとまるようにする
これはこういった仕様なのかもしれません。


以下手順です。

1、レポートを加工
今回は今まで使っていた一覧形式のレポートを流用しました。 明細を一覧に表示した上で最後に表を表示したいのであればそのままですが、今回は表だけにしたいのでSummary領域だけを残し後は最小化 (高さを0に)します。

2、Crosstabを追加
パレットからCrosstabをドラッグ&ドロップimage

「次へ」をクリック
image

行要素を選択、ここでは二つまで選択できますが、後でから追加、編集が可能です。複数選択した場合は1,2の順番でグルーピングされますので部門別社員別の様な見方をしたい場合はそのように設定します。
image

列要素の選択、行要素同様 
image

集計要素を選択します。 一般的な集計以外に偏差も取れるようですがシンプルにSumを選択
image

表のスタイルを選択します。特にこだわりが無ければそのまま「完了」をクリックします。ちなみにここで「背景色無し」という設定は出来ないので後でから背景色を抜く作業をします。
image

これでCrosstabが配置されます。
image

Crosstab内の編集を行う場合は右のCrosstabを、レポート自体を編集する場合は左のMain reportをクリックして画面を切り替えます。
image


おまけ
・0を非表示に
集計結果が0の場合は表示しない方が見やすいので
各要素の Print When Expressions に

$V{XxxMeasure}.equals(Integer.valueOf(0)) ? Boolean.FALSE : Boolean.TRUE

と入れて対象項目が0の場合はBoolean.FALSEを返し非表示にします。

・背景色の変更
デフォルトのCrosstabは水色が基本の配色になっていますが、一般的にカラー印刷はコストが掛かるので背景色を取り除きます。

取り除く際はレポートをXML表示にして以下「」内のキーワードを正規表現付きで空文字に置換します。
(分かりづらいですが最後に半角スペースがあります)

「backcolor=.*" 」

2010年6月4日金曜日

中古PCを手配

知り合いが中国で仕事を始めるという事で中古のノートPC手配を頼まれた。
用途としてはインターネットとメール、Officeが使えればいいので、古いPCでもいいのだが、Windows2000は今年の夏でサポートが切れるので対象外、また古いPCにPuppyLinuxやUbuntuを入れてもいいのではと思ったが、何かあった時にサポートが難しくなるのでそれも対象外とした。

また、ちょっと年配の方なのであまり小さいのもちょっと... という要望だったのでそれにあった物を探した。
要望をまとめると以下の通り

提示された要望
・A4サイズのノートPC
・メールとインターネット、Officeが使えればいい
・予算は2万位

これにこちらでの判断を追加すると、
・A4サイズのノートPC
・WindowsXP以降
・CPUはそこそこの物でもOK
・メモリはXPのSP3を考慮すると 512MB以上は欲しい
・無線LANはあっても無くてもOK
・バッテリーは出来るだけあった方がいい
・予算は2万位

個人的にIBM(Lenovo)のThinkPadが好きなのでオークション等を調べてみたらThinkPad R40eが結構出回っているみたいなのでそれがいいと思ったのだが、あの赤丸のポインティングデバイスがいまいち受け入れられないようなので、同じように数が多いDELLを中心に探したが、条件に合うものがなかなか無かった。

色々見てみた所、オークションで2004年製のNECのLet's Noteが手ごろな値段であったので落札、メモリが256MBしかなかったので追加で512MB購入し、全部で23,000円位になった。

商品が到着後、パーティションを切ったりAvast入れたりバックアップイメージを取ったりと諸作業をして引き渡し。
バックアップイメージはWindowsUpdateとその他設定をした状態で取り、外部メディアに保存しているので、もし何かあっても10分位でその時点に復元できるようにした。

バッテリーも良好で2.5時間位は持つようだし、出先で使う分には十分。
その人が持っている、2年くらい前のDELLノートよりも早くて使いやすいと言われた。
最近は新品でも10万円を切る感じで売っているが、用途によっては中古の方がコストパフォーマンスが良いのかもしれない。と思った。


2010年4月16日金曜日

ローカルディスクが ロ と表示される

マイコンピュータの表示がおかしいとと連絡があったので対処、行ってみるとマイコンピュータの中身が以下のようになっていました。

image

普通は以下のようグループ別に表示されるのですが

image

どうやら名前の先頭でまとめられている様子。使っている人も「特に何もしていない」という事でしたので、何か変になったのかなと思いましたが、調べてみたら簡単に解決しました。

image 

マイコンピュータの空いている所で右クリックして

「アイコンの整列(I)」を選択して「種類(T)」を選択

これだけでした。ここで「名前(N)」を選択すると最初の状態になってしまうようです。

2010年3月27日土曜日

Excel2007でグラフ入りのxlsファイルを保存すると小さくなる

Excel2000形式(*.xls)で作ったグラフ入りのファイルをExcel2007で開いて保存するとグラフが小さくなる現象が発生。
色々試してみるとどうやら2007で保存をするだけでグラフのプロットエリアが一回り小さくなる様子。

色々調べてみた所マイクロソフトのサポートに以下のページがありました。

グラフのプロット エリアをサイズ変更される可能性があります、またはがシフトされる少し Excel 2007 でグラフの右部分に

自動翻訳みたいなので内容も若干おかしな日本語になっています。原因の部分も下のように変な文章になっています。

・ブックが、 Excel 97-2003年ブック (*.xls) ファイル形式で保存します。
・倍率が 100% 以外の設定に変更されるとブックを保存します。
・ブックは Excel 2007 と以前のバージョンの Excel の両方に、Excel 2007 ブックとして保存または。

もとになっているページを見てみると

・The workbook is saved in the Excel 97-2003 Workbook
(*.xls) file format.
・The workbook is saved when the zoom setting is changed
  to a setting other than 100 percent.

・The workbook is alternately saved as an Excel 2007 workbook
 both in Excel 2007 and in an earlier version of Excel.

と、表示を100%以外で保存するとこの現象が起きる。と言った内容で書かれていました。

実際問題になっているファイルを見てみると表示倍率は80%でしたので100%に戻してみた所小さくなる現象はでなくなりました。
(微妙にレイアウトが変わってしまう場合があるようですが、
こちらはまた別で調べたいと思います)

取り合えず原因はわかったものの、Excel2000,2003,2007が混在している以上これからも起きうる問題です。パッチとかは出ないのでしょうか?



2010年3月26日金曜日

JasperReportsで四則演算

ACCESSのレポートで列AとBを足したい場合は非連結のテキストボックスを設けて

Private Sub 詳細_Format(Cancel As Integer, FormatCount As Integer)
    テキストボックス = A + B
End Sub

とすればA+Bの計算結果をテキストボックスに表示する事が出来ましたが、
(式エディタは面倒なので使ってませんでした)
JasperReportsでやってみた所、うまくいかずはまりました。

まず、ACCESSと同じ感覚で以下の様にして

 $F{A} + $F{B}

レポートのコンパイルを行うとこんなエラーが

The operator + is undefined for the argument type(s) java.lang.Integer, java.lang.Integer

Integerでは + 演算子が使えないという内容でしたので今度は

 $F{A}.intValue() + $F{B}.intValue()

とした所

Cannot cast from int to Integer

というエラーに...

エラーの内容を元にWebで調べてみたのですが、英語での情報しかない上に、「データソースの段階で計算しておけばいいじゃない?」。というような内容であまり参考にはならずで、あきらめようとしていたのですが、どうやらJavaの文法が使えそうな気がしてきたので

Integer.valueOf($F{A}.intValue() + $F{B}.intValue())

の様にしてみた所うまく表示されるようになりました。
VariablesではIntegerのまま使えるのになぜ?という感じではありますが一応解決です。

2010年3月25日木曜日

Hibernateで ORDER BY *** IS NULL ASC を実現したい

MySQLでソート時にNULLを優先させたくない場合は

ORDER BY XXX IS NULL ASC, XXX ASC

と書く事で解決できますが、Hibernateに対応するAPIが見つかりませんでした。

Criteriaを使ってコードがすっきりしているのでSession#createSQLQuery()は使いたくなかったので以下の様にして無理やり実現してみたのですが、もっと簡単に出来ないものでしょうか?

List list
// createCriteria()内で検索条件を追加
Criteria criteriaA = createCriteria(session);
Criteria criteriaB = createCriteria(session);

// キーとなる XXX が Not Null なデータを取得
criteriaA.add(Expression.isNotNull("XXX"));
criteriaA.addOrder(Order.asc("XXX"));
list = criteriaA.list();

// キーとなる XXX が Null なデータを取得しcriteriaAの結果に追加
criteriaB.add(Expression.isNull("XXX"));
list.addAll(criteriaB.list());




2010年3月18日木曜日

障害発生時の画面キャプチャ取得

Robot#createScreenCapture()を使うと現在の画面キャプチャが取れるようなのでそれを画像として保存する処理を仮作成。

離れた事業所で運用しているシステムで障害が発生した場合、電話だけでは要領を得ないので主要な所にはVNCをインストールしてますが、障害が起きている状態で連絡が来るわけでもないので、例外発生時の画面キャプチャを残す事で少しは有力な情報が得られそう。

同じような用途で実行時の画面インスタンス情報もテキスト化する処理を作りたいが、なかなか時間が確保できない...


// 画面サイズの取得
GraphicsEnvironment env = GraphicsEnvironment.getLocalGraphicsEnvironment();
Rectangle rect = env.getMaximumWindowBounds();

// 画面キャプチャ
Robot robot = new Robot();
BufferedImage image = robot.createScreenCapture(rect);

// 取得したイメージを画像へ保存
Date date = new Date();
SimpleDateFormat dataFormat = (SimpleDateFormat)DateFormat.getDateInstance();
dataFormat.applyPattern("yyyyMMdd_HHmmss");
ImageIO.write(image, "gif", new File(dataFormat.format(date) + ".gif"));