見積デモの実装解説
では、基礎を踏まえた上で見積デモのサンプルを見てみましょう。今回も前回と同様、ソースコードが理解しやすいように、印刷の機能を抽出して作成したサンプルを添付ファイルとして用意しました。実際のソースコードについてはそちらをご確認ください。
サンプルを実行すると、以下のような画面が表示されます。
画面の左上にある各入力項目は、見積先の詳細情報を入力するためのものです。見積書作成のためには必須であるため、これらの項目には入力チェック機能を実装しています。
||見積先電話入力 {let company-phone-field:TextField = {TextField width = 150pt, ||validate-withを用いて必須入力と ||形式チェックを追加 {validate-with {RegExpValidator.from-ValidationPattern ValidationPattern.ja-phone-number }, required? = true }, ||入力完了時に電話を見積書へ反映する {on ValueFinished at tf:TextField do {if tf.validation-result == null then {phone.add tf.value,replace? = true} } } } }
各入力領域は入力チェック機能が実装されましたが、『見積書発行』ボタンを押した時に値が不正のままだと、見積書も不正のまま印刷されてしまいます。そこで、『見積書発行』ボタンを押したときにも入力チェックが実行されるようにボタン側に処理を実装します。
{CommandButton label = "見積書発行", {on Action do ||validate-dialogを用いて ||入力項目の一括チェックを行います。 {if {validate-dialog input-base-info} then ||印刷を実行します。 {print-graphic estimate-print} } } }
『見積書発行』ボタンに記述しているvalidate-dialogというのは指定したグラフィックの中に含まれる入力チェックを一括で実行し、不正な点があればエラーメッセージを表示するというものです。validate-dialogプロシージャはエラーの有無をboolで返しますので、この返却された値を見ながら、エラーが発生したかどうかを判定することが可能となっております。ここでは、validate-dialogがtrue、つまりエラーが存在しない場合のみ、印刷を実行します。
続いて、ヘッダー部分の印刷の制御を行います。今回、ヘッダーには見積先の名称や住所、電話番号などが入力されますが、入力内容に応じて帳票上の文字を変更する必要があります。そこで、以下のように実装しました。
{let name:Frame = {Frame text-underline? = true}} {let name2:Frame = {Frame}} {let address:Frame = {Frame}} {let phone:Frame = {Frame}} (省略) ||見積先名称入力 {let company-name-field:TextField = {TextField width = 150pt, ||validate-withを用いて必須入力チェックを追加 {validate-with {StringValidator}, required? = true }, ||入力完了時に名称を見積書へ反映する {on ValueFinished at tf:TextField do {if tf.validation-result == null then {name.add tf.value&" 御中",replace? = true} {name2.add tf.value&" 株式会社",replace? = true} } } } } (省略) {estimate-print.add {Frame width = {make-elastic}, halign = "left", name||見積先名称を表示 } }
まず表示用の領域としてFrame型の変数nameを用意します。変数nameで表示する文字列は見積先名称が入力されるたびに更新されます。この変数nameを印刷用グラフィック(変数estimate-print)に含めることで、動的に変更を行います。この処理を通じて、アプリケーションの操作に合わせて印刷用グラフィックを変更することにより、ヘッダー部分を常に最新の状態で印刷することができます。
最後に明細印刷の機能についてです。明細行の印刷は明細の内容とデータ件数によって実装方法が変わりますが、ここでは第2回のときに作成した明細のデータを印刷するという前提で処理を実装しています。
let total:int = 0 ||明細のレコードのイテレーションを行って ||印刷する明細のグラフィックを作成します。 {for r:Record key index:int in {RecordView list} do {estimate-meisai.add {row-prototype index + 1, r["Code"], r["Name"], r["Count"], "台", r["Price"], r["Subtotal"] } } ||合計金額を計算します。 set total = total + (r["Subtotal"] asa int) } ||合計金額を出力します。 {estimate-meisai.add {row-prototype {cell-prototype colspan = 6,halign = "right","計"},total} }
印刷を行うときも、基本はデータの集合であるRecordSetのイテレーションです。レコード1件ずつデータを抽出してレイアウトを整形し、印刷を行います。ここでは行インデックスを取得するためにRecordSetを一度RecordViewでラップしました。RecordViewはRecordSetと同様に操作することができるデータの集合ですが、RecordViewを用いると行のインデックスを取得することができるようになります。
このような機能を組み合わせて、印刷機能が実装されています。実際の動作については、添付ファイルの方にてご確認ください。
おわりに
以上全3回を通じて見積デモの機能をご紹介してきましたが、見積デモの構造を理解いただけましたでしょうか? 見た目は複雑そうな機能も、1つ1つ機能を紐解いていくと、実はシンプルな実装によって実現されています。見積デモはこの他にも日付の入力や見積情報の出力などさまざまな機能がありますが、これらもCurlのAPIを用いて単純に実装されているのがほとんどです。
この他にも、Curl Apps Galleryには100を越えるアプリケーションが公開されています。それらはソースコードも合わせて公開されており、中には実際の開発に役立つアイデアもいっぱい詰まっています。Curlにご興味を持っていただけた方、またCurlの開発を行うことになった方はぜひCurl Apps Galleryを覗いてみてください。