[ 初めての方へ | 一覧(最新更新順) | 全文検索 | 過去ログ ]
『同一フォーム上に2組の連携するコンボボックスを作成』(SJC)
先程 [[20090923194642]] 『コンボボックスの連携&重複削除』(SJC) で教えて頂いた続き(?)なのですが 新しく質問させて頂きます。
先程ご教授頂き、現在ユーザーフォーム上のコンボボックス1〜4まで連携させた状態でいます。 コードは以下の通りです(教えて頂いたものをコピペした状態です・・・)。
'===================================================================================== 'ComboBox1(分類)に「製品リスト」シートA列の選択肢を表示 'ComboBox2(品種名)にComboBox1で選択した「分類」に対応する「品種名」の選択肢を表示(重複は削除) 'ComboBox3(品目名)にComboBox2で選択した「品種名」に対応する「品目名」の選択肢を表示(重複は削除) 'ComboBOx4(入れ目)にComboBox3で選択した「品目名」に対応する「入れ目」の選択肢を表示(重複は削除) 'Microsoft Scripting Runtime への参照設定が必要 ' [ツール] メニューの [参照設定] をクリックし、 ' [Microsoft Scripting Runtime] チェック ボックスをオンにする '=====================================================================================
Option Explicit
Private dic() As Scripting.Dictionary Private dicMax As Long Private Const BOXCOUNT = 4 '◆ComboBoxの数
Private Sub UserForm_Initialize() Dim v, sKey As String Dim i As Long, j As Long, k As Long, n As Long
With Worksheets("製品リスト") v = .Range("A2", .Cells(.Rows.Count, 1).End(xlUp)). _ Resize(, BOXCOUNT).Value End With
dicMax = UBound(v) * BOXCOUNT '程度 ReDim dic(1 To dicMax) Set dic(1) = New Scripting.Dictionary k = 1 For i = 1 To UBound(v) n = 1 For j = 1 To BOXCOUNT - 1 If Not IsEmpty(v(i, j)) Then sKey = v(i, j) If Not dic(n).Exists(sKey) Then k = k + 1 dic(n)(sKey) = k '★下位のComboBox用dic番号 Set dic(k) = New Scripting.Dictionary n = k Else n = dic(n)(sKey) End If Next dic(n).Item(v(i, j)) = Empty Next dicMax = k With ComboBox1 .List = Application.Transpose(Array(dic(1).Keys, dic(1).Items)) End With End Sub
Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer) Dim i As Long For i = dicMax To 1 Step -1 Set dic(i) = Nothing Next End Sub
Private Sub ComboBox1_Change() ComboBox_Update ComboBox1, ComboBox2 End Sub
Private Sub ComboBox2_Change() ComboBox_Update ComboBox2, ComboBox3 End Sub
Private Sub ComboBox3_Change() ComboBox_Update ComboBox3, ComboBox4 End Sub
Private Sub ComboBox_Update(ByVal Combo1 As MSForms.ComboBox, _ ByVal Combo2 As MSForms.ComboBox) Dim idx As Long Dim n As Long, i As Long Dim v idx = Combo1.ListIndex If idx < 0 Then Exit Sub n = Combo1.List(idx, 1) With Combo2 i = 0 .Clear For Each v In dic(n).Keys .AddItem v .List(i, 1) = dic(n).Item(v) i = i + 1 Next
End With
End Sub
続いて、同じユーザーフォーム上のコンボボックス5〜8とテキストボックス1を連携させたいのですが、うまくいきません。 やりたい内容としては、
ComboBox5(添付情報)に「様式リスト」シートA列の選択肢を表示(重複削除) ComboBox6(分類)にComboBox5で選択した「添付情報」に対応する「分類」の選択肢を「様式リスト」シートB列から表示(重複削除) ComboBox7(品目名)にComboBox6で選択した「分類」に対応する「品目名」の選択肢を「様式リスト」シートC列から表示(重複削除) ComboBox8(扱い先)にComboBox7で選択した「品目名」に対応する「扱い先」の選択肢を「様式リスト」シートD列から表示(重複削除) TextBox1(CP情報)にComboBox7で選択した「品目名」に対応する「CP情報」を「様式リスト」シートH列から表示
です。
教えて頂いたコードのボックス名を変更(例えばComboBox1→COmboBox5)すればできるはずだと安易に考えたのがいけないのですが・・・。
また、現在作成しているユーザーフォーム1が完成したら 全く同じ形のユーザーフォーム2・3も作成(コピー)し、 各コンボボックスやテキストボックスの値を別シートのセルに転記したいと考えているのですが やはり不具合が出てしまうものでしょうか・・・。
コードをきちんと理解していない故の 浅はかな質問だとは思うのですが 初心者な上に締切間近で軽くパニック状態だからと 寛大なお心でご教授頂ければ幸です。 どうぞ宜しくお願い致します。
こんばんは。 > 教えて頂いたコードのボックス名を変更(例えばComboBox1→COmboBox5)すればできるはずだと安易に考えたのがいけないのですが・・・。
前の「製品リスト」表と今回の「情報リスト」表とは 独立しているんですよね? でしたら、 Dictionaryオブジェクトの第2のシリーズを追加して(いい名前が思いつかないので、dib とします) コードは dicをセットするためにやっていることをそっくりコピーすればいい。 幸い、今度もComboBoxの数は4段階だし。。。 前とちがうのは ComboBox4 までで終わりだったが、こんどは (4番目の)ComboBox8の選択項目に対応 した(H列の)値をTextBoxに表示する、という点。
Option Explicit
Private dic() As Scripting.Dictionary '第1グループ用 Private dicMax As Long '第1グループ用 Private Const BOXCOUNT = 4 '第1グループ用◆ComboBoxの数
Private dib() As Scripting.Dictionary '第2グループ用 Private dibMax As Long '第2グループ用
Private Sub UserForm_Initialize() Dim v, sKey As String Dim i As Long, colm As Long, k As Long, n As Long
With Worksheets("製品リスト") '------- 第1グループのTree 作成 v = .Range("A2", .Cells(.Rows.Count, 1).End(xlUp)). _ Resize(, BOXCOUNT).Value End With
dicMax = UBound(v) * BOXCOUNT '程度 ReDim dic(1 To dicMax) Set dic(1) = New Scripting.Dictionary k = 1 For i = 1 To UBound(v) n = 1 For colm = 1 To BOXCOUNT - 1 If Not IsEmpty(v(i, colm)) Then sKey = v(i, colm) If Not dic(n).Exists(sKey) Then k = k + 1 dic(n)(sKey) = k '★下位のComboBox用dic番号 Set dic(k) = New Scripting.Dictionary n = k Else n = dic(n)(sKey) End If Next dic(n).Item(v(i, colm)) = Empty Next dicMax = k With ComboBox1 '先頭レベルComboBox1の リストをセットする .List = Application.Transpose(Array(dic(1).Keys, dic(1).Items)) .ListIndex = 0 End With
' 続いて、ComboBox5〜ComboBox8とTextBox1 '------- 第2グループのTree 作成 ' With Worksheets("様式リスト") v = .Range("A2", .Cells(.Rows.Count, 1).End(xlUp)). _ Resize(, 8).Value 'H列まで End With
dibMax = UBound(v) * BOXCOUNT '程度 ReDim dib(1 To dibMax) Set dib(1) = New Scripting.Dictionary k = 1 For i = 1 To UBound(v) n = 1 For colm = 1 To BOXCOUNT - 1 If Not IsEmpty(v(i, colm)) Then sKey = v(i, colm) If Not dib(n).Exists(sKey) Then k = k + 1 dib(n)(sKey) = k '★下位のComboBox用dic番号 Set dib(k) = New Scripting.Dictionary n = k Else n = dib(n)(sKey) End If Next dib(n).Item(v(i, colm)) = v(i, 8) '---- 最後のComboBox8 には H列の値を連動させる Next dibMax = k With ComboBox5 '先頭のComboBox5 に リスト dib(1) をセット .List = Application.Transpose(Array(dib(1).Keys, dib(1).Items)) .ListIndex = 0 End With
End Sub
Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer) Dim i As Long For i = dicMax To 1 Step -1 Set dic(i) = Nothing Next For i = dibMax To 1 Step -1 Set dib(i) = Nothing Next
End Sub
Private Sub ComboBox1_Change() ComboBox_Update ComboBox1, ComboBox2, dic() '第3引数に 使用dictionaryオブジェクト名を入れる End Sub
Private Sub ComboBox2_Change() ComboBox_Update ComboBox2, ComboBox3, dic() End Sub
Private Sub ComboBox3_Change() ComboBox_Update ComboBox3, ComboBox4, dic() End Sub
Private Sub ComboBox5_Change() ComboBox_Update ComboBox5, ComboBox6, dib() '第3引数に 使用dictionaryオブジェクト名を入れる End Sub
Private Sub ComboBox6_Change() ComboBox_Update ComboBox6, ComboBox7, dib() End Sub
Private Sub ComboBox7_Change() ComboBox_Update ComboBox7, ComboBox8, dib() End Sub
Private Sub ComboBox_Update(ByVal Combo1 As MSForms.ComboBox, _ ByVal Combo2 As MSForms.ComboBox, _ dictio() As Dictionary) '第3引数に 使用dictionaryオブジェクト名を入れる Dim idx As Long Dim n As Long, i As Long Dim v idx = Combo1.ListIndex If idx < 0 Then Exit Sub n = Combo1.List(idx, 1) With Combo2 i = 0 .Clear For Each v In dictio(n).Keys .AddItem v .List(i, 1) = dictio(n).Item(v) i = i + 1 Next .ListIndex = 0 End With End Sub
Private Sub ComboBox8_Change() Dim ss As String Dim idx As Long With ComboBox8 idx = .ListIndex If idx < 0 Then Exit Sub TextBox1.Text = .List(idx, 1) End With End Sub
(kanabun) 2009-09-25 00:25
(kanabun)様
何度も丁寧に 本当に有り難う御座います。 おかげさまでうまく動きました。 御礼が遅くなり申し訳ありませんでした。
仰るとおり >前の「製品リスト」表と今回の「情報リスト」表とは 独立して います。 説明不足で申し訳ありませんでした。
重ね重ね恐縮ですが、 >こんどは (4番目の)ComboBox8の選択項目に対応した(H列の)値をTextBoxに表示する に付け加えて ComboBox8の選択項目に対応した(E列の)値を別シート(「依頼書」シート、セルB12)に ComboBox8の選択項目に対応した(F列の)値を別シート(「依頼書」シート、セルE12)に表示するにはどのようにすればよいでしょうか。 (「情報リスト」シートの絞り込みはComboBox8が最終です。 ComboBox8で選択するとE,F,Hの各列には重複するデータはありません)
>dib(n).Item(v(i, colm)) = v(i, 8)
>With ComboBox8 idx = .ListIndex If idx < 0 Then Exit Sub TextBox1.Text = .List(idx, 1) End With
の辺りを変更・追加すれば出来ると思い、色々と試してみたのですがうまくいきません。
度々 本当に申し訳ありませんが何卒宜しくお願い致します。 (SJC)
> >dib(n).Item(v(i, colm)) = v(i, 8) > > >With ComboBox8 > idx = .ListIndex > If idx < 0 Then Exit Sub > TextBox1.Text = .List(idx, 1) > End With > > の辺りを変更・追加すれば出来ると思い、
おっしゃるとおりです(^^ Dictionary (オブジェクト名 dib() )のアイテムには それがどこのセルからもってきたデータか? という情報はありませんから、 >dib(n).Item(v(i, colm)) = v(i, 8) の代わりに、3つのセルの値を TABか何かで結合して アイテムに代入しておくわけです。
→ dib(n).Item(v(i, colm)) = v(i, 8) & vbTab & v(i,5) & vbTab & v(i,6)
で、ComboBox8_Click() イベントプロシージャで
Dim v as variant '変数追加 With ComboBox8 idx = .ListIndex If idx < 0 Then Exit Sub v = Split(.List(idx, 1), vbTab) 'TABで結合された文字列を 3つにわける TextBox1.Text = v(0) 別シートのセル1.Value = v(1) 別シートのセル2.Value = v(2) End With
のようなコードを書けば、可能かと思います。 もうちょっとですから、再度トライしてみてください。
(kanabun) 2009-09-26 0:37
(kanabun)様
本当に何度もありがとうございました。 おかげさまでうまく動きました。
結合してから分ける という処理が必要なのですね。 思いもよりませんでした。
これからじっくり勉強したいと思います。 ありがとうございました。 (SJC)
[ 一覧(最新更新順) ]
YukiWiki 1.6.7 Copyright (C) 2000,2001 by Hiroshi Yuki.
Modified by kazu.