- ベストアンサー
Access フォーム コンボボックス
フォーム上のコンボボックスの選択したデータをテーブルに保存するにはどのようにすれば宜しいのでしょうか? 実際のものは、社員が複数人表示されていまして、その社員一人一人が1日ごとの出勤が可能か不可能かをコンボボックスから選択しテーブルに書き込みたいのですが、その社員一覧のテキストボックスと出勤可・不のコンボ(コントロールソースにてテーブルの各日付ごとに設定)をフォームに作ったところ、社員一覧と社員に対するコンボがずらっと表示さるのですが、コンボを選択しようとしますと下部に「このコントロールは式○○に連結しているため編集できません。」と表示されます。 長文になり、尚且つかなり分かりづらい説明で申し訳ございませんが宜しくお願い致します。
- みんなの回答 (7)
- 専門家の回答
質問者が選んだベストアンサー
> 改めて1の説明を お待たせ致しました。 では「1」のパターンの説明をさせて戴きます。 なお、今回も、1年分のデータを同じテーブル内で管理する形になっています。 A)テーブル群の作成 以下のテーブルは前回のまま使用: ・社員一覧 ・可否リスト 以下のテーブルを新規作成: ・出勤予定A 設置フィールド=社員ID、月度、1日(数値型・バイト)、2日(数値型・バイト)・・・31日(数値型・バイト) ※デザインビューで以下を設定: ・全ての日付系フィールドに既定値=「0」を設定 ・「社員ID」「月度」の組み合わせを「主キー」に設定 ・月度リスト 設置フィールド=月度(数値型) ※1~12の整数12レコードを予め保存 以上のテーブルを作成し、「出勤予定」以外のテーブルにレコードを保存したら、以下のSQLで「出勤予定A」テーブルにレコードを作成します: INSERT INTO 出勤予定A ( 社員ID, 月度 ) SELECT 社員一覧.社員ID, 月度リスト.月度 FROM 月度リスト, 社員一覧; クエリの作成方法は前回と同じです。なお、前回は全部で12回クエリを実行しましたが、今回は1回のみになります。 B)出勤予定の参照・編集用フォームの作成 1)新規フォームを作成し、フォームヘッダに「対象月度」テキストボックスを設置 2)フォームのプロパティシートで、「データ」タブ・レコードソースに以下のSQL文を貼り付け: SELECT 出勤予定A.* FROM 出勤予定A WHERE (((出勤予定A.月度)=[Forms]![MF_出勤予定A]![対象月度])); 3)メニューで「表示(V)」→「フィールドリスト(L)」をクリック 4)「書式設定」ツールボックスでコンボボックスをクリックした後、フィールドリストから「社員ID」をフォーム詳細領域にドラッグアンドドロップし、「社員ID」コンボボックスを作成 (コンボボックス名は「社員」に変更しても可) 5)プロパティシートで、上記コンボボックスに以下の設定を記録: 「書式」タブ・列数=2、「データ」タブ・値集合タイプ=テーブル/クエリ、同タブ・連結列=2 同タブ・値集合ソース=SELECT 社員一覧.社員名, 社員一覧.社員ID FROM 社員一覧 ORDER BY 社員一覧.社員名; 6)同様にして、「1日」コンボボックスを作成 7)プロパティシートで、上記コンボボックスに以下の設定を記録: ※前回の「可否ID」コンボボックスと同じ設定。 「書式」タブ・列数=2、「データ」タブ・値集合タイプ=テーブル/クエリ、同タブ・連結列=2 同タブ・値集合ソース=SELECT 可否リスト.可否, 可否リスト.可否ID FROM 可否リスト; 8)「1日」コンボボックスと同様に、「2日」~「31日」コンボボックスを作成、設定を記録 9)プロパティシートでフォームに以下の設定を記録: 「書式」タブ・既定のビュー=帳票フォーム、「データ」タブ・追加の許可=いいえ、 同タブ・削除の許可=いいえ 10)フォームヘッダに「表示」コマンドボタンを作成し、プロパティシートの「クリック時」にカーソルをおいたら、「...」(ビルダ)をクリックし、以下の文を貼り付け: Private Sub 表示_Click() Requery [30日].Visible = (対象月度 <> 2) [31日].Visible = (対象月度 = 1 Or 対象月度 = 3 Or 対象月度 = 5 Or 対象月度 = 7 Or 対象月度 = 8 Or 対象月度 = 10 Or 対象月度 = 12) End Sub 11)フォームを「MF_出勤予定A」として保存(仮) これで、各人の出勤予定の入力/参照兼用のフォームができるはずです。 不明な点などありましたら、遠慮なくご質問下さい。
その他の回答 (6)
- DexMachina
- ベストアンサー率73% (1287/1744)
> 完成までの期間が大幅に短縮されそうです。 お役に立てて何よりです。 > 社員名の列を固定することは可能でしょうか? 帳票型では私も方法を知りませんが、データシート型にすれば「書式(O)」→「列の固定(Z)」の使用により、可能になります。 但し、この場合はヘッダ・フッタなどが表示されなくなりますので、それらを両立するには、「単票型メインフォーム」+「データシート型サブフォーム」の形に変更するのがよいと思います。
お礼
貴重な御回答ありがとうございます。 同じご質問で何回もは失礼だと思い新しく質問を作りましたので、宜しかったら列固定の回答(・コマンドボタンのコード・メイン・サブで今まで通りに社員及び出勤予定が表示されない)をお願いできないでしょうか?(下記URL) http://oshiete1.goo.ne.jp/kotaeru.php3?q=1601818 宜しくお願い致します。
- DexMachina
- ベストアンサー率73% (1287/1744)
では、手順をご説明します。(かなり長文です) 因みに、1年分のデータを、全て同じテーブルで管理する形になっています。 A)テーブル群の作成 ・社員一覧 設置フィールド=社員ID(数値型・長整数)、社員名(テキスト型) (必要に応じて、入社年度などを追加しても可) ※「社員ID」に「主キー」を設定 (「社員ID」にカーソルをおいた状態で、「主キー」ボタン(ツールバーの鍵マークボタン)をクリック) ・可否リスト 設置フィールド=可否ID(数値型・バイト)、可否(テキスト型) ※「可否ID」に「主キー」を設定 ※このテーブルには、(可否ID,可否)=(0,?),(1,○),(2,×)の3レコードを予め保存 ・出勤予定 設置フィールド=社員ID(数値型・長整数)、月度(数値型・バイト)、日付(数値型・バイト)、可否ID(数値型・バイト) ※デザインビューで以下を設定: ・「可否ID」の既定値=「0」 ・「社員ID」「月度」「日付」の組み合わせを「主キー」に設定 (Excelと同じ要領で3行を同時に選択した後、「主キー」ボタンをクリック) (主キーが設定されると、その行の左に鍵マークが表示されます(この場合、3行に鍵マークを表示)) ・日付リスト 設置フィールド=日付(数値型) ※1~31の整数31レコードを予め保存 以上のテーブルを作成し、「出勤予定」以外のテーブルにレコードを保存したら、以下のSQLで「出勤予定」テーブルにレコードを作成します: INSERT INTO 出勤予定 ( 社員ID, 日付, 月度 ) SELECT 社員一覧.社員ID, 日付リスト.日付, [対象月度は?] AS 月度 FROM 社員一覧, 日付リスト WHERE (((日付リスト.日付)<=31) AND (([対象月度は?])=1 Or ([対象月度は?])=3 Or ([対象月度は?])=5 Or ([対象月度は?])=7 Or ([対象月度は?])=8 Or ([対象月度は?])=10 Or ([対象月度は?])=12)) OR (((日付リスト.日付)<=30) AND (([対象月度は?])=4 Or ([対象月度は?])=6 Or ([対象月度は?])=9 Or ([対象月度は?])=11)) OR (((日付リスト.日付)<=29) AND (([対象月度は?])=2)); 新規クエリをデザインビューで開いたら、メニューの「表示(V)」→「SQLビュー(Q)」をクリックし、既定で表示されている「Select;」等を削除して、上のSQL文を貼り付け、適当な名前(「MQ_予定作成」等)をつけて保存します。 このクエリを実行すると「対象月度は?」と聞かれるので、まず1を入力して下さい。「出勤予定」テーブルに全社員の1月の予定が「可否=?」で記録されます。(「1月」等ではなく、数字のみ入力します) 以降、このクエリを同様に起動し、「対象月度は?」の問いに2~12を順次入力すれば、1年分の予定が記録されます。 なお、閏年分の「2/29」も追加されているので、通常の月では上記SQL文の最後にある「<=29」を「<=28」とするか、追加後に「月度=2&日付=29」のレコードを削除する削除クエリを「出勤予定」テーブルに実行して下さい。 B)出勤予定編集用のフォームとクエリの作成 1)新規フォームを作成し、フォームヘッダに「対象月度」テキストボックスと「対象社員」コンボボックスを設置 2)プロパティシートで、上記コンボボックスに以下の設定を記録: 「書式」タブ・列数=2、「データ」タブ・値集合タイプ=テーブル/クエリ、同タブ・連結列=2 同タブ・値集合ソース=SELECT 社員一覧.社員名, 社員一覧.社員ID FROM 社員一覧 ORDER BY 社員一覧.社員名; 3)フォームを「MF_予定編集」として保存(仮) 4)新規クエリを作成し、以下のSQL文を貼り付け、「MQ_予定編集」として保存 SELECT 出勤予定.社員ID, 出勤予定.月度, 出勤予定.日付, 出勤予定.可否ID FROM 出勤予定 WHERE (((出勤予定.社員ID)=[Forms]![MF_予定編集]![対象社員]) AND ((出勤予定.月度)=[Forms]![MF_予定編集]![対象月度])); 5)「MF_予定編集」フォームのレコードソースに「MQ_予定編集」クエリを設定 6)上記フォームのフォームヘッダに「表示」コマンドボタンを作成し、クリック時イベントに再クエリ(requery)を設定 7)メニューで「表示(V)」→「フィールドリスト(L)」をクリック 8)フィールドリストが表示されるので、その中の「日付」をフォーム詳細領域にドラッグアンドドロップし、「日付」テキストボックスを作成(コントロールソースが自動的に設定される) 9)「書式設定」ツールボックスでコンボボックスをクリックした後、「可否ID」コンボボックスを同様に作成 (「可否ID」の「名前」は、「可否」に変えても可) 10)プロパティシートで、上記コンボボックスに以下の設定を記録: 「書式」タブ・列数=2、「データ」タブ・値集合タイプ=テーブル/クエリ、同タブ・連結列=2 同タブ・値集合ソース=SELECT 可否リスト.可否, 可否リスト.可否ID FROM 可否リスト; 11)プロパティシートでフォームに以下の設定を記録: 「書式」タブ・既定のビュー=帳票フォーム、「データ」タブ・追加の許可=いいえ、同タブ・削除の許可=いいえ 12)フォームを上書き保存 これで、ヘッダの「対象社員」「対象月度」の両方を指定して「表示」ボタンを押すと、「日付」と「可否」が縦に並んだ形で表示されます。 C)クロス集計クエリの作成 新規クエリをデザインビューで開き、以下のSQL文を貼り付け、「MQ_出勤予定」として保存: TRANSFORM First(可否リスト.可否) AS 可否の先頭 SELECT 出勤予定.月度, 社員一覧.社員名 FROM (社員一覧 INNER JOIN 出勤予定 ON 社員一覧.社員ID = 出勤予定.社員ID) INNER JOIN 可否リスト ON 出勤予定.可否ID = 可否リスト.可否ID GROUP BY 出勤予定.月度, 社員一覧.社員名 PIVOT 出勤予定.日付; このクエリを実行すると、各社員の出勤可否が一覧で表示されます。 (但し上の状態では、1年間の予定全てが、月度でソートされて表示されます。必要に応じてフィルタ操作等を行って下さい) なお、前回にも説明した通り、クロス集計クエリは参照専用のため、ここで「可否」などを編集することはできません。 補足説明が必要でしたら、またご質問下さい。
補足
長文にわたり、細かな所まで説明していただいたおかげで実装できました。本当にありがとうございます。 その中、大変申し上げにくいのですが、私がDexMachina様から説明してもらいたかったのは1だったのですが、何かの間違えで2でお願いしてしまいました。 こちらの、手違いで大変申し訳ありませんが、改めて1の説明をお願いできますでしょうか? 本当に、本当に申し訳ございません。 宜しくお願い致します。
- DexMachina
- ベストアンサー率73% (1287/1744)
No.2です。 > 上記のようなフォーム構造にしております。 え~・・・実は、私が挙げた「1」,「2」のどちらの『テーブル』でも、CELSIOR2005さんが望むような『フォーム』を作成することが可能です。 で、通常、同じようなデータ(今回の例では「出勤可否」)を扱う場合は、「2」のようなデータをまとめ方をした方が効率的なのですが・・・直感的には「1」の方がわかりやすいのも事実です。 どちらで回答すればよろしいでしょうか? 参考として、以下に「1」と「2」のメリット・デメリットを簡単にまとめてみます。 「1」: ・直感的にわかりやすい ・データ入力と参照の両方を、縦軸:社員名、横軸:日付の表示でできる ・出勤可否を記録するテーブルに、日数分の列(フィールド)が必要 (ひと月分を1テーブルとするなら28~31列) ・フィールドが多いため、後で検索やデータ転用をするには向かない (抽出条件を各フィールドで個別に設定する必要がある) 「2」: ・出勤可否を記録するテーブルは、「社員ID」「日付」「出勤可否」の3フィールドの設置で済む ・同種のデータが1フィールドに記録されるため、検索やデータ転用が容易 (但し、1~12月で別テーブルとするなら、クエリでもそれなりの対応が必要) ・縦軸:社員名、横軸:日付で表示するには、「クロス集計クエリ」を使う必要がある ・「クロス集計クエリ」は参照専用になるため、入力用には別のフォームが必要 (例えば、1社員分のデータが日付分だけ縦に並ぶ形)
補足
お手数ですが2でお願い致します。
#1です。色々な実装がありそうですが、簡単なのはサブフォームの使用かと思われます。制約も多いですが、簡単なサンプルを作ってみました。以下 氏名(テーブル) フィールド(属性):氏名(テキスト)、氏名ID(オートナンバー)、月(数値) 出欠(テーブル) フィールド(属性):氏名ID(数値)、月(数値)、1(Yes/No)~31(Yes/No) フォーム1 レコードソース:氏名 テキストボックスを貼り付けて、コントロールソース:氏名 コンボボックスを貼り付けて、コントロールソース:月、値集合タイプ:値リスト、値集合ソース:1;2;3;4;5;6;7;8;9;10;11;12 別途、出欠(フォーム)を用意 レコードソース:出欠 テキストボックスで、デバッグ用も兼ね、氏名、月を貼り付ける。 チェックボックスで1~31 フォーム1にサブフォームとして「出欠」を埋め込み、リンクを 氏名ID;月 の二つでとる。 これで基本的に良いのですが、月を変えても、その結果にすぐ反応しません。そこで月コンボボックスの更新後処理イベントハンドラーに[イベント プロシージャ]で DoCmd.RunCommand acCmdSaveRecord DoCmd.Requery " の二行を書き込みます。これで基本的にはお望みの形になるかと。 制約その他 ・月毎に別テーブルを用意するのは、切り替えが面倒です ・上記例では社員を選択するのがやりにくいです。もう一工夫必要でしょう ・このままでは2月でも31日まで表示されます。このあたりももう一工夫
お礼
細かい所まで説明していただきありがとうございます。 色々な方法で試してみたいと思います。 ありがとうございました。
- DexMachina
- ベストアンサー率73% (1287/1744)
ひょっとして、コントロールソースに「=~」という形で式を設定されている、ということでしょうか? 参照専用のフィールドの場合はコントロールソースに式を設定しても問題ありませんが、コントロールの入力値をテーブルに保存するには、保存先のフィールドを「コントロールソース」に指定する必要があります。 ここに式を設定すると、ご質問にあるようなエラーが発生します。 それと、テーブルの構造を確認したいのですが: 1) 氏名 1日 2日・・・・31日 鈴木 ○ × ○ 佐藤 ○ ○ × 田中 × ○ ○ 2) 氏名 日付 可否 鈴木 1日 ○ 佐藤 1日 ○ 田中 1日 × 鈴木 2日 × 佐藤 2日 ○ 田中 2日 ○ この1)、2)のどちらかの形、ということでよろしいでしょうか? それとも全く別の形でしょうか? もし2)の形で、フォームのレコードソースにクロス集計クエリを指定しているとすると、クロス集計クエリは参照専用のため、やはり編集はできなくなります。 (ただ、エラーメッセージの内容を見ると、これではなさそうですが)
補足
フォームヘッダー----------------- 年(コンボ)月(コンボ) 1~31 詳細----------------------------- 氏名 ○or×or?(コンボ) フォームフッター----------------- 色々なボタン等 上記のようなフォーム構造にしております。 DexMachina様が回答してくださった1の形がまさに、私が望んでいる形になります。 それでテーブルには1~12のテーブルがあり、 ヘッダーのコンボで選ばれた月と相当するテーブルに保存する構造にしたいと思っており(まだ出来ていない)1年間保存されていれば十分なので。 あと、各社員横にあるコンボで出勤予定を選択してテーブルに保存する際には社員IDで社員を特定し各レコードごとに保存していきたいと考えております。 コントロールソースを設定しないと、15日なら15日で各社員全員の15日がいっぺんに変更されてしまいます。 やはり今、私が考えているやり方は効率が悪いでしょうか? 分かりづらい説明で大変申し訳ございませんが宜しくお願い致します。
コンボボックスを編集(選択)可能にするには、プロパティでコントロールソースを空白にし、値集合ソース、連結列に適当な値を入れてやればよいです。 しかしお望みの 社員を選択し、出欠を. . . . にコンボボックスは適しません。無理すれば出来るでしょうが使いにくいです。それではどうするか フォームにテキストボックスを貼り付け、そのコントロールソースを社員名にします。フォームの書式で、「既定のビュー」を帳票に設定します。これで社員が一覧できます。社員名の右(どこでも良い)に出欠を表示編集するチェックボックスを貼り付け、これのコントロールソースを出欠(Yes/no型)に結びつけます。コンボボックスデモできますが面倒です。 これで社員とその出欠が一覧編集できるでしょう。 それではコンボボックスはいつ使うのか? 社員が複数の選択肢から一つを選ぶのに使います。だからそれが出欠でも良いのですが、選択肢として別のテーブルかリストを用意する必要があります。選択結果の数値やテキストが社員テーブルの当該フィールドに書き込まれるようにします。
お礼
回答、的確なアドバイスありがとうございます。 再度挑戦してみます。 ありがとうございました。
お礼
完成しました。 本当に細かな所まで説明していただき助かりました。本当にありがとうございます。 DexMachina様のおかげで完成までの期間が大幅に短縮されそうです。 お手数をおかけしたその直後で申し訳ございませんが、フォーム上で日付が表示しきれていない部分を閲覧したいときに右にスクロールすると社員名が見えなくなってしまうのですが、社員名の列を固定することは可能でしょうか?(確か不可能だったような・・・)