• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:Access vba 教えてください。 初心者です)

Access VBA初心者のためのソフトリストとソフトの関連付け方法

このQ&Aのポイント
  • 初心者向けのAccess VBAで、テーブルT_ソフトリストとT_ソフトを使ってフォームF_入力のコンボボックスに関連するソフト名を表示する方法を教えてください。
  • フォームF_入力のコンボボックスに使用者を入力すると、T_ソフトから使用者を探し、ソフトリストIDを取得し、そのIDを元にT_ソフトリストからソフト名を表示する方法を教えてください。
  • Access VBAの初心者ですが、フォームF_入力のコンボボックスに入力した使用者に関連するソフト名を表示する方法が知りたいです。テーブルT_ソフトリストとT_ソフトを使って関連付けを行う方法を教えてください。

質問者が選んだベストアンサー

  • ベストアンサー
  • piroin654
  • ベストアンサー率75% (692/917)
回答No.10

遅くなりました。 (1) Combo_UserTypeの設定 集合タイプ   テーブル/クエリ 値集合ソース  T_使用者 列数      2 列幅      0cm,2cm 連結列     1 リスト幅    3cm (2) フォームのコード '######ここから######## Private Sub Combo_UserType_AfterUpdate() 'MsgBox Me!Combo_UserType.Column(0) Me!Combo_User.RowSource = "" Me!Combo_User.Requery Me!Combo_User.Value = "" '変数宣言 Dim db As Database Dim rs1 As Recordset Dim rs2 As Recordset Dim varSoft As String 'オブジェクト設定 Set db = CurrentDb Set rs1 = db.OpenRecordset("T_ソフトリスト", dbOpenDynaset) Set rs2 = db.OpenRecordset("T_ソフト", dbOpenDynaset) '検索開始 If rs2.RecordCount > 0 Then rs2.MoveFirst Do Until rs2.EOF 'データが見つかった時の処理 If CLng(Me!Combo_UserType.Column(0)) = CLng(rs2![使用者]) Then varSoft = DLookup("[ソフト名]", "T_ソフトリスト", "[ID] = " & rs2![ソフトリストID]) Combo_User_NotInList varSoft, acDataErrAdded End If rs2.MoveNext Loop End If rs1.Close: Set rs1 = Nothing rs2.Close: Set rs2 = Nothing db.Close: Set db = Nothing End Sub Private Sub Combo_User_NotInList(NewData As String, Response As Integer) If Me!Combo_User.RowSource = "" Then Combo_User.RowSource = NewData Else Combo_User.RowSource = Combo_User.RowSource & ";" & NewData End If Response = acDataErrAdded End Sub '######ここまで###### Combo_UserTypeの更新後では、いくつか変更しました。 (1) 「'データが見つかった時の処理」のコメント以下の2行。 もし、If文の中に入らないようであれば、 If CLng(Me.Combo_UserType.Column(0)) = CLng(rs2![使用者]) Then のように、両方、あるいはどちらか一方をCLngでキャストしてみて ください。たぶん、それで入ると思います。 (2) varSoft = DLookup("[ソフト名]", "T_ソフトリスト", "[ID] = " & rs2![ソフトリストID]) にしましたが、もとの varSoft = DLookup("[ソフト名]", "T_ソフトリスト", "[ID] = " & rs2![ソフトリストID] & "") でもデータは取れると思います。 (3) Me.Combo_UserType.Column(0) のようにして、コンボボックスでは名前を表示し、 非表示にしているIDをColumn(0)でコンボボックスの 列のインデックスで指定してIDを取得するように しました。 (4) 最初に抜けていたオブジェクトの後処理を最後に 追加しました。 たぶん、KtoTtoAさんが言われたキャストはCLng による型変換だろうと思います。。

KtoTtoA
質問者

お礼

回答有り難うございます。 当方の不手際で、列幅を修正するのを忘れていました。申し訳ございませんm(__)m これを修正したところ思ったとおりの動作致しました。 何度も丁寧な解説、ご指導ありがとうございました。

すると、全ての回答が全文表示されます。

その他の回答 (18)

  • piroin654
  • ベストアンサー率75% (692/917)
回答No.8

ちょっと微調整してみます。お待ちを。

KtoTtoA
質問者

補足

お手数おかけして申し訳ないですm(__)m よろしくお願いします。

すると、全ての回答が全文表示されます。
  • piroin654
  • ベストアンサー率75% (692/917)
回答No.7

【1】もし・・ >使用者は実際には別のテーブルで用意していて、 >数値型となっています。 ということは、T_ソフトの使用者は使用者IDの ような数値型で、T_使用者のようなテーブルが 別にあるといことでしょうか。 Combo_UserTypeで使うQ使用者は実際にはT _ソフトの使用者のフィールドをグループ化 して名寄せをし、名前を取り出し、使用者一覧 の代わりにしています。 こういう、経緯なので最終的に (1) Combo_UserTypeでは値集合ソースを T_使用者にし、Combo_UserTypeでは使用者名を 選択する機構にしますが、実際には使用者に 割り当てられた使用者IDをもとにT_ソフトの 使用者IDを検索し、同じ使用者IDを持つレコード から順次ソフト名を取り出し、Combo_Userに ソフト名を表示する、ということにします。 (2)したがって、T_使用者なる実際のテーブル名と 実際の使用者IDはどのような名称か、また 使用者は使用者でいいのか、そのあたりを聞かせて ください。 【2】 キャスト キャストと言う言葉が出てきたのでドッッッッキリ したのですが、もし・・その二 が想像したもので ないことを祈って、まずは 【1】もし・・ についてどうなのか、聞かせてください。

KtoTtoA
質問者

補足

回答有り難うございます。 「ということは、T_ソフトの使用者は使用者IDの ような数値型で、T_使用者のようなテーブルが 別にあるといことでしょうか。」 とおっしゃる通りT_使用者というテーブルがあり、下記のようになっています。 「T_使用者」←テーブル名 ID | 名前 | ────────── 1 | 田中  | 2 | 佐藤  | 3 | 鈴木  | 4 | 斉藤  | 名前:テキスト型 このようになっているので、実際には使用者を変数に入れて取得すると1や4といった数字が返ってくるようになっています。 (1)についてはコメントを頂いたとおりになっています。 これだと何か問題があるでしょうか?(・・;)

すると、全ての回答が全文表示されます。
  • layy
  • ベストアンサー率23% (292/1222)
回答No.6

ネットで探しているなら 『コンボボックス 連動 連携』 こんなキーワードで事例があると思います。 利用者を必ず先に選択でしょうか?。 利用者を決めたときのソフトは1つに絞られますか、複数ありますか?。 利用者を変えたら都度絞り込むため、利用者コンボの更新後処理でソフト側のデータを準備、となります。表示のもとになるソースを都度変えます。 ソフト側が1つならDLOOKUP関数も有効です。

KtoTtoA
質問者

補足

回答有り難うございます。 >利用者を必ず先に選択でしょうか?。 必ず先に選択します。 >利用者を決めたときのソフトは1つに絞られますか、複数ありますか?。 ソフトは複数になります。

すると、全ての回答が全文表示されます。
  • piroin654
  • ベストアンサー率75% (692/917)
回答No.5

No3の(3)フォームのCombo_Userの設定 のところで、クエリのSQL文を貼り付けたとき、 ずれていました。 SELECT T_ソフトリスト.ソフト名 FROM (T_ソフト INNER JOIN Q使用者 ON T_ソフト.使用者 = Q使用者.使用者) INNER JOIN T_ソフトリスト ON T_ソフト.ソフトリストID = T_ソフトリスト.ID WHERE (((Q使用者.使用者)=[Forms]![F_入力]![Combo_UserType])); 上記をはりつけてください。

すると、全ての回答が全文表示されます。
  • piroin654
  • ベストアンサー率75% (692/917)
回答No.4

ついでなので、No3の最後に述べて方法を載せて おきます。 【3】方法その三 (1)のバリエーション どちらかと言えば、このほうがメイン。 (1) Combo_UserTypeの設定 値集合タイプ   テーブル/クエリ 値集合ソース   Q使用者 列数       1 列幅       2 (2) 以下のコードをフォームのコード表に貼り付け、 保存してください。 '#####ここから##### Private Sub Combo_UserType_AfterUpdate() 'Combo_Userの初期化 Me!Combo_User.RowSource = "" Me!Combo_User.Requery Me!Combo_User.Value = "" '変数宣言 Dim db As Database Dim rs1 As Recordset Dim rs2 As Recordset Dim varSoft As String 'オブジェクト設定 Set db = CurrentDb Set rs1 = db.OpenRecordset("T_ソフトリスト", dbOpenDynaset) Set rs2 = db.OpenRecordset("T_ソフト", dbOpenDynaset) '検索開始 If rs2.RecordCount > 0 Then rs2.MoveFirst Do Until rs2.EOF 'データが見つかった時の処理 If Me!Combo_UserType.Text = rs2![使用者] Then varSoft = DLookup("[ソフト名]", "T_ソフトリスト", "[ID] = " & rs2![ソフトリストID] & "") Combo_User_NotInList varSoft, acDataErrAdded End If rs2.MoveNext Loop End If End Sub 'コンボボックスにデータを追加するプロシージャ 'AccessのバージョンによってはAddItemが使えるが 'バージョンがいろいろあるのでベタに作成 Private Sub Combo_User_NotInList(NewData As String, Response As Integer) If Me!Combo_User.RowSource = "" Then Combo_User.RowSource = NewData Else Combo_User.RowSource = Combo_User.RowSource & ";" & NewData End If Response = acDataErrAdded End Sub '#####ここまで###### 以上です。

KtoTtoA
質問者

補足

多数の回答有り難うございます。 No4のやり方でやりたいと思います。 このソースコード通り書いてみたのですが、デバッグをしたときに >If Me!Combo_UserType.Text = rs2![使用者] Then このIf文の中に入らないのですが、それはCombo_UserTypeの型と使用者の型とが一致していないからなのでしょうか? 現在、使用者は実際には別のテーブルで用意していて、数値型となっています。 Combo_UserTypeはテキスト型となっています。 キャストのようなものをすれば良いのでしょうか?

すると、全ての回答が全文表示されます。
  • piroin654
  • ベストアンサー率75% (692/917)
回答No.3

【2】方法その二 二つのコンボボックスの値集合ソースにデータを設定し、 二つのコンボボックスを連動させる方法です。 (1)とは違い、コンボボックスのプロパティで「値集合タイプ」 は「テーブル/クエリ」です。 (1) クエリの作成 以下のSQL文を新しいクエリのSQLビューに貼り付け、 「Q使用者」という名前で保存してください。 SELECT T_ソフト.使用者 FROM T_ソフト GROUP BY T_ソフト.使用者; (2)フォームのCombo_UserTypeの設定 値集合タイプ テーブル/クエリ 値集合ソース Q使用者 列数     1 列幅     2cm (3)フォームのCombo_Userの設定 値集合タイプ  テーブル/クエリ 値集合ソース  以下のSQL文を貼り付ける SELECT T_ソフトリスト.ソフト名 FROM (T_ソフト INNER JOIN Q使用者 ON T_ソフト.使用者 = Q使用者.使用者) INNER JOIN T_ソフ トリスト ON T_ソフト.ソフトリストID = T_ソフトリスト.ID WHERE (((Q使用者.使用者)=[Forms]![F_入力]![Combo_UserType])); 列数    1 列幅    2cm (3)フォームのコードの設定 以下のコードをフォームのコード表に貼り付け、保存してください。 Private Sub Combo_UserType_AfterUpdate() Me.Combo_User.Requery End Sub Private Sub Combo_UserType_Change() Me!Combo_User.Value = "" Me!Combo_User.Requery End Sub 以上、二つの方法です。分からないところがあれば 補足してください。 なお、(1)の方法で、質問に >フォームの使用者のコンボボックスに入力をしたときに とあるので、あくまでもコンボボックスに書き込んだ 場合としています。 (1)の場合、コンボボックスのCombo_UserTypeには、 (2)と同じようにコンボボックスにあらかじめ データをセットしておいて、そこから選び出す ことも簡単にできます。 そのように変更したいのであれば、補足してください。 少しの変更で済みます。

すると、全ての回答が全文表示されます。
  • piroin654
  • ベストアンサー率75% (692/917)
回答No.2

二つの方法を紹介します。少し入り組んでいますが、 じっくり検討してください。 量が多いので二つに分けます。 【1】方法その一 質問の内容そのままに、二つのコンボボックスに 何も設定しない、言わばテキストボックスのような 使い方。ただ、コントロールがコンボボックス というだけのものです。 DAOを使っているので、コード表の参照設定から、 Microsoft DAO xx Object Library にチェックが 入っているか確認してください。xxは3.6のような 数字です。なお、Microsoft ActiveX Objects Library xx にチェックが入っていたらチェックをはずしてください。 Combo_Userのプロパティで「値集合タイプ」を「値リスト」 にしてください。 Combo_UserTypeの更新後処理で設定します。 以下のコードをすべてフォームのコード表に 貼り付け、保存してください。 '#####ここから##### Private Sub Combo_UserType_AfterUpdate() '変数宣言 Dim db As Database Dim rs1 As Recordset Dim rs2 As Recordset Dim varSoft As String 'オブジェクト設定 Set db = CurrentDb Set rs1 = db.OpenRecordset("T_ソフトリスト", dbOpenDynaset) Set rs2 = db.OpenRecordset("T_ソフト", dbOpenDynaset) '検索開始 If rs2.RecordCount > 0 Then rs2.MoveFirst Do Until rs2.EOF 'データが見つかった時の処理 If Me!Combo_UserType.Text = rs2![使用者] Then varSoft = DLookup("[ソフト名]", "T_ソフトリスト", "[ID] = " & rs2![ソフトリストID] & "") Combo_User_NotInList varSoft, acDataErrAdded End If rs2.MoveNext Loop End If End Sub 'Combo_Userの初期化 Private Sub Combo_UserType_Change() Me!Combo_User.RowSource = "" Me!Combo_User.Requery Me!Combo_User.Value = "" End Sub 'コンボボックスにデータを追加するプロシージャ 'AccessのバージョンによってはAddItemが使えるが 'バージョンがいろいろあるのでベタに作成 Private Sub Combo_User_NotInList(NewData As String, Response As Integer) If Me!Combo_User.RowSource = "" Then Combo_User.RowSource = NewData Else Combo_User.RowSource = Combo_User.RowSource & ";" & NewData End If Response = acDataErrAdded End Sub '#####ここまで###### 方法その一はここまでです。 続く

すると、全ての回答が全文表示されます。
  • layy
  • ベストアンサー率23% (292/1222)
回答No.1

クエリやVBAのどこまで知っているか、わからないですが・・・。 ID |ソフトリストID | 使用者 |取得 ─────────────────── 1 |  4     | 佐藤  |D 2 |  2     | 鈴木  |B 3 |  5     | 斉藤  |E 4 |  1     | 佐藤  |A 5 |  3     | 田中  |C =================== 選択クエリ使えば、上記の状態ができるかと思います。 これで5行から「鈴木」を選んだときは、「B」も決定されている、 という感じで考えてみたらどうでしょう。

KtoTtoA
質問者

補足

回答ありがとうございます。 1週間ほど前からネットを元に色々調べながらやっている初心者です…。 ご指摘いただいた様な方法で使用者コンボボックスに入力した場合、それを元にソフト名コンボボックスに入るのでしょうか? 説明不足でしたが、あくまで使用者を入力した後に、ソフト名を絞り込んで表示するようにしたいのですが…

すると、全ての回答が全文表示されます。

関連するQ&A