Microsoft Access 掲示板

コンボボックスの連携に伴うもとになるクエリの値について

29 コメント
views
4 フォロー

あるクエリに基づいてフォームを作成しています。
フォームに2つのコンボボックスを置いていて、プルダウンで連動させています。
フォームで入力した値をもとのクエリで見てみると、1つ目のコンボボックスの値がコードになっています。
2つ目のコンボボックスの値は選択したものがきちんと登録されています。
なぜ、1つめはコンボボックスで選択したものではなく、それに紐づくコードなのかわからなく困っています。
1つ目のコンボボックスで入力したものも選択したものがきちんとクエリに反映されてほしいです。
後工程でこのクエリの結果をテーブルに吐き出して、エクセルでエクスポートしてピボットで集計することを考えています。なのでここは数字だと困るのです。ご教授よろしくお願いします。別ルートにてファイルを展開します。

添付ファイル

ojyamajyo
作成: 2019/04/30 (火) 15:30:23
最終更新: 2019/05/01 (水) 17:03:17
通報 ...
  • 最新
  •  
2
ojyamajyo 2019/05/03 (金) 13:16:21

再入力は可能です。
どのようにテーブルを作ればよろしいでしょうか?

3
hatena 2019/05/04 (土) 02:32:44 修正

T_勤怠

フィールド名データ型
社員IDオートナンバー型
社員IDテキスト型
日付日付/時刻型
開始時刻日付/時刻型
終了時刻日付/時刻型
業務No数値型
作業No数値型
備考テキスト型

業務名、作業名 フィールドは削除して、業務No、作業No フィールドを追加する。

T_業務マスタ T_作業マスタ T_社員マスタ は現状のままでOKです。

Q_勤怠 も 業務名、作業名 を 業務No、作業No に変更。

F_勤怠入力 の業務名、作業名のコンボボックスのプロパティを下記のように変更。

業務名のコンボボックス

プロパティ設定値
名前cb業務No
コントロールソース業務No
値集合ソースSELECT 業務No, 業務名称 FROM T_業務マスタ ORDER BY 業務No;
連列列1
列数2
列幅0cm
 
作業名のコンボボックス
プロパティ設定値
名前cb作業No
コントロールソース作業No
値集合ソースSELECT 作業No, 作業名 FROM T_作業マスタ WHERE 業務No=[cb業務No];
連列列1
列数2
列幅0cm
 
cb業務Noの更新後処理とフォームのレコード移動時のイベントプロシージャを下記のように記述。
Private Sub cb業務No_AfterUpdate()
    Me.cb作業No = Null
    Me.cb作業No.Requery
End Sub

Private Sub Form_Current()
    Me.cb作業No.Requery
End Sub

以上です。
修正したサンプルファイル

4
ojyamajyo 2019/05/04 (土) 10:28:50

ありがとうございました。
上記の処理後、Q_勤怠にT_業務マスタ T_作業マスタをリレーションしてQ_勤怠に業務名、作業名が表示されるようになりました。

質問なのですが、
Private Sub Form_Current()
    Me.cb作業No.Requery
End Sub

とは、具体的にどのようなことをしているのでしょうか?

あと、サンプルファイルをアップロードしていただいたようなのですが、URLが不明で開けませんとメッセージが出てしまい、開けない状況です。
ご教示いただけたらと思います。
よろしくお願いいたします。

5

サンプルファイルのURLを修正しました。これでダウンロードできると思います。

Form_Current() の役割ですか、

コンボボックス cb作業No のドロップダウンリストの内容を 業務No によって制限してますが、
レコード移動すると、業務No も変わりますので、それに合わせて、cb作業No のドロップダウンリストの内容を変更するために必要となります。

6
ojyamajyo 2019/05/04 (土) 12:28:25

Form_Current() の役割 理解しました。
そこまで考えて構築しないといけないのですね。勉強になりました。
次の工程でいまたつまづいています。
日付、社員ID、氏名は固定というか、その日に入力する限りはその都度入力することをしなくしたいです。
イメージとしては朝1番に日付からすべてを入力する。
登録ボタンを押すと、次のレコードに進むが日付、社員ID、氏名は引き継ぐといった感じです。
ご教授願えればと思います。

ファイル再度アップロードします。

7

そのような場合は、既定値プロパティを使うといいです。
既定値プロパティは新規レコードで、入力する前に既定の値を表示しておくものです。

まず、日付ですが、入力する日に、その日のデータを入力するなら、Date() の日付を既定値に設定しておけばいいですね。
前日のデータを入力するなら、Date()-1 の日付を既定値に設定します。

社員IDは、最初は空白にしておいて、入力したら、その値を既定値に設定するようにすれば、次の新規レコードから、前に入力した値が表示されます。

フォームのコードは下記のようになります。

Private Sub Form_Load()
    Me.日付.DefaultValue = "#" & Format(Date, "yyyy/mm/dd") & "#"
    DoCmd.GoToRecord , , acNewRec
End Sub

Private Sub 社員ID_AfterUpdate()   
    Me.社員ID.DefaultValue = Me.社員ID
End Sub

Private Sub 日付_AfterUpdate()
    Me.日付.DefaultValue = "#" & Format(Me.日付.Value, "yyyy/mm/dd") & "#"
End Sub

修正したサンプルファイル

サンプルファイルの上記以外の修正点

  • 社員IDをテキストボックスからコンボボックスに変更した。
     リストは、社員ID と 社員名の2列表示にした。

  • 社員名のコントロールソースをコンボボックスの2列目の値を参照するようにした。
    =[社員ID].[Column](1)
    クエリの社員名にしておくと、マスタの社員名を更新する恐れがあるし、新規レコードで社員IDの規定値に対応する社員名が表示されないため。

  • 社員名の「タブストップ」を「いいえ」にした。社員名は入力する必要がないので。

8
ojyamajyo 2019/05/04 (土) 19:14:56

早速のご教授ありがとうございます。
社員は100名ほどを想定しており、コンボボックスよりもIDを入力することを求められています。
そこで、ご教授のようにVBAを記述しましたが、新しいレコードに進むとIDは全レコードのものを表示できますが
氏名が前レコードのものを表示できません。
コントロールソースが異なるものとなるから表示されないということはわかるのですが、
この場合、氏名のコントロールソースにはどのように記述すればよろしいでしょか?
また、ほかのVBAの記述が必要でしょうか?
ファイル更新しますのでご教授のほどよろしくお願いいたします。

9
ojyamajyo 2019/05/04 (土) 19:54:22

立て続けにすみません。
コンボボックスでも社員IDを手入力で氏名に反映できるので前回の質問は取り下げさせていただきます。
フォームに登録ボタンを作って
新しいレコードに移動し、開始時刻にフォーカスさせる。
という仕組みにしました。

ここで
テーブル作成クエリの「Q_勤怠詳細_t」を同時に実行できないかと思案しています。
登録ボタンを押すと
①新しいレコードに移動する
②開始時刻にフォーカスさせる
③テーブル作成クエリの「Q_勤怠詳細_t」を実行する。
この3つが一つのボタンでできないかと。。。

別ボタンを作ると、押し忘れる人がいることも考えられるので
思案中です。

フォームを閉じるときとかにアクションクエリを実行するとかも考えたのですが
行き詰りました。

ご教授よろしくお願いします。

ファイル更新します。

10
ojyamajyo 2019/05/04 (土) 20:57:30

お世話になります。
テーブル作成クエリの「Q_勤怠詳細_t」をフォームを閉じるときに実行することができ目的を達成することができました。
しかしながら
Private Sub Form_Load()
    Me.日付.DefaultValue = "#" & Format(Date, "yyyy/mm/dd") & "#"
    DoCmd.GoToRecord , , acNewRec
End Sub

Private Sub 社員ID_AfterUpdate()
    Me.社員ID.DefaultValue = Me.社員ID
End Sub

Private Sub 日付_AfterUpdate()
    Me.日付.DefaultValue = "#" & Format(Me.日付.Value, "yyyy/mm/dd") & "#"
End Sub

を記述したところ フォームを開くとエラーが出てしまいます。

一度、VBAの記述などをチェックしていただけますでしょうか?

ほぼほぼ最終地点に到達させていただいております。
ご教授よろしくお願いします。

ファイル Demo5 に更新します。

11
ojyamajyo 2019/05/05 (日) 08:36:19

お返事のないまま進めて申し訳ありません。
VBAの記述を手入力でし直したところ、うまく動きました。
最後に、テキストボックスが空欄の場合、エラーメッセージを出す方法はありますでしょうか?

社員ID
氏名
開始時刻
終了時刻
稼働時間
業務名
作業名
件数
については、空欄の場合「~を入力してください」というものです。

ご教授よろしくお願います。

ファイル DEMO6に更新します。

12

ファイル DEMO6 の内容を見ました。

質問に答える前に、少し確認させてください。

テーブル作成クエリ「Q_勤怠詳細_t」は何のために実行するのでしょうか。
フォームを閉じるたびに実行されますが、
T_勤怠詳細 を削除してから、作成しなおすという動作になります。
何のためにこの動作が必要と考えましたか。

T_勤怠詳細 と同じ内容のものは、クエリで取得できますので、T_勤怠詳細テーブル自体必要のないものだと思いますが。

13
ojyamajyo 2019/05/05 (日) 12:04:50

クエリのデータをテーブルにして、CSVでエクスポートするために作りました。

14

クエリでもテーブルと同様にcsvエクスポートできますよ。保存するたびに、テーブル削除、作成を繰り返すのは無駄ですし、ファイル破損の危険性が増えるだけですのやめましょう。現状のテーブル作成クエリを選択クエリに変更して、エクスポートしたいときにそのクエリを指定すればいいだけですので。

15
ojyamajyo 2019/05/05 (日) 13:36:15

お世話になります。
ファイルの破損があるのですね。メンバー個人が入力を終了したときにテーブル作成をしてもらおうと考えたのですが、
管理者が翌朝に1回やれば済むというお話ですね。
理解しました。ここは手動で行いたいと思います。
エクスポート操作も保存しました。

最後の難関です。
サブフォームに入力した履歴を表示するようにしました。
開始時刻、終了時刻、件数はサブフォーム上で修正ができるようにしたいです。
(というか現状修正ができてしまいます。)
しかし、業務名と作業名をサブフォーム上で訳の分からない名前に修正されるとマスタテーブルにもその修正変更が及んでしまいます。
ユーザーが入力後に修正することは必至であると考えています。
サブフォーム上で修正できればいいのですが、前段の不具合が生じるのでいかんともしがたい状況です。

サブフォームの業務名、作業名をコンボボックスのようにプルダウンで選択制御することはできないでしょうか?

ご教授のほど、よろしくお願いします。

ファイル更新します。

完成前.zip です。

16
hatena 2019/05/05 (日) 17:30:41 修正 >> 15

添付ファイル
完成前.zip

17

ファイルの破損があるのですね。メンバー個人が入力を終了したときにテーブル作成をしてもらおうと考えたのですが、
管理者が翌朝に1回やれば済むというお話ですね。
理解しました。ここは手動で行いたいと思います。

テーブル自体必要ないです。クエリをエクスポートします。
エクスポート操作を保存したなら、朝、最初に起動したときに、
そのエクスポートをVBAで実行するようにするといいでしょう。
実行した日時を保存するテーブルを作成しておいて、実行日時を格納しておきます。
ファイルを起動したときは、今日の日付の実行履歴がなければ実行するというようにしておけば、
1日に1回だけ実行できます。

完成前サンプルファイルついて

いろいろ修正点がありますので、一つずつ指摘していきますね。

テーブル設計

  • T_勤怠 テーブルの 業務No、作業No フィールドの規定値が 0 になってますが、これは削除しましょう。
    0に設定してあると、入力せずに保存すると、0 になり未入力チェックができなくなります。

  • リレーションシップを設定しましょう。
    リレーションシップを設定する意義は下記のリンク先を参照してください。
    リレーションシップを設定した場合の利点 - hatena chips
    リレーションシップを設定して、「参照整合性」にチェックを入れておくと、マスターに存在しない値を入力なるとメッセージが出て入力できないようになります。データベースではデータの不整合が発生すると致命的ですので設定しておいた方がいいでしょう。

サブフォームの設計

  • 業務名、作業名 に関しては、クエリでマスターから引っ張ってくると、そこで編集するとマスターの方を更新してしまうので、メインフォームの方の設計のようにコンボボックスにしてコントロールソースは 業務No、作業No にして、列数、列幅の設定で業務名、作業名を表示させるようにします。
    テキストボックスを右クリックして[コントロールの種類の変更]-[コンボボックス]でコンボボックスに変更して、メインフォームのコンボボックスと同じ設定にしてください

  • レコードソースのクエリに抽出条件を設定していますが、抽出はリンク親フィールド/リンク子フィールドの設定で可能ですので、クエリの抽出条件は削除しておきましょう。
    リンク親フィールド/リンク子フィールドの設定は、社員ID;日付 というよう設定にします。複数のフィールドはセミコロンで区切って設定すればOKです。

  • 上記のように設定すれば、クエリに業務名、作業名は不要ですし、抽出条件も不要なので、レコードソースは、メインフォームと同じ Q_勤怠 にしてもOKですね。そうすれば、Q_勤怠内訳は不要なので削除しておきましょう。クエリは多くなると管理・メンテナンスが大変になりますのでなるべく少なくなるようにします。

  • メインフォームに「修正登録」というボタンがあり、そのクリック時で
    DoCmd.RunCommand acCmdSaveRecord
    を実行してますが、実は、これは無意味です。メインフォームのレコード保存になり、サブフォームとは無関係です。
    サブフォームで編集した場合、サブフォームでレコード移動するか、メインフォームへフォーカスを移動した時点で自動的に保存されます。
    「修正登録」をクリックするとメインフォームにフォーカス移動しますのでそこで自動保存されます。
    もし「修正登録」クリックするまでは登録されないとユーザーに誤解を与えますので、このボタンは削除しましょう。

修正したサンプルファイル
完成前_1.zip

18
ojyamajyo 2019/05/05 (日) 19:10:25

お世話になります。
いろいろとありがとうございます。
サブフォームもメインフォームと同様にコンボボックスにするということですが
業務名を選択しても作業名はそれに紐づくものが表示されるというわけではないのでしょうか?
サブフォームの業務名コンボボックスと作業名コンボボックスの集合値ソースには、どのように記載したらよいのでしょうか?
重ね重ねご教授お願いいたします。

19
hatena 2019/05/07 (火) 13:48:11 修正

サブフォームもメインフォームと同様にコンボボックスにするということですが
業務名を選択しても作業名はそれに紐づくものが表示されるというわけではないのでしょうか?
サブフォームの業務名コンボボックスと作業名コンボボックスの集合値ソースには、どのように記載したらよいのでしょうか?

データシートビューではコンボボックスの絞り込みは難しいですね。
帳票フォームなら方法はありますが、裏技的な難易度が高いものになります。

サブフォームは更新不可にして、サブフォームでダブルクリックすると、メインフォームにそのレコードが表示されて、そこで編集できるようにするというインタフェイスにしたらどうでしょうか。

20
ojyamajyo 2019/05/07 (火) 18:45:21

なるほど。
難しいのですね。
ご提案のように
サブフォームは更新不可にして、サブフォームでダブルクリックすると、メインフォームにそのレコードが表示されて、そこで編集できるようにするというインタフェイスにしようと思います。
サブフォームでダブルクリックしたときというのは、どのようにそのレコードを判別するのでしょうか?
該当レコードをダブルクリックしたときというのは、どこにそのイベントを記述したらよいのでしょうか。
ある特定のフィールドのダブルクリック時イベントに記述すればいいのでしょうか?
そうするとそのフィールドの箇所をダブルクリックしない限りフォームは立ち上がらないということになりませんか?
すべてのフィールドに対してダブルクリック時イベントに記述するということでしょうか?
ご教授よろしくお願いいたします。

21

現状の T_勤怠 テーブルには主キーがないので、下記のフィールドを追加して主キーにします。

フィールド名 勤怠ID
データ型 オートナンバー型

フォームのレコードソースの Q_勤怠 にも、勤怠ID フィールドを表示させます。

そのうえで、サブフォームの 社員ID テキストボックスのクリック時に下記のコードを設定します。

Private Sub 社員ID_DblClick(Cancel As Integer)
    With Me.Parent
        .SetFocus
        .Recordset.FindFirst "勤怠ID=" & Me.勤怠ID
    End With
End Sub

以上でどうでしょうか。

22
ojyamajyo 2019/05/07 (火) 21:51:21

ご返事ありがとうございます。
早速以下を実施しました。

ご提案のように フィールドを追加しました。
フィールド名は勤怠IDだとしっくりこないので、稼働IDとしました。

サブフォームの各フィールドは、編集ロックをかけて更新不可としました。

サブフォームの社員IDテキストボックスにご提案いただいたコードを設定しました。
しかしながら、ダブルクリックをしても何の反応もありません。
どこがおかしいのか検証しても発見に至りませんでした。

ご指摘、ご教授いただけますでしょうか。

ファイルを更新します。
完成前_3.zip です。

よろしくお願いいたします。

23
ojyamajyo 2019/05/08 (水) 06:08:05

申し訳ありません。
私の認識不足でした。
社員IDをダブルクリックすると、あらたに単票フォームが立ち上がると勘違いしていました。
メインフォームのデータが変わるのでそこで編集するということですね。
理解しました。

現状までのファイルを更新します。
完成前_5_zip です。

あと1点やりたいことがあります。
メインフォーム上でも、サブフォーム上でもよいのですが
詳細の稼働時間と件数の合計を表示させたいと思っています。

=SUM([稼働時間]) という数式をどこかに入れるというような認識なのですが
どこにどう入れたらいいか分かりかねています。

この点ご教授いただけたらと思います。

よろしくお願いします。

ファイルを更新します。
完成前_5.zip です。
よろしくお願いいたします

24

受け取った完成前_5.zipですが、パスワードかかっていて解凍できませんでした。

サブフォームのフォームヘッダーかフッターにテキストボックスを配置して、

名前 稼働時間計
コントロールソース =SUM([稼働時間])

と設定します。
メインフォームにテキストボックスを配置して、コントロールソースを下記のように設定します。

=[サブフォームコントロール名].[Form]![稼動時間計]

25
ojyamajyo 2019/05/08 (水) 13:20:21

申しわけありません。
zipファイルのパスワードは

persol

です。

今一度ご確認いただけますでしょうか。

26
ojyamajyo 2019/05/08 (水) 13:27:06

サブフォームコントロール名とは どのような記述になりますでしょうか。

27

メインフォームのデザインビューでサブフォームを埋め込んでいるコントロールを選択して、プロパティに表示される名前です。下記を参照してください。

サブフォームとサブフォームコントロールの違いとは? - hatena chips

28
ojyamajyo 2019/05/08 (水) 15:28:19

お世話になります。
ご提案のように設定をしてみましたが、エラーと表示されてしまいます。
ファイルを更新しますのでご確認いただけますでしょうか。

demo_6.zip

パスワードは

ah10020616

です。

よろしくお願いします。

29
ojyamajyo 2019/05/08 (水) 20:35:41

お世話になっております。
もう一度、解説を読みなおして設定したところ、うまく表示ができました。
稼働IDをクリックすると該当のメインフォームに移り、修正できる仕組みのところを
ハイパーリンクにして選択しやすいようにもしてみました。

ファイルを更新いたしますので、ご確認いただけますでしょうか。
パスワードは付けていません。

このあとは、インターフェイスまわりを整備してみようと思います。