ACCESS勉強中のものです(初心者レベル)。
メイン・サブフォームがあり、メインにはユーザー等の入力をしてサブにはテーブルにある商品をコンボで選ぶ形にしてます。(その他数量等の入力あり)。商品には個々に区分けが数種あり(仮にA・B・C等)それは商品テーブルに各入力されています。
サブフォームに一番最初に区分けAの商品を選んだ場合、BやC(つまりA以外)が選べない様にしたいのです。メッセージボックスで警告を出し規制をかけたいのです。フォームのページ毎に一つの商品区分け分商品しか選択出来ない様にしたいのです。
どうしたら簡単にそんな事が出来るのかと思いまして。組立がわからなくて・・・
よろしくお願いします。
通報 ...
メインフォームのレコードソースはテーブルはユーザー情報を格納するもの。
サブフォームのレコードソースはそのユーザーが購入する商品データを入力するもの。
ということですか。
できれば、関係するテーブルのテーブル名とそのフィールド構成を提示してもらえますか。
少なくとも下記の3つのテーブルが必要なはずです。
ユーザー情報のテーブル
商品購入データのテーブル
商品情報のテーブル
データーベースはまずは、テーブル設計が重要でそれがまちがっていたら、使い物にならないので。
フォームにページという概念はないのですが、どのような意味が使っていますか。
何をもって簡単と言うかわかりませんが
コンボボックスの入力規則に以下を設定します
※各項目は実際のフォームの内容に合わせる必要があります
構成は下記です。
1.ユーザーテーブル:●ユーザーID(主キー) ●ユーザー名
2.商品テーブル:●商品ID(主キー) ●商品名 ●区分け
3.取引メインテーブル:●取引ID(主キー) ●日付 ●ユーザー選択(コンボにて)
4.取引明細テーブル(サブ):●明細ID(主キー) ●商品選択(コンボにて) 他数量等 ●取引ID
この3と4を使い(取引IDを1対多でリレーション)して親子フォームを作成しています。
フォームのページというのは私が勝手に認識してました。取引ID毎の親子フォームになっているもので。
取引入力時にその時のサブフォームで一番最初に選択した商品区分け以外の区分けを選ぼうとした場合に警告を出しキャンセルさせたいのです。少し前からこのフォームで処理していたのですが事情がかわり取引毎に同一区分け商品だけが紐付けしなくてはいけなくなったので(過去に入力されたものはいいのですが、今後で)
hiroton さん早速ありがとうございます。関数単体の意味はわかるのですが全体の処理はどういう動きでしょうか?(長い関数式が慣れてなくて、すみません)
宜しくお願いします。
関数は「機能をひとまとめにしたもの」なので、そこだけ抜き出せば何らかの値に置き換わります。複雑な計算式はメモ帳などで整形してみると理解しやすくなります
これをプログラミング的な思考に置き換えていきます
本手法は入力規則を使うことにしたので、「入力可能な
商品ID
かどうかを判定し、入力可能であればその商品ID
を入力規則の値にする」様な計算式を作成しますまず、「サブフォームに一番最初に区分けAの商品を選んだ」の時点で「最初の入力」の場合と「2回目以降の入力」で別な処理を行う必要が出ます。つまり、「何の制限もない初回入力」と「制限のかかる2回目以降」を作る必要があります
「(最初の入力)」はどんな
商品ID
でも入力できる必要があるので、入力規則としては「どんな商品ID
が指定されても同じ商品ID
になるような式」とします。つまり自分自身を設定すれば解決です「(2回目以降の入力)」は、「自身の区分け」と「入力済みデータの区分け」が同じかどうかを判定し、処理を分岐(そのまま入力、または、入力規則のエラーとしてメッセージ表示)させます
ただ、入力規則を使う関係上、「同じかどうか」だけでなく、「同じ場合は自身の
商品ID
」という結果が必要になります。そこで、DLookup関数を使って商品テーブル
から「(入力済みデータの区分け)+自身の商品ID
」のレコードの商品ID
を求めていますこれで、自身が同じ区分内の商品かチェックされるという仕組みです
「(入力済みデータの区分け)」の取得方法はそのまま関数が何をやっているのか考えてみてください。
取引明細テーブルに区分けデータも記録しているのであれば、区分け判定部分の計算式はもう少し単純にできそうですね
実装方法はいくつか考えられますが、「入力規則に計算式を一つ入れればいい」が謳い文句として簡単そうに見えたのでそれで実現しています。(VBA使ったほうがすっきりする回答になるんですけどね)
hirotonさん すごく分かり易い表現でして頂きありがとうございます。お手数かけました。
中々すごい式ですね。VBAでする場合はどう記述したらいいでしょうか? サブフォームで2つ目以降の商品をコンボで選んだ時に警告が出てキャンセルが理想的です。そうすると色々と認識しやすいので。
宜しくお願いします。
VBAでやるなら更新前処理でチェックすればいいでしょう
入力内容はなかったことにして元に戻すなら
Me.Undo
が使えます入力規則のように入力内容をチェックする必要はないので「区分け」の比較だけでいいですね。入力中のデータの方はコンボボックスのデータに「区分け」も含めるようにしておけば簡単に指定できます
もっと言えば、サブフォームのレコードソースをクエリにして、「区分け」を含むようにすれば更に簡単ですね
「取引明細テーブル」と「商品テーブル」を
商品ID
で結合して区分け
フィールドを追加します自分のグループで自分以外に同じ区分けがあるか?をチェックすればいいので
で、同じ「区分け」を指定していると判断できます
入力規則で判定するなら、これを使って
VBAでやるなら、現在サブフォームに読み込まれているレコード内で比較すればいいので
このように実装できます
一部修正
Recordset.Clone
を使うと編集前の状態でRecordsetが作成されるようです(考えてみれば当たり前)。最初のレコードの編集でも編集前と編集後を比較できるのでレコード位置のチェックは不要になりました参考
フォームの Recordset, RecorsetClone, RecordSet.Clone の違いとは?(hatena chipsさん)
取引メインテーブルに区分けフィールドを追加して下さい。
取引メインフォームに区分けフィールド連結テキストボックスを追加して下さい。
そして、取引明細サブフォームの商品選択(コンボにて)の抽出条件に取引メインフォームの区分けフィールド連結テキストボックスを設定するような仕組みを考えて下さい。
例えば、ヘッダーに商品クエリのリストボックスを置く。取引メインフォーム区分け連結テキストボックスの値に応じて、動的に絞り込み、結果が表示されるようにする。必要な商品を選択して、ボタンを押せば、取引明細サブフォームの商品選択に反映されるようにする。
色々なアイデアありがとうございました(レスポンス遅くなりました)。
それぞれ試してみたのですが無反応でした。これは私が完全に理解しておらずVBAの間違い・不足によるものではと思ってます。
それで乏しい知識をひねり、対象の取引IDに対するDFirst関数で先頭のものを参照して2つ目以降を比較することで何とか上手くいきました。
もっと勉強してから頂いたアイデアも再トライしたいと思っています。
色々とお手数かけました。