こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

締切り済みの質問

アクセスで3つのフィルターを連携させたい

3つのコンボックスがあります
Combo1 → 都道府県
Combo2 → 市区
Combo3 → 町村

都道府県と市区までは正常にフィルター出来るのですが、町村を選ぶと都道府県や市区も
同じ町村の名前のデータを引っ張ってきてしまいます。
ボタンを付けることも考えましたが、VBAの能力があまりないので、失敗ばかりしています。
良い知恵を教えて頂けないでしょうか。


Private Sub Combo1_AfterUpdate()
Dim Strkubun As String
Strkubun = Me.Combo1
Me.Filter = "[都道府県]= '" & Strkubun & "'"
Me.FilterOn = True
Me.Requery
End Sub


Private Sub Combo2_AfterUpdate()
Dim Strkubun As String
Strkubun = Me.Combo2
Me.Filter = "[市区]= '" & Strkubun & "'"
Me.FilterOn = True
Me.Requery

End Sub

Private Sub Combo3_AfterUpdate()
Dim Strkubun As String
Strkubun = Me.Combo3
Me.Filter = "[町村]= '" & Strkubun & "'"
Me.FilterOn = True
Me.Refresh
End Sub

投稿日時 - 2015-04-13 13:44:58

QNo.8954871

すぐに回答ほしいです

このQ&Aは役に立ちましたか?

1人が「このQ&Aが役に立った」と投票しています

回答(8)

ANo.8

すみません。補足と回答に時間差ができたので
分けて回答します。

################################################

その1

回答の準備をしていたら先に補足がありましたが、
いろいろと確認したいことなどが入り乱れそうなので
先にNo6に届いた補足について、

各テーブルにあるこれらの郵便番号について、

>この住所録には共通のIDとして郵便番号があります。
>このIDをキーとしてクエリで都道府県、市区、町村を連結させています。
郵便番号
都道府県

郵便番号
市区

郵便番号
町村

たとえば、一番下の「町村」の郵便番号は
一つの「町村」に対して当然ながら一つですよね。
その上の「市区」は一つの「市区」に複数の郵便番号が存在する、
ということになりますか?さらにその上の
「都道府県は」複数の郵便番号が存在するという
ことになりますか?


###############################################
その2

以下は準備していたものです。

フォーム作成し、テーブル、クエリを質問の仕様に
して確認してみましたが、やはり共通の郵便番号
では、コンボボックスのいろいろな組合せにとっては
いろいろな不具合がでます。

やはり、No5で言いましたようにテーブルの構成を
やり直す必要があります。

具体的にいいますと、郵便番号そのものが都道府県、
市区、町村などの区分の合成になっているからです。
たとえば、
都道府県 01
市区   234
町村   5678
のような番号が、一つになって012345678
のような郵便番号になています。

No5で書きましたものをあわせますと、

都道府県 01      都道府県ID
市区   01234  市区ID
町村   012345678   町村ID

と、同じことになります。つまり郵便番号は
都道府県ID + 市区ID + 町村ID
と同等ということです。

質問の場合、テーブルのリレーションは下位の
レコードは自分の直接の親の情報をもてばいいのです。
つまり、「町村」の一つのレコードは直接の親で
ある「市区」の誰それ、「市区」の一つのレコードは
直接の親である「都道府県」の誰それ、などです。
共通の郵便番号となると、一番下位の「町村」は
複数の親が存在するということになります。


その上で、No5で言いましたようなVBAコードで
対応するということになります。


したがって、せっかく共通の郵便番号があるならば
それらを、

T都道府県
都道府県ID  01
都道府県


T市区
市区ID    01234
市区
都道府県ID  01


T町村
町村ID   012345678
町村
市区ID   01234


のように切り貼りし、クエリのリレーションを
No5のようにして、フォームのレコードソースに
すればいいのでは、と思います。

長くなりましたが、本来はコンボボックス同士の
連動もしたほうが検索の効率はグッとアップ
します。必要ならば回答します。




#################################################################
その3


郵便番号から住所を割り出そうとすれば、
必ず「都道府県」、「市区」、「町村」が
一つのレコードとして存在するか、あるいは
別テーブルであっても、No5のような構成の
テーブルが必要になります。

No6の補足にある、

この住所録には共通のIDとして郵便番号があります。
このIDをキーとしてクエリで都道府県、市区、町村を連結させています。
したがって、
郵便番号
都道府県

郵便番号
市区

郵便番号
町村


の中で、これらに記載されている「郵便番号」は、

012345678
北海道

012345678
札幌

012345678
すすきの1234番地

のようなデータ構成のレコードが存在する、ということですか?
もし、このようなデータだと、やはり無理があるかと思います。

投稿日時 - 2015-04-14 14:40:37

お礼

色々、教えて頂きありがとうございます。もう一度データ等を検証してまた分からなくなったらご質問させて頂きます。毎回のことですが、大変ありがとうございます。

投稿日時 - 2015-04-14 15:36:28

ANo.7

やはり、AND検索をするときは確実な
AND検索のためのSQL文を作成する必要が
あります。方法は、No6の(3)に書いた通り
なのですが、参照する内容を確認のために、

コンボボックスには、何を表示していますか。

郵便番号
郵便番号と名称
名称

のいずれですか。
それによって、
Me!Combo1.Column(1)
などの、Column(1)の値を変更するか、
あるいは必要ないかの判断をします。


ところで、フォームには重複したデータが表示
されることはありませんね?

投稿日時 - 2015-04-14 12:22:57

補足

郵便番号のみテキストボックスで表示されるようにしてあり、Combo1(都道府県の名称)、Combo2(市区の名称)、Combo3(町村の名称)の3種類のコンボックスです。
説明が不十分で申し訳ございません。
つまり3つのコンボックスの絞り込みにより郵便番号を抽出したいということです。
大変申し訳ございませんでした。

投稿日時 - 2015-04-14 13:15:47

ANo.6

No5で、図の選択するフィールドのところが
欠けていたので再表示しておきます。
これで、フォームのレコードソースにします。
一応、都道府県IDを表示するようにしています。
必要かどうかは判断してください。

投稿日時 - 2015-04-13 22:58:41

補足

この住所録には共通のIDとして郵便番号があります。
このIDをキーとしてクエリで都道府県、市区、町村を連結させています。
したがって、
郵便番号
都道府県

郵便番号
市区

郵便番号
町村

と3つのテーブル構成となっております。

投稿日時 - 2015-04-14 11:22:16

ANo.5

(1)
たぶん、テーブルの設計に問題があるのでは、と思います。
このような場合、各テーブル名をT都道府県、T市区、T町村
とします。

T都道府県
都道府県ID (主キー)
都道府県

T市区
市区ID (主キー)
市区
都道府県ID (数値型)


T町村
町村ID (主キー)
町村
市区ID (数値型)


このようにします。各テーブルのIDはオートナンバー
か、あるいは数値型を想定しています。

T市区の都道府県IDは該当する都道府県のID
を格納します。同様に、T町村の市区IDは
該当する市区のIDを格納します。
そうすると、これらを基にクエリを作成するとき、
以下のようにそれぞれのIDが結ばれるように
します。(画像を参照)
これをフォームのレコードソースにします。
なお、各テーブルには上位のテーブルのデータとして
各上位のテーブルの主キーとしてのIDを設定しています。
この場合は、テーブルの正規化として上位の、たとえば
T市区の上位テーブルとしてT都道府県の都道府県名を
設定する必要はありません。都道府県IDを設定します。


(2)
各コンボボックスのプロパティの設定は、

列数    2
列幅    0cm,5cm
リスト幅  5cm

とします。列幅の最初の0cmは、各テーブルのID(主キー)
がテーブルの最初に登録されるとしてこの表示はいらない
ので、0cmとしています。ただし検索に必要なので非表示
で、データとしてコンボボックに持つ、ということです。
5cmとかいう幅は実際に合わせて変更してください。

このようにテーブルを設定すると、フォームのレコードソースは
結合線で結ばれたテーブルで作成したクエリですから、どの
一つのフィールドにフィルタをかけても必ず関連したデータ
しか表示されません。

このようにすると、今のフィルタのかけ方でも機能するはずです。
一度、少ないデータで確認してみてください。



(3)
ボタンのクリックでデータを平う場合は、コンボボックスの
表示データの設定に考慮すべき点があるので、少しコードに
目新しいものがでてきます。


Private Sub cmd検索_Click()
  Dim strFil As String
  Dim i As Long
  Dim strKey(1 To 3) As String

  strFil = ""
  If IsNull(Me!Combo1) And IsNull(Me!Combo2) And IsNull(Me!Combo3) Then
    MsgBox ("コンボボックスの選択がされていません")
    Exit Sub
  End If

  If IsNull(Me!Combo1) Then
    strKey(1) = ""
  Else
    strKey(1) = "[都道府県] ='" & Me!Combo1.Column(1) & "'"
  End If

  If IsNull(Me!Combo2) Then
    strKey(2) = ""
  Else
    strKey(2) = "[市区] ='" & Me!Combo2.Column(1) & "'"
  End If

  If IsNull(Me!Combo3) Then
    strKey(3) = ""
  Else
    strKey(3) = "[町村] ='" & Me!Combo3.Column(1) & "'"
  End If

  For i = 1 To 3
    If strKey(i) = "" Then
    Else
    strFil = strFil & strKey(i) & " AND "
    End If
  Next i

  strFil = Left(strFil, (Len(strFil) - 5))
  Me.Filter = strFil
  Me.FilterOn = True
End Sub

ここで、Column(1) というのが出てきますが、
これはコンボボックスの二番目のフィールド
を指します。Column(0)は一番目のフィールドで
この場合は非表示の各IDを指します。


いちおう、このようなところですが確認してみてください。

投稿日時 - 2015-04-13 21:42:33

ANo.4

Option Compare Database
Option Explicit

Private Sub コンボ_都道府県_Change()
  Me.コンボ_市区 = ""
  Me.コンボ_町村 = ""
  DoFilter
End Sub

Private Sub コンボ_市区_Change()
  Me.コンボ_町村 = ""
  DoFilter
End Sub

Private Sub コンボ_町村_Change()
  DoFilter
End Sub

Public Sub DoFilter()
  Dim strKubun(2) As String
  Dim strFilter  As String
  
  ' -----------------------------
  ' 区分の取得
  ' -----------------------------
  strKubun(0) = IIf(Len(Me.コンボ_都道府県 & "") > 0, コンボ_都道府県, "")
  strKubun(1) = IIf(Len(Me.コンボ_市区 & "") > 0, Me.コンボ_市区, "")
  strKubun(2) = IIf(Len(Me.コンボ_町村 & "") > 0, Me.コンボ_町村, "")
  ' -----------------------------
  ' フィルターの編集
  ' -----------------------------
  strFilter = "[都道府県] LIKE 'XXXXX*' AND [市区] LIKE 'YYYYY*' AND [町村] LIKE 'ZZZZZ*'"
  strFilter = Replace(strFilter, "XXXXX", strKubun(0))
  strFilter = Replace(strFilter, "YYYYY", strKubun(1))
  strFilter = Replace(strFilter, "ZZZZZ", strKubun(2))
  ' -----------------------------
  ' フィルターの実行
  ' -----------------------------
  Me.Filter = strFilter
  Me.FilterOn = True
End Sub

投稿日時 - 2015-04-13 18:16:45

ANo.3

すみません。もう一つ。
(1)
それぞれのコンボボックスで単独でフィルタをかけたとき、
どのような結果を求めていますか。
(2)
また、二つの組合せではどのような結果を求めていますか。

投稿日時 - 2015-04-13 17:49:27

ANo.2

連投ですみません。No1の続きです。

もし、フォームにフィルタをかけるならば、

(1)
フォームのレコードソースはどのようになっていますか。
もし、テーブルならば、都道府県、市区、町村
の三つのフィールドがはいっているのでしょうか。
あるいは、別々のテーブルをクエリで一つに
しているのでしょうか。

(2)
>アクセスで3つのフィルターを連携させたい
>Combo1 → 都道府県
>Combo2 → 市区
>Combo3 → 町村

これらのコンボボックスは単独でフィルタを
かけることはありますか。

投稿日時 - 2015-04-13 16:31:37

ANo.1

(1)
>アクセスで3つのフィルターを連携させたい

これは、フォームにフィルタをかける、という
ことですか、あるいは3っつのコンボボックスを
連動させたい、ということですか?


(2)
各コンボボックスのコントロールソースは
同じテーブルですか、あるいは別々の
テーブルですか。

できたら、各コンボボックスのコントロール
ソースを補足してもらえれば、と思いますが。

投稿日時 - 2015-04-13 15:31:54

補足

(1)
フォームのレコードソースはどのようになっていますか。
もし、テーブルならば、都道府県、市区、町村
の三つのフィールドがはいっているのでしょうか。
あるいは、別々のテーブルをクエリで一つに
しているのでしょうか。
上記に関しては別々のテーブルでクエリーで1つにしております。

(2)
>アクセスで3つのフィルターを連携させたい
>Combo1 → 都道府県
>Combo2 → 市区
>Combo3 → 町村
上記は単独でフィルターをかけるつもりです。

補足として都道府県も市区、町村も1つづつのテーブルで同じデータが(例:北海道が数十)入っています。市区も同様に北海道なら北海道の市区分の全データが入っています。
1つづつフィルターをかけないと重たくなってしまう気がしているだけなので、検索ボタン等で一括検索でも構いません。
いつもいつもご迷惑をお掛けして申し訳ございませんが、
何卒、宜しくお願い致します。

投稿日時 - 2015-04-13 16:44:26

あなたにオススメの質問