- 締切済み
2つのサブフォーム間でデータの連携
今、ある単票フォームに、2つのサブフォームを配置し、そのサブフォーム間で金額の連携をしたいと考えています。 【親フォームA】 ・ID1、長整数型(主きー) ・受付日時 ・発注金額総合計 <== ※Bが更新されたら、ここを更新したい 【サブフォームB】 ・ID2、長整数型(主キー) ・ID1(外部キー) ・発注日 ・発注合計金額 <=== ※Cが更新されたら、ここを更新したい ==> Aの更新へ↑ 【サブフォームC】 ・ID3、長整数型(主キー) ・ID2(外部キー) ・発注項目名 ・単価 ・数量 ==>ここを更新する→Bへ↑ ・単位 ==>ここを行進する→Bへ↑ ・摘要 サブフォームB、Cは、いずれも帳票型です。 それぞれ、テーブルA, B, Cがレコードソースで テーブル構成は、上の項目の構成と同じです。 A-ID1: B-ID1 = 1:多 B-ID2: C-ID2 = 1:多 この時、Cで単価と数量を入力したら、Bの発注合計金額の値を更新したいです。 それと同時に、親Form Aの「発注金額総合計」の値を、Bの全てのレコードの「発注合計金額」のSumで更新したいです。 よろしくお願いします。
- みんなの回答 (2)
- 専門家の回答
お礼
ご回答ありがとうございました。 とりあえず、時間的に余裕がありませんので、また、落ち着いた時に書かれている内容を吟味してみたいと思います。 ありがとうございます。
補足
大変お忙しいなか詳しい説明をくださり、ありがとうございます。 以下、私からのお返事を書かせていただきます。 >■前提条件 (1)開発言語(アプリ) → Accessです。 (2)親フォーム及びサブフォームBの更新したい項目はテーブルの項目で、フォームのレコードソースです。リレーションシップも設定済みです。 (3)データベース → Accessです。 >説明(3a).データベースがSQLServerやOracleServerの場合、集計クエリを用いた更新クエリの作成が可能 →先でSQL Serverに移行する事を検討するかも知れません。集計クエリを用いた更新クエリー作成がアクセスでは出来ないという情報、ありがとうございました。 >■準備 >(1)テーブルAの「発注金額総合計」を更新するSQLを用意 >(1A).集計+テーブル作成SQLを用意 (Sum関数利用) ><サンプルコード:SQL名=Q_TBL_B_SumTBL> >SELECT T_TBL_B.ID1, Sum(T_TBL_B.発注合計金額) AS 合計金額 INTO T_TBL_B_SumTBL >FROM T_TBL_B GROUP BY T_TBL_B.ID1 HAVING T_TBL_B.ID1 = ★引数★ >※テーブル作成する理由は、上記前提の説明(3b)の問題点の代替案 Group by + Having句の使い方をこちら「http://www.atmarkit.co.jp/ait/articles/0706/21/news128.html」で調べてみました。 処理の順番では、Where句→Group by句→Having句となるので、Group by句でグループ分けしたものに対して、Having句でID1の抽出する値を絞り込んでいるということですね。 >(1B).(1A)で作成したテーブルを用いて、テーブルAの「発注金額総合計」を更新 ><サンプルコード:SQL名=Q_TBL_B_Upd> >UPDATE T_TBL_B_SumTBL LEFT JOIN T_TBL_A ON T_TBL_B_SumTBL.ID1 = T_TBL_A.ID1 >SET T_TBL_A.発注金額総合計 = [T_TBL_B_SumTBL]![合計金額]; この場合、Update [SUM table b] left join [table a] on ... とすると、左から右への更新クエリーになって、該当するレコードがない場合には、追加クエリーの役目もするのですね。。。 (http://hatenachips.blog34.fc2.com/blog-entry-153.html) >■対応回答(未検証につき作成時には微調整が必要) >(1).サブフォームCの更新時イベントにて、準備(2)のSQL等を実行後(Docmd.RunSQL関数だったかな) >サブフォームBのリクエリーを実施 >(2).サブフォームBの更新時イベントにて、準備(1)のSQL等を実行後(Docmd.RunSQL関数だったかな) >親フォームAのリクエリーを実施 →現在、RecordsetCloneを取得して、計算して、フォームの該当フィールドにセットする処理を作ってみましたが、イベントの処理がなかなか難しいです。ヘタすると、イベントがずっと連鎖して動きっぱなしのような画面の動きになってしまいます。その理由は、多分、親、子、孫で「Before_Updateのイベント」に処理を入れているからです。その対策として、値を更新した後に孫のサブフォームのフレームにSetfocusするとしたら、イベントの連鎖更新が止まりました。 スピードに関して言えば、しかし、処理的には上の更新クエリーのほうがずっと速いのでしょうか? ><備考A> →まずはボタンを作って試してみるというご提案、とても役に立ちそうです。 ><備考B> >リクエリー等を頻繁に行うと、ちらつきが気になる人がよくいます → Me.Repaint = False → Me.Repaint = True ですね <備考C> >フォーム更新後イベントに付き、入力しただけでは反映されません >入力即という事であれば、項目の更新後または変更時イベントで行えばよいと思います >が、その場合以下の点に注意 >(備考C1).Access特有の編集時における元に戻す(確かEscを2回クリック)機能が使えなくなります >(備考C2).さらに頻繁に動作することになる為、データ量によってはレスポンスが悪くなる可能性有 → フィールドの更新後処理で為した時、RecordsetCloneを使うと、値を変える前の古い値で計算してしまい、うまくいきませんでした。なので、Form_Currentで実行していますが・・・ すると、計算結果が更新出来ない時が出てしまう時があり、そのために、ボタンを作ってしまいました。無理やりRecordsetCloneで値の計算をする時、わざわざRuncommand acCmeSaveRecordを実行してから、RecordsetCloneを作っています。 フィールドの更新後処理では、SQLで更新クエリーを実行すると、フォームのレコードソースの値は既に更新されているのでしょうか? よろしくお願いします。