- 締切済み
マイクロソフトアクセスのコンボボックス
アクセス初心者です。仕事上、アクセスと格闘中です。 注文の入力時の話です。顧客住所の入力ミスを防止するため、コンボボックスで顧客番号を選ぶと担当者や住所などの顧客情報が自動で入力できるそうですが、実際にはうまくできません。コンボボックスで顧客情報を表示して顧客番号を入力するところまではできました。が、住所等の表示方法が分かりません。ご存知の方、お知恵を貸してください。
- みんなの回答 (5)
- 専門家の回答
みんなの回答
- kurodai2
- ベストアンサー率38% (77/202)
>単純にキー入力を減らしたいだけなんです。注文テーブルに顧客住所を再入力するのを避けたかったんです ここが、根本的に違いますよ。 顧客情報に顧客の住所を持たせるのであれば 注文データには、顧客の住所欄は不要です。 注文データには、顧客IDがあればよいのです。 顧客IDから、顧客情報を参照すれば 顧客の住所はいつでも参照できます。 顧客の住所欄が、顧客情報と注文データに重複しないように 管理されるためにできたのが、正に リレーショナル型のデータベース です。 もし、その顧客の住所が変わった場合を想定してみてください。 顧客マスタだけで管理していれば、1か所変更すれば済みますが、 注文データにまで住所を持たせると それらすべてを修正しないと ならなくなります。 間違いも発生します・・データの整合性が取れなくなります。 先ず、テーブルの設計を整理しましょう。 テーブルは、最初にきっちり設計しておかないと、手戻りで大変なことになります。
- CHRONOS_0
- ベストアンサー率54% (457/838)
>単純にキー入力を減らしたいだけなんです。 入力する必要そのものが無いのですから、もっと楽になりますね >入門書を片手に格闘中です。。 いいものが作れるようになるまでには何冊もの本を読むことになると思いますが がんばってください
- CHRONOS_0
- ベストアンサー率54% (457/838)
根本的なところの理解が少しずれていますよ お望みのようなことをするには >顧客番号、担当者や住所などの顧客情報 をまとめたテーブルが必要です で、そのようなテーブルがあるとき、他のテーブルにこれらの情報をダブって持つことは テーブル設計の基本規則(正規化規則)に違反します テーブルは [顧客マスタ](顧客番号、顧客名、住所、担当者、・・・) [注文](注文年月日、顧客番号、商品ID、数量、・・・) のようにします テーブル注文には顧客番号だけを参照キーとして取り込みます 他の情報を格納してはいけません 両テーブルは顧客番号でリレーションシップを設定します この辺データベースの基本の非常に重要なところです これを理解せずにデータベースを作ってもろくなものは出来ません どの入門書にも初めの辺りで書かれていますからよく勉強してください
- kurodai2
- ベストアンサー率38% (77/202)
表示したいのですね。 例えば、コンボボックスが 顧客コンボと言う名前だとします。 そのコンボの、値集合ソースは SELECT 顧客M.顧客ID, 顧客M.顧客名, 顧客M.住所 FROM 顧客M; 列数:3 列幅:2cm;5cm;6cm で、顧客ID・顧客名・住所の3列がコンボ表示されるとします。 連結列:1で、コンボで選択すると、顧客IDがコントロールソースに格納される。 ここまでは、OKですね。 コンボを選択したときの、顧客ID・顧客名・住所は コンボボックスの何カラム目かで 値を参照できます。 顧客IDは、顧客コンボ.column(0) 顧客名は、顧客コンボ.column(1) 住所は、顧客コンボ.column(2) となります。 これらを、選択と同時に表示したい場合には、 先ず、コンボの横にでも、テキストボックスを配置します。 この場合、2つ配置したとします。 1つ目のテキストボックスのコントロールソースに =顧客コンボ.column(1) と設定します。選択時に顧客名が表示されます。 2つ目のテキストボックスのコントロールソースに =顧客コンボ.column(2) と設定します。選択時に住所が表示されます。
補足
最後の=顧客コンボ.column(1)に関してです。 他テーブルのデータを表示したいのですが、どのようにコントロールソースに記述すればよいのですか?
関数さえ準備しておれば、僅か9行ないし10行のコードで実現できることですが・・・。 問題は、最後の方で示す関数をウワーッと思われるか否かと思います。 <顧客名簿> ID__顧客名_______担当者_ID____住所 1___鈴木 一郎______________1_____東京都 2___中村 太郎______________1_____大阪府 3___山田 次郎______________2______兵庫県 <入力フォーム> ****************************************************** コンボ_顧客名簿 [鈴木 一郎__|______1|____東京都] テキスト_顧客名簿_ID___________________[_____1] テキスト_顧客名簿_担当者_ID________[_____1] テキスト_顧客名簿_顧客名____________[鈴木 一郎] テキスト_顧客名簿_住所_______________[_東京都] ****************************************************** さて、これだけですと、次のようなコードで実現できます。 Private Sub Form_Load() Me.コンボ_顧客名簿.RowSource = DBSelect("SELECT * FROM 顧客名簿") End Sub Private Sub コンボ_顧客名簿_Click() Dim intIndex As Integer Dim strRowSource As String intIndex = (Me.コンボ_顧客名簿.ListIndex + 1) * 4 - 3 If intIndex > 0 Then strRowSource = Me.コンボ_顧客名簿.RowSource Me.テキスト_顧客名簿_ID = CutStr(strRowSource, ";", intIndex) '<--- 無駄! Me.テキスト_顧客名簿_顧客名 = CutStr(strRowSource, ";", intIndex + 1) Me.テキスト_顧客名簿_担当者_ID = CutStr(strRowSource, ";", intIndex + 2) Me.テキスト_顧客名簿_住所 = CutStr(strRowSource, ";", intIndex + 3) End If End Sub ・フォームロード時に、Me.コンボ_顧客名簿.RowSource を DBSelect関数でセットする。 ・コンボ_顧客名簿_Click時に、各テキストボックスに Me.コンボ_顧客名簿.RowSource のデータを代入する。 Me.コンボ_顧客名簿.値集合タイプ=値リスト Me.コンボ_顧客名簿.列数=4 Me.コンボ_顧客名簿.列幅=0cm,2cm,2cm,2cm Me.コンボ_顧客名簿.連結列=1 テキスト_顧客名簿_ID___________________[_____1] もちろん、このテキストボックスは無駄と言えば無駄です。 ※値リストの場合、Me.コンボ_顧客名簿.RowSourceの実態は、data_1;data_2;・・・・;Data_n となっています。 ※DBselect関数もCutStr関数も、それらを意識した関数です。 先ずは、イミディエイトウインドウで、次の関数の働きを確認されて下さい。 ? DBSelect("SELECT * FROM 顧客名簿") 1;鈴木 一郎;1;東京都;2;中村 太郎;1;大阪府;3;山田 次郎;2;兵庫県 ? CutStr("1;鈴木 一郎;1;東京都;2;中村 太郎;1;大阪府;3;山田 次郎;2;兵庫県", ";", 1) 1 ? CutStr("1;鈴木 一郎;1;東京都;2;中村 太郎;1;大阪府;3;山田 次郎;2;兵庫県", ";", 2) 鈴木 一郎 ? CutStr("1;鈴木 一郎;1;東京都;2;中村 太郎;1;大阪府;3;山田 次郎;2;兵庫県", ";", 3) 1 ? CutStr("1;鈴木 一郎;1;東京都;2;中村 太郎;1;大阪府;3;山田 次郎;2;兵庫県", ";", 4) 東京都 <標準関数> Public Function DBSelect(ByVal strQuerySQL As String, _ Optional ByVal strSeparator As String = ";") As String On Error GoTo Err_DBSelect Dim I As Integer Dim J As Integer Dim R As Integer Dim C As Integer Dim M As Integer Dim N As Integer Dim rst As ADODB.Recordset Dim fld As ADODB.Field Dim Datas As String Set rst = New ADODB.Recordset ' ================= ' Begin With: rst ' ----------------- With rst .Open strQuerySQL, _ CurrentProject.Connection, _ adOpenStatic, _ adLockReadOnly If Not .BOF Then M = .RecordCount - 1 N = .Fields.Count - 1 .MoveFirst For R = 0 To M For C = 0 To N Datas = Datas & .Fields(C) & strSeparator Next C .MoveNext Next R End If End With ' --------------- ' End With: rst ' =============== Exit_DBSelect: DBSelect = Left(Datas, Len(Datas) + (Len(Datas) > 0)) Exit Function Err_DBSelect: MsgBox "SELECT 文の実行時にエラーが発生しました。(DBSelect)" & Chr$(13) & Chr$(13) & _ "・Err.Description=" & Err.Description & Chr$(13) & _ "・SQL Text=" & strQuerySQL, _ vbExclamation, " 関数エラーメッセージ" Resume Exit_DBSelect End Function Public Function CutStr(ByVal TEXT As String, _ ByVal Separator As String, _ ByVal N As Integer) As String Dim strDatas() As String strDatas = Split("" & Separator & TEXT, Separator, , 0) CutStr = strDatas(N * Abs((N <= UBound(strDatas)))) End Function
補足
何がなんだか???って感じです。苦笑) 親切に回答頂いたのに理解できなくて申し訳ありません。 想像以上に奥が深い世界みたいですね。
補足
やはり・・・初心者ですから。 単純にキー入力を減らしたいだけなんです。注文テーブルに顧客住所を再入力するのを避けたかったんです。入門書を片手に格闘中です。。