
教えてください。
コンボボックスが4つあります。
コンボボックス1から4まで絞り込んで表示したいのですが
コンボボックス2が複数の重複アイテムが表示されます。
★印のところがうまくいきません。
データは添付ファイルのデータを使用しています。
宜しくお願い致します。
Private Sub UserForm_Initialize()
Dim ico As Long
ico = 1
With ThisWorkbook.Worksheets("商品comマスタ")
Do While .Cells(ico, 1) <> ""
ITE = .Cells(ico, 1).Value
flg = 0
For I = 0 To UserForm1.ComboBox1.ListCount - 1
If ITE = UserForm1.ComboBox1.List(I) Then flg = 1
Next I
If flg = 0 Then UserForm1.ComboBox1.AddItem ITE
ico = ico + 1
Loop
End With
End Sub
Private Sub ComboBox1_Change()
'ComboBox2セット
Dim ico As Long
ico = 1 '読み込みY座標
With ThisWorkbook.Worksheets("商品comマスタ")
key = UserForm1.ComboBox1.Text '1つ前の値をキーにする
UserForm1.ComboBox2.Clear 'コンボボックスクリア
Do While .Cells(ico, 1) <> "" 'リストの最後までループ
If .Cells(ico, 1) = key Then 'A列がキーの値だったら
ITE = .Cells(ico, 2).Value 'B列の値をITEに
flg = 0 '追加フラグ
If ITE = UserForm1.ComboBox2.List(I) Then flg = 1 'ITEの値がすでにコンボボックス2に入っている
For I = 0 To UserForm1.ComboBox2.ListCount - 1 'コンボボックス2をループ
If ITE <> Worksheets("商品comマスタ").Cells(ico + 2, 2).Value Then '★
ITE = Worksheets("商品comマスタ").Cells(ico + 2, 2).Value
End If
Next
If flg = 0 Then UserForm1.ComboBox2.AddItem ITE 'FLGが0だったらITEをコンボボックスに追加
End If
ico = ico + 1
Loop
End With
UserForm1.ComboBox2.SetFocus
End Sub
Private Sub ComboBox2_Change()
'ComboBox3セット
Dim ico As Long
ico = 1
With ThisWorkbook.Worksheets("商品comマスタ")
key = UserForm1.ComboBox1.Text
key1 = UserForm1.ComboBox2.Text
UserForm1.ComboBox3.Clear
Do While .Cells(ico, 1) <> ""
If .Cells(ico, 1) = key And .Cells(ico, 2) = key1 Then
ITE = .Cells(ico, 3).Value
flg = 0
For I = 0 To UserForm1.ComboBox3.ListCount - 1
If ITE = UserForm1.ComboBox3.List(I) Then flg = 1
Next
If flg = 0 Then UserForm1.ComboBox3.AddItem ITE
End If
ico = ico + 1
Loop
End With
UserForm1.ComboBox3.SetFocus
End Sub
Private Sub ComboBox3_Change()
'ComboBox4セット
Dim ico As Long
ico = 1
With ThisWorkbook.Worksheets("商品comマスタ")
key = UserForm1.ComboBox1.Text
key1 = UserForm1.ComboBox2.Text
key2 = UserForm1.ComboBox3.Text
UserForm1.ComboBox4.Clear
Do While .Cells(ico, 1) <> ""
If .Cells(ico, 1) = key And .Cells(ico, 2) = key1 And .Cells(ico, 3) = key2 Then
ITE = .Cells(ico, 4).Value
flg = 0
For I = 0 To UserForm1.ComboBox4.ListCount - 1
If ITE = UserForm1.ComboBox4.List(I) Then flg = 1
Next
If flg = 0 Then UserForm1.ComboBox4.AddItem ITE
End If
ico = ico + 1
Loop
End With
UserForm1.ComboBox4.SetFocus
End Sub
Private Sub ComboBox4_Change()
'ComboBox5セット
Dim ico As Long
ico = 1
With ThisWorkbook.Worksheets("商品comマスタ")
key = UserForm1.ComboBox1.Text
key1 = UserForm1.ComboBox2.Text
key2 = UserForm1.ComboBox3.Text
key3 = UserForm1.ComboBox4.Text
UserForm1.ComboBox5.Clear
Do While .Cells(ico, 1) <> ""
If .Cells(ico, 1) = key And .Cells(ico, 2) = key1 And .Cells(ico, 3) = key2 And .Cells(ico, 4) = key3 Then
ITE = .Cells(ico, 5).Value
flg = 0
For I = 0 To UserForm1.ComboBox5.ListCount - 1
If ITE = UserForm1.ComboBox5.List(I) Then flg = 1
Next
If flg = 0 Then UserForm1.ComboBox5.AddItem ITE
End If
ico = ico + 1
Loop
End With
UserForm1.ComboBox5.SetFocus
End Sub

No.6ベストアンサー
- 回答日時:
コンボボックス2のみ修正しました。
ITEを明示的に宣言していない為、Forのループの中でITEの値が正しく評価されていないようです。明示的に宣言しました。
Option Explicitを1行目に記述し、全ての変数を明示的に宣言することを推奨します。それを行っていれば、今回のようなエラーは発生しません。
ico=1の場合、見出し行も対象になりますが、よろしいのでしょうか。
(コンボボックス2では実害がないが、コンボボックス1で実害があります)
Private Sub ComboBox1_Change()
'ComboBox2セット
Dim ico As Long
Dim ITE As String
ico = 1 '読み込みY座標
With ThisWorkbook.worksheets("商品comマスタ")
key = UserForm1.ComboBox1.Text '1つ前の値をキーにする
UserForm1.ComboBox2.Clear 'コンボボックスクリア
Do While .Cells(ico, 1) <> "" 'リストの最後までループ
If .Cells(ico, 1) = key Then 'A列がキーの値だったら
ITE = .Cells(ico, 2).Value 'B列の値をITEに
flg = 0 '追加フラグ
For i = 0 To UserForm1.ComboBox2.ListCount - 1 'コンボボックス2をループ
If ITE = UserForm1.ComboBox2.List(i) Then flg = 1 'ITEの値がすでにコンボボックス2に入っている
Next
If flg = 0 Then UserForm1.ComboBox2.AddItem ITE 'FLGが0だったらITEをコンボボックスに追加
End If
ico = ico + 1
Loop
End With
UserForm1.ComboBox2.SetFocus
End Sub
tatsumaru77さん、有難う御座います。
うまく行きました。
希望どおりに絞り込みができ、表示アイテムも重複無です。
何度もやり直していたのでコードミスしてました。
有難う御座いました。
No.7
- 回答日時:
抽出を前に戻った際の対処法で悩みました。
Private myDic As Object
Private keyN(1 To 4) As String
Private Sub UserForm_Initialize()
Dim r As Range
Set myDic = CreateObject("Scripting.Dictionary")
With Worksheets("商品comマスタ")
UserForm1.ComboBox1.Clear
For Each r In Range("A1", Cells(Rows.Count, "A").End(xlUp)) 'A1~で良いのかな?
If Not myDic.Exists(r.Text) Then
myDic.Add r.Text, CreateObject("Scripting.Dictionary")
UserForm1.ComboBox1.AddItem r.Text
End If
If Not myDic(r.Text).Exists(r.Range("B1").Text) Then _
myDic(r.Text).Add r.Range("B1").Text, CreateObject("Scripting.Dictionary")
If Not myDic(r.Text)(r.Range("B1").Text).Exists(r.Range("C1").Text) Then _
myDic(r.Text)(r.Range("B1").Text).Add r.Range("C1").Text, CreateObject("Scripting.Dictionary")
If Not myDic(r.Text)(r.Range("B1").Text)(r.Range("C1").Text).Exists(r.Range("D1").Text) Then _
myDic(r.Text)(r.Range("B1").Text)(r.Range("C1").Text).Add r.Range("D1").Text, CreateObject("Scripting.Dictionary")
If Not myDic(r.Text)(r.Range("B1").Text)(r.Range("C1").Text)(r.Range("D1").Text).Exists(r.Range("E1").Text) Then _
myDic(r.Text)(r.Range("B1").Text)(r.Range("C1").Text)(r.Range("D1").Text).Add r.Range("E1").Text, ""
Next
End With
End Sub
Private Sub ComboBox1_Change()
Dim key
With UserForm1.ComboBox2
ch_CB (2)
For Each key In myDic(keyN(1)).Keys
.AddItem key
Next
End With
End Sub
Private Sub ComboBox2_Change()
Dim key, i As Integer
If UserForm1.ComboBox2.ListCount = 0 Then Exit Sub
With UserForm1.ComboBox3
ch_CB (3)
For Each key In myDic(keyN(1))(keyN(2)).Keys
.AddItem key
Next
End With
End Sub
Private Sub ComboBox3_Change()
Dim key, i As Integer
If UserForm1.ComboBox3.ListCount = 0 Then Exit Sub
With UserForm1.ComboBox4
ch_CB (4)
For Each key In myDic(keyN(1))(keyN(2))(keyN(3)).Keys
.AddItem key
Next
End With
End Sub
Private Sub ComboBox4_Change()
Dim key, i As Integer
If UserForm1.ComboBox4.ListCount = 0 Then Exit Sub
With UserForm1.ComboBox5
ch_CB (5)
For Each key In myDic(keyN(1))(keyN(2))(keyN(3))(keyN(4)).Keys
.AddItem key
Next
End With
End Sub
Private Sub ch_CB(n As Integer)
Dim i As Integer
For i = n To 5
With UserForm1.Controls("ComboBox" & i)
.Clear
.ListIndex = -1
End With
Next
For i = 1 To 4
keyN(i) = UserForm1.Controls("ComboBox" & i).Value
Next
End Sub
はてさて動いてくれるものなのか・・・な?
めぐさん、色々考えてアドバイス頂いて有難うござました。
どうもタイプミスのようです。
tatsumaru77さんのご指摘のように
If ITE <> Worksheets("商品comマスタ").Cells(ico + 2, 2).Value Then '★
ITE = Worksheets("商品comマスタ").Cells(ico + 2, 2).Value
不要のようです。
有難うございました。
No.5
- 回答日時:
絞り込みは何とか出来るでしょうけど、私の検証中の物では仮にCombobox3まで絞り込んだ後でCombobox1でエラーになるなど、飛び越えたコントロールを操作した場合の回避について悩み中です。
やっぱジャグ配列は厳しいかなぁ。
コレクションは経験ないので回避されているのかもですが。
No.4
- 回答日時:
おはようございます。
コードを読むと、重複しないリストを作る方法が上手くいかないようですね。
最初は、UserForm1.ComboBox2.Clearなので、ここは、
If ITE = UserForm1.ComboBox2.List(I) Then flg = 1 'ITEの値がすでにコンボボックス2に入っている
Listがないのでエラーになるのでは無いかと思います。
なので、if UserForm1.ComboBox2.ListCount=0 Then のようなコードが必要かと、
最初の値は、すんなり 'コンボボックス2をループせずに
UserForm1.ComboBox2.AddItem ITE
For I = 0 To UserForm1.ComboBox2.ListCount - 1 'コンボボックス2をループ
If ITE <> Worksheets("商品comマスタ").Cells(ico + 2, 2).Value Then '★
また、2つ下の行の値を取得しに行っているようですが、試していないので解らないのですが、それで間違えないのでしょうか、
1つずつ値を検証する必要があるように思います。
ソートなどをしているのかも知れませんが、予測できない行に重複データがあるとご質問に書かれている方法だとComboBoxと言う事もあり、大変かもしれませんね。
VBAの場合、重複しないデータを作成する方法は、連想配列やCollectionオブジェクト、AdvancedFilterなど、色々あります。
最近、連想配列をよく見かけますが、データ加工などしないでリストを作るだけなら私的にはコレクションをよく使います。
ごめんなさい。ちょっと分かり難いかも知れませんが、使っているものの改造で作ってしまいました。Collectionオブジェクトを使っています。
下記は、ご質問の内容と離れ、余計なお世話だと思います。
興味があれば参考にされてください。
UserForm_Initializeに書いているコードを参考にしてみてください。
'参照シート名、親ComboBoxの選択値(配列)、登録ComboBoxの番号、参照列番号
Sub ComboBox_list(SHname As String, myKey() As String, CtlN As Integer, colmN As Integer)
Dim i As Long, j As Integer, cnt As Integer, flag As Boolean
Dim Combo_list As New Collection
Controls("ComboBox" & CtlN).Clear
With Worksheets(SHname)
For i = 1 To .Cells(Rows.Count, colmN).End(xlUp).Row
For j = LBound(myKey) To UBound(myKey)
If .Cells(i, j + 1).Value = myKey(j) Then cnt = cnt + 1
Next j
If cnt = UBound(myKey) + 1 Then
If .Cells(i, colmN).Offset(, -1).Value = myKey(cnt - 1) Then
On Error Resume Next
Combo_list.Add .Cells(i, colmN).Value, CStr(.Cells(i, colmN).Value)
If Err.Number = 0 Then
Controls("ComboBox" & CtlN).AddItem .Cells(i, colmN).Value
End If
On Error GoTo 0
End If
End If
cnt = 0
Next
End With
End Sub
Private Sub UserForm_Initialize()
Dim i As Long
Dim Combo_list As New Collection
With Worksheets("商品comマスタ")
For i = 1 To .Cells(Rows.Count, 1).End(xlUp).Row
On Error Resume Next
Combo_list.Add .Cells(i, 1).Value, CStr(.Cells(i, 1).Value)
If Err.Number = 0 Then
Controls("ComboBox" & 1).AddItem .Cells(i, 1).Value
End If
On Error GoTo 0
Next
End With
End Sub
Private Sub ComboBox1_Change()
'ComboBox2セット Dim i As Long
Dim myArray(0) As String
myArray(0) = Controls("ComboBox" & 1)
Call ComboBox_list("商品comマスタ", myArray, 2, 2)
Me.ComboBox2.SetFocus
End Sub
Private Sub ComboBox2_Change()
'ComboBox3セット
Dim i As Long
Dim myArray(1) As String
For i = 0 To 1
myArray(i) = Controls("ComboBox" & i + 1)
Next i
Call ComboBox_list("商品comマスタ", myArray, 3, 3)
Me.ComboBox3.SetFocus
End Sub
Private Sub ComboBox3_Change()
Private Sub ComboBox4_Change()
の内容は上記を参考に組んでみてください。
ComboBox2_Change同様、必要項目でSub ComboBox_listを呼べば対応できると思います。
なさりたい事を誤解していたらごめんなさい。
No.3
- 回答日時:
No.2です。
あ!絞り込みたいんでしたっけ。
だとしたらあの回答はダメですね。
Dictionaryオブジェクトでジャグ配列組むかもですがデータ量によってはパンクするかな?
No.2
- 回答日時:
For I = 0 To UserForm1.ComboBox2.ListCount - 1 'コンボボックス2をループ
If ITE <> Worksheets("商品comマスタ").Cells(ico + 2, 2).Value Then '★
ITE = Worksheets("商品comマスタ").Cells(ico + 2, 2).Value
End If
Next
ここって条件が成立すると変数:ITEに代入するけど、その後何もなくループは続くので次にまた条件が成立するとITEの中身が変わってしまうだけでしかないのでは?
具体的に何をしたいのかがわかってない(寝ぼけてるから!)ので何ですけど、Comboboxの値を切り替えるたびに大ごとな作業を行なっている気もしなくもない。
読み込みたい列をそれぞれ必要とするなら、別シートにそれぞれの列?毎に重複しない値を準備しておいてから読み込ませるのも手ではないかなと。
http://blog.jmiri.net/?p=1949
メインのシートからデータをコピペしたサブシートで、1列単位で重複する値を消しちゃうってのはダメな物なの?
⇒該当しない組み合わせが出来ちゃう危険もあるのか・・・な?
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Visual Basic(VBA) VBA Userformで一部別シートに転記がしたいのですが 2 2023/05/24 13:08
- Visual Basic(VBA) ExcelVBAで、index、match関数を使用して、指定範囲に出力したい 3 2022/10/18 21:53
- Visual Basic(VBA) 前回ご教授いただいたコードに覚えたてのループ処理で品名りんごAから順に20回for nextでループ 7 2023/01/13 22:01
- Visual Basic(VBA) いつもお世話になっております、VBAで教えて頂きたいのですが 2 2022/05/05 22:20
- Visual Basic(VBA) Excelで下記のようにマクロを作ったところ、一回目は実行できたのですが、二回目以降「実行時エラー1 1 2022/03/25 08:08
- Excel(エクセル) なぜExit Subがあるのかわかりません 4 2023/02/19 12:34
- Visual Basic(VBA) ユーザーフォームに2つのコンボボックス銀行名「ConboBox1」支店名を「ConboBox2」とし 4 2022/08/03 17:34
- Excel(エクセル) VBAの指示の内容 昨日こちらでご教示頂いたのですが初心者な為、一つ一つの指示が何をやっているのかわ 2 2022/10/25 18:08
- Visual Basic(VBA) VBA 別ブックからの転記の高速化について VBA 別ブックからの転記の高速化についてご教授下さい。 19 2022/07/26 13:07
- Excel(エクセル) VBAで組み合わせ算出やCOUNTIFSの処理を高速化したいです。 4 2022/04/07 02:38
このQ&Aを見た人はこんなQ&Aも見ています
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
UWSCの終了の仕方
-
ごめんなさい 応用てきだとおう...
-
VBAでの一時停止と再開の方法
-
「人を傷つけることは悪いこと...
-
エクセルの当番表を作っていま...
-
配列にaaaからzzzまでの17576(2...
-
隣接交換法のアルゴリズムについて
-
VLC media Playerでのループ再生
-
(C#)フォームのキャンセルで計...
-
ループ結線の調査方法
-
多重ループの抜けだし方
-
Perlを使用してひらがな表...
-
VBAでln関数の計算
-
ループについて教えてください...
-
Visual BasicのUserFormが閉じ...
-
クッキーの処理
-
GIFアニメをループさせたくない
-
エクセル 数値の分解と展開
-
C言語でファクト関数を使わずに...
-
プログラミングについて int i,...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
UWSCの終了の仕方
-
画面を強制的に再描画させる方法
-
Escキーを押すと、中断する時と...
-
範囲指定したセルを1つずつ飛...
-
vb.netです。2次元配列の要素を...
-
VBAで3秒だけ時間を止めたい
-
エクセルの当番表を作っていま...
-
UWSCに制限時間を付けたいです
-
DOSコマンドのループ内のTIMEコ...
-
VBAでの一時停止と再開の方法
-
CSVファイルの特定の行だけを読...
-
DoEventsが必要な理由について
-
GIFアニメをループさせたくない
-
VBA for i=1 to lastrow
-
Do whileでExitせず、ループの...
-
VBA Boxが空白の場合のメッセー...
-
vb.netからエクセル関数書き込み
-
イベントの発生を待つ
-
乱数の桁数指定、または範囲指定。
-
エクセル関数で1〜12の数字がル...
おすすめ情報
めぐさん、絞り込みをしたいので結局サブシートでも同じことになるんです。
やっぱり無理なんでしょうか?
bonaronさん、アドバイス有難う御座います。
位置ですか?
先に重複無のデータを配列してからループですか?
やってみます。