この特集のトップページへ
>
Chapter 7:プレゼンテーション層の構築
7.7.8 明細処理
●明細の新規作成と編集
フォームが準備できたところで,早速明細情報の新規登録処理から実装してゆく。まずは,明細情報を新規登録するため,List 7-155に示すNewSlipDetailプロシージャを実装する。
List 7-155は,引数に伝票番号をとり,指定された伝票番号と対応する伝票に新しい明細を追加する準備をするためのプロシージャである。
List 7-155では,まず9行目で引数として渡された伝票番号をグローバル変数SlipIDに保存している。そのあと,FormEditSlipDetailフォーム上のテキストボックスやコンボボックスを初期化し,最後にグローバル変数SlipDetailIDに-1を設定している。グローバル変数SlipDetailIDは,編集対象となっている明細の明細番号を保持する変数であり,-1のときには新規明細を示すものとする。
12行目にあるFillComboプロシージャの呼び出しは,その時点で登録されている製品の一覧をCOMBO_PRODUCTコンボボックスに設定するための処理である。FillComboプロシージャは,List 7-156のように実装する。List 7-156の処理は,「●製品一覧にコンボボックスに格納する」で説明した内容とほとんど変わらない。しかし,Business.ProductコンポーネントのGetProductsメソッド(List 6-68)を呼び出して取得した製品情報(ADODB.Recordsetオブジェクト)を,グローバル変数g_objRecに保存しておくという点がやや異なる(18行目)。ここで保存しておいたADODB.Recordsetオブジェクトは,ユーザーが選択された製品の価格を参照するために,あとで用いる予定である。その詳細は,「○製品単価を補完し,合計金額を自動算出する」で説明する。
さて,FormSlipDetailフォーム(Fig.7-92)で[新規]ボタン(BTN_NEWボタン)が押されたときには,まずList 7-155に示したNewSlipDetailプロシージャを呼び出し,そのあとFormEditSlipDetailフォーム(Fig.7-98)をモーダル表示する。その実装は,List 7-157のようになる。
○明細情報の編集同様に,明細情報を編集するためのプロシージャを用意する。ここではFormEditSlipDetailフォームにList 7-158に示すEditSlipDetailプロシージャを実装する。
EditSlipDetailプロシージャは,引数に編集対象となる明細を含む伝票の伝票番号,明細番号,その時点の明細に記載されている製品番号,数量,単価,価格,摘要を順にとり,その情報でFormEditSlipDetailフォーム上のテキストボックスやコンボボックスを初期化する働きを持つ。
ユーザーがFormSlipDetailフォーム(Fig.7-92)の[編集]ボタン(BTN_EDITボタン)を押したときには,EditSlipDetailプロシージャを呼び出してから,FormEditSlipDetailフォームをモーダル表示する。その実装は,List 7-159のようになる。
○[OK]ボタン,[キャンセル]ボタンが押されたときの処理以上で,ユーザーがFormSlipDetailフォーム(Fig.7-92)で[新規]ボタンや[編集]ボタンを押したときに,FormEditSlipDetailフォーム(Fig.7-98)が表示されるようになった。
あとは,[OK]ボタン(BTN_OKボタン)が押されたときにユーザーが入力した明細情報をデータベースに反映させる処理を実装すればよい。その実装は,List 7-160のようになる。
List 6-160では,グローバル変数SlipDetailIDの値が-1であれば(つまり新規登録であれば),20行目にあるようにBusiness.SlipコンポーネントのAddSlipDetailメソッド(List 6-126)を呼び出して伝票を登録し,そうでなければ(つまり既存明細の編集であれば),23行目にあるように同コンポーネントのUpdateSlipDetailメソッド(List 6-128)を呼び出して伝票を更新する,という処理をしている。
なお,UpdateSlipDetailメソッドの実装においては,明細を更新するときに履歴を残すため,明細を削除ずみにしてから新しい明細を追加するという手法をとった(「6.4.3 明細の処理」を参照)。よって,ユーザーが明細を編集したあとは,FormSlipDetailフォームのFLXGrid_SlipDetail階層フレキシブルグリッド上に編集まえの明細が取り消し線を伴って記載され,その下に編集後の明細情報が記載されることになる。
明細を追加したり明細を編集したりした場合には,それに伴い,伝票に記載されている小計,消費税額,合計額などが変更される可能性がある。よって本来ならば,明細の追加や編集に伴って,FormSlipフォーム(Fig.7-86)のDGrid_Slipデータグリッドの内容も更新する必要がある。しかし,本節の冒頭でも説明したとおり,このような機能を実装したところ極端な速度低下が見られたため,今回はその実装を割愛している。
ところで,ここでユーザーが[キャンセル]ボタン(BTN_CANCELボタン)を押したときの処理も実装しておく。[キャンセル]ボタンが押されたときには,何もせず,ただフォームを閉じるだけでよい。その実装は,List 7-161のようになる。
| お詫びと訂正 |
Chapter 6で実装したDataObj.SlipDetailコンポーネントのGetSubTotalメソッド(List 6-124)に不具合があることが判明した。DataObj.SlipDetailコンポーネントのGetSubTotalメソッドは,明細を追加,編集,削除するときに用いるBusiness.SlipコンポーネントのAddSlipDetailメソッド(List 6-126),UpdateSlipDetailメソッド(List 6-128),DeleteSlipDetailメソッド(List 6-129)から呼び出されて,ある伝票の小計(伝票に結び付けられている明細の小計の総和)を算出する働きを持つ。Chapter 6で実装したGetSubTotalメソッドは,正しく小計を返さないという問題があるため,明細を追加,編集,削除するときに,伝票の小計,消費税,合計が不正な値になってしまう。 大変申し訳ないが,DataObj.SlipDetailコンポーネントのGetSubTotalメソッド(List 6-124)をList 6-162のように訂正させていただく。訂正した箇所は19行目であり,“GROU BY”以降を削除している。これは筆者のミスであり,論理的な不具合の修正ではない。 |
以上で,明細の新規登録や編集作業ができるようになったわけだが,もう少し機能を追加したい箇所がある。それは,ユーザーがCOMBO_PRODUCTコンボボックスにおいて製品を選択したときに,自動的にその製品の単価をTXT_UNITPRICEテキストボックスに格納するという処理である。この処理がないと,明細を追加したり編集したりするたびに,該当製品の価格を製品情報ウィンドウ(FormProductフォーム:Fig.7-67)で逐一調べるという作業が必要になってしまう。そこで,List 6-163の処理を実装する。
List 7-163は,COMBO_PRODUCTコンボボックスのLostFocusイベントを処理し,COMBO_PRODUCTコンボボックスがフォーカスを失ったときに,COMBO_PRODUCTコンボボックスで選択されている製品の製品価格をTXT_UNITPRICEテキストボックスに格納するというものである。
製品価格を取得する箇所は9行目である。ここでは,グローバル変数g_objRecに保存されているADODB.RecordsetオブジェクトのFindメソッドを利用して,COMBO_PRODUCTコンボボックスで選択されている製品を含むレコードを検索している。そして11行目で,取得したレコードのPRICEフィールドの値をTXT_UNITPRICEテキストボックスに設定している。
ここではLostFocusイベントを処理して,フォーカスを失ったときにTXT_UNITPRICEテキストボックスに製品の価格を設定するように実装した。しかし,そうではなく,Changeイベントを処理するように実装してもよい。Changeイベントを処理するようにすれば,ユーザーがCOMBO_PRODUCTコンボボックスで製品を選択するたびに,即座にその価格がTXT_UNITPRICEテキストボックスに格納されるようになる。しかし,Changeイベントは,ユーザーがCOMBO_PRODUCTコンボボックスで別の製品を選択するたびに発生してしまうため,どうしてもイベントの発生頻度が高くなり,その処理に伴ってADODB.Recordsetオブジェクトへの検索を実行しても,処理速度がやや低下するという問題がある。そこで今回は,Changeイベントではなく,LostFocusイベントを処理することにした。LostFocusイベントの場合には,フォーカスを失ったときにしかイベントが発生しないので,イベントの発生頻度は少なくなり,上記のような問題は生じない。
ところで,製品が選択されたときだけでなく,単価(TXT_UNITPRICEテキストボックス)や数量(TXT_NUMBERテキストボックス)が入力されたときには,自動的に「単価×数量」が「合計」を示すTXT_PRICEテキストボックスに格納されると便利である。そこで,List 7-164とList 7-165の処理を実装しておく。List 7-164はTXT_UNITPRICEテキストボックスのLostFocusイベントを,List 7-165はTXT_NUMBERテキストボックスのLostFocusイベントを,それぞれ処理し,TXT_UNITPRICEテキストボックスに入力されている値(単価)とTXT_NUMBERテキストボックスに入力されている値(数量)とを掛け合わせ,その結果をTXT_PRICEテキストボックスに設定している。この処理を実装することにより,ユーザーがTXT_UNITPRICEテキストボックスやTXT_NUMBERテキストボックスから別のコントロールにフォーカスを合わせたとき,合計価格が自動的に入力されるようになる。
| 114/134 |
