[[20120410105511]] 『ユーザーフォームで一致する内容をコンボボックス』(peridot) ページの最後に飛ぶ

[ 初めての方へ | 一覧(最新更新順) | 全文検索 | 過去ログ ]

 

『ユーザーフォームで一致する内容をコンボボックスに表示』(peridot)

 またまたすみません
 以前に似たような質問を見たような気がするのですが検索してもうまく見つけられなかったので…

[[20120409105405]]

 の関連です。

 データシート"箱サンプル"にデータを入力するためのユーザーフォームを作っています。

 その際に下記の"単価マスタ"シートからコンボボックスに表示する内容を参照しようとしています。

 ★シート"単価マスタ"
   A   B    C    D    E   F    G    H    I    J
 1 単価表
 2    記号  媒体名 基本単価 追加分 付帯業務 区分 基本コスト 単価   分類
 3    SK    KZ   19    1    1.2  1.5  22.7    17.0  作業簿_SK
 4    SK    MZ   19    1    1.2  1.5  22.7    17.0  作業簿_SK
 5    SK    HY   19    2    0   1.5  22.5    16.9  作業簿_SK
 6    SK    FR   19    0    0   1.5  20.5    15.4  作業簿_SK
 7    VA    KK   19    2    1.2  1.5  23.7    17.8  作業簿_KK
 8    VE    KK   19    0    0   1.5  20.5    15.4  作業簿_KK
 9    VS    10P   19    0    12.2  1.5  32.7    24.5  作業簿_その他

 コンボボックス1に「記号」、コンボボックス2に「媒体名」、コンボボックス3に「分類」を表示させるのですが、
 その際コンボボックス1&コンボボックス2の組み合わせが"単価マスタ"に登録されていたら
 その時点でコンボボックス3に「分類」の内容を表示させ、その組み合わせが無ければコンボボックス3は空白にしたいです。

 (例)
 ComboBox1 = "SK"
 ComboBox2 = "KZ"
 ↓単価マスタに同じ組合せがあるので
 ComboBox3 = "作業簿_SK"

 ComboBox1 = "SK"
 ComboBox2 = "ZZ"
 ↓単価マスタに組合せがないので
 ComboBox3 = ""(空白)

 現在のコード(コンボボックス1〜3にリストを表示させるコード)は下記の通りです。

  Option Explicit

 Private Sub UserForm_Initialize()

    Dim i As Long, j As Long, flag As Boolean
    Dim msh As Worksheet
    Dim z As Long

    Set msh = Sheets("単価マスタ")

    With msh.UsedRange
        z = .Range("B" & Rows.Count).End(xlUp).Row
    End With

    With ComboBox1
        For i = 3 To z
            If .ListCount = 0 Then
                .AddItem msh.Cells(i, 2)
            Else

                flag = False
                For j = 0 To .ListCount - 1
                    If msh.Cells(i, 2) = .List(j) Then
                        flag = True
                        Exit For
                    End If
                Next j
                If flag = False Then .AddItem msh.Cells(i, 2)
            End If
        Next i
    End With

    With ComboBox2
        For i = 3 To z
            If .ListCount = 0 Then
                .AddItem msh.Cells(i, 3)
            Else

                flag = False
                For j = 0 To .ListCount - 1
                    If msh.Cells(i, 3) = .List(j) Then
                        flag = True
                        Exit For
                    End If
                Next j
                If flag = False Then .AddItem msh.Cells(i, 3)
            End If
        Next i
    End With

    UserForm2.ComboBox3.List = Array("", "作業簿_SK", "作業簿_KK", "作業簿_その他")

 End Sub

 初歩的ですみません。
 よろしくお願いたします。

 質問が有ります
 現在のコードでは、「単価マスタ」の「記号」「媒体名」を無関係に重複無くComboBox1とComboBox2のListに
 登録していますが?
 此れを、ComboBox1とComboBox2で連動しなくても善いのですか?
 詰まり、ComboBox1で選択すると、ComboBox2では単価表に在るComboBox1で選ばれた記号だけに対する
 媒体名だけを表示する様にはしなくても善いのですか?
 其れに因りコードが代わります?

 (Bun)


 ありがとうございます。

 連動する方がよいのですが私がコードが分からなかったので…
 本来はComboBox1とComboBox2で連動するのが希望です。

 ★追加です
 ComboBox1とComboBox2で連動することになれば、単価マスタに登録があるものについては
 ComboBox3の選択も必要なくなりますので、

 ・ComboBox1とComboBox2の組合せがあればComboBox3に「分類」の内容を表示→ComboBox3を編集不可にする
 ・ComboBox1とComboBox2の組合せが無い場合、ComboBox3を空白にして編集可能にする

 というようにしたいのですができますでしょうか?

 (peridot)

 すみません!
 上からの指示でフォームの仕様が変更になりました!

 入力の手順ですが、

 1ComboBox3 で「分類」を選択
 2ComboBox1にその「分類」に該当する「記号」が表示される
 (例)「分類」作業簿_SK → 「記号」SK が表示される
 3ComboBox1に連動した「媒体名」がComboBox4〜11(すみません、増えました)に表示される

 なので、選択の手順(絞り込みの手順)が

 ComboBox3 → ComboBox1 → ComboBox4〜11

 で連動して表示されるようにしたいです。

 たびたび申し訳ございません・・・

 ユーザーフォームのレイアウト

  TextBox1(日付)

  ComboBox3(分類)

  ComboBox1(記号)

  ComboBox4(媒体名) TextBox2(数量)
  ComboBox5(媒体名) TextBox3(数量)
   :
  ComboBox11(媒体名) TextBox9(数量)

  CommandButton1(入力)

 (peridot)

 手順が変わったのはいいんだけど
 ComboBox3 で分類を選ぶ -> その分類に紐つく記号がComboBox1のリストに入る -> そこで何かを選ぶ
 さぁ、このあと 選んだ分類と記号を持った媒体のリストを 4〜11 の 7つのComboBoxにいれる?
 同じものを入れるということ?それならそれでいいんだけど?

 (ぶらっと)

 解りました考えて見ましょう

 (Bun)


 すべっているかもしれないけど。

 全てのComboBoxのRowSourceは指定しないで。
 また、少なくともComboBox3とComboBox1のMatchRequiredはTrueを設定しておいて。
 ユーザーフォーム表示時点に、負荷を集中させ、コンボボックス選択時の負荷をおさえている。
 これが、あまりにもということなら、コンボボックス選択時に負荷を分散させることも
 (面倒だけど)可能。

 ★ アップしたコードを1行訂 15:55

 Option Explicit

 Dim dic As Object

 Private Sub UserForm_Initialize()
    Dim c As Range
    Dim myCode As String
    Dim myCat As String
    Dim myMedia As String

    Set dic = CreateObject("Scripting.Dictionary")

    With Sheets("単価マスタ")
        For Each c In .Range("B3", .Range("B" & .Rows.Count).End(xlUp))
            With c.EntireRow
                myCode = .Range("B1").Value
                myCat = .Range("J1").Value
                myMedia = .Range("C1").Value
            End With
            If Not dic.exists(myCat) Then Set dic(myCat) = CreateObject("Scripting.Dictionary")
            If Not dic.exists(myCode) Then _
                    Set dic(myCat)(myCode) = CreateObject("Scripting.Dictionary")
            dic(myCat)(myCode)(myMedia) = True
        Next
    End With
    Me.Tag = "Skip"
    ComboBox3.Clear
    ComboBox3.List = dic.keys
    Me.Tag = Empty

 End Sub

 Private Sub ComboBox3_Change()
    Dim v As Variant
    Dim i As Long

    If Me.Tag = "Skip" Or ComboBox3.ListIndex < 0 Then Exit Sub

    Me.Tag = "Skip"
    ComboBox1.Clear
    ComboBox1.List = dic(ComboBox3.Value).keys
    For i = 4 To 11
        Me.Controls("ComboBox" & i).Clear
    Next
    Me.Tag = Empty
 End Sub

 Private Sub ComboBox1_Change()
    Dim i As Long
    If Me.Tag = "Skip" Or ComboBox1.ListIndex < 0 Then Exit Sub

    For i = 4 To 11
        With Me.Controls("ComboBox" & i)
            .Clear
            .List = dic(ComboBox3.Value)(ComboBox1.Value).keys
        End With
    Next
 End Sub

 Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
    Set dic = Nothing
 End Sub

 (ぶらっと)

 連動させるとちょっと複雑に成るけど我慢して?

 1、先ず抽出をする作業用のシートを作成します(AdvancedFilterを使って此処に抽出して行きます)
  上手く動く様に成ったら、このシートは非表示にして構いません
  新規のシートに「抽出」と言うシート名を付けて下さい

 2、「抽出」シートに以下の様な列見出しを設定して下さい
  抽出範囲としてA1:分類、B1:記号、C1:媒体名
  条件範囲としてF1:分類、G1:記号
  とします

	A	B	C	D	E	F	G
 1	分類	記号	媒体名			分類	記号

 この列見出しは必ず「単価マスタ」からCopyして下さい

 3、UserFormには、必ずComboBox1、ComboBox3、ComboBox4〜11が在る物とします

 4、UserFormのコードモジュールに以下のコードを記述します

 Option Explicit

 Private Const clngExtr As Long = 3 '抽出列数

 Private rngList As Range    '単価マスタのデータ範囲
 Private rngWork As Range    '作業用シートの抽出範囲
 Private rngCrit As Range    '作業用シートの条件範囲先頭セル位置
 Private lngRow As Long      '抽出行数(最終行位置)

 Private Sub UserForm_Initialize()

    Dim vntData As Variant
    Dim lngRows As Long

    '単価マスタ先頭セル位置を指定
    Set rngList = Worksheets("単価マスタ").Range("B2")

    '作業用シートの抽出範囲を指定
    Set rngWork = Worksheets("抽出").Range("A1")

    '作業用シートの条件範囲先頭セル位置を指定
    Set rngCrit = rngWork.Parent.Range("F1")

    'Listの行数、列数取得
    With rngList
        'B列で行数の取得
        lngRows = .Offset(Rows.Count - .Row).End(xlUp).Row - .Row
        'J列「分類」データの取得
        vntData = .Offset(1, 8).Resize(lngRows + 1).Value
        'J列「分類」の重複取り、ComboBox1のListを設定
        ComboBox3.List = Unique(vntData)
    End With

    'データ範囲の再設定
    Set rngList = rngList.Resize(lngRows + 1, 9)

 End Sub

 Private Sub UserForm_Terminate()

    Set rngList = Nothing
    Set rngWork = Nothing
    Set rngCrit = Nothing

 End Sub

 Private Sub ComboBox3_Change()

    Dim vntData As Variant

    If ComboBox3.ListIndex = -1 Then
        Exit Sub
    End If

    '「記号」のデータを取得
    vntData = GetComboList(ComboBox3.Text, 1)

    With ComboBox1
        '抽出行数が0で無いなら
        If lngRow > 0 Then
            'ComboBox1にListを設定
            .List = vntData
        Else
            'ComboBox1をクリア
            .Clear
        End If
    End With

 End Sub

 Private Sub ComboBox3_Enter()

    Dim i As Long

    ComboBox1.ListIndex = -1

    For i = 4 To 11
        With Controls("ComboBox" & i)
            .ListIndex = -1
            .Clear
        End With
    Next i

 End Sub

 Private Sub ComboBox1_Change()

    Dim i As Long
    Dim vntData As Variant

    If ComboBox1.ListIndex = -1 Then
        Exit Sub
    End If

    '「媒体名」のデータを取得
    vntData = GetComboList(ComboBox1.Text, 2)

    For i = 4 To 11
        With Controls("ComboBox" & i)
            '抽出行数が0で無いなら
            If lngRow > 0 Then
                'ComboBoxにListを設定
                .List = vntData
            Else
                'ComboBoxをクリア
                .Clear
            End If
        End With
    Next i

 End Sub

 Private Sub ComboBox1_Enter()

    Dim i As Long

    For i = 4 To 11
        With Controls("ComboBox" & i)
            .ListIndex = -1
            .Clear
        End With
    Next i

 End Sub

 Private Function GetComboList(vntCrit As Variant, lngNum As Long) As Variant

    Dim vntData As Variant

    '条件範囲にComboBoxの値を代入(式の形で)
    rngCrit.Offset(1, lngNum - 1).Value = "=""" & vntCrit & """"

    'AdvancedFilterを実行
    DoFilter rngList, rngCrit.Resize(2, lngNum), rngWork.Resize(, clngExtr)

    '抽出範囲から
    With rngWork
        '抽出行数を取得
        lngRow = .Offset(Rows.Count - .Row).End(xlUp).Row - .Row
        '列見出し以上の行が在るなら
        If lngRow > 0 Then
            '指定列からデータを配列に取得
            vntData = .Offset(1, lngNum).Resize(lngRow, 2).Value
            ReDim Preserve vntData(1 To lngRow, 1 To 1)
            GetComboList = Unique(vntData)
        End If
    End With

 End Function

 Private Sub DoFilter(rngScope As Range, _
                    rngCriteria As Range, _
                    rngCopyTo As Range, _
                    Optional blnUnique As Boolean)

  '  AdvancedFilterを実行

    rngScope.AdvancedFilter _
            Action:=xlFilterCopy, _
            CriteriaRange:=rngCriteria, _
            CopyToRange:=rngCopyTo, _
            Unique:=blnUnique

 End Sub

 Private Function Unique(vntData As Variant) As Variant

 '  値の重複取り

    Dim i As Long
    Dim j As Long
    Dim lngEnd As Long
    Dim vntList As Variant

    ReDim vntList(1 To UBound(vntData, 1))

    '値の重複取り
    For i = 1 To UBound(vntData, 1)
        For j = 1 To lngEnd
            If vntData(i, 1) = vntList(j) Then
                Exit For
            End If
        Next j
        If j > lngEnd Then
            If Not IsEmpty(vntData(i, 1)) Then
                lngEnd = j
                vntList(lngEnd) = vntData(i, 1)
            End If
        End If
    Next i

    ReDim Preserve vntList(1 To lngEnd)

    '戻り値として重複無しの値を返す
    Unique = vntList

 End Function

 (Bun)


 (ぶらっと)様

 >選んだ分類と記号を持った媒体のリストを 4〜11 の 7つのComboBoxにいれる

 はい、実際にはComboBox4〜11には17個ほどのリストが入ることになるのですが、その日に必要なものを
 プルダウンから選び、件数をテキストボックスに入力して「箱サンプル」シートに転記していきます。

 ただ、今まだ悩んでいる部分がありまして…

 ★シート"箱サンプル"(データシート)

   A   B   C   D  E   F   G  H  I  J   K   L
 1 SK作業                    合計
 2 記号 媒体名 件数    記号 媒体名 件数     記号 媒体名 件数
 3 SK1  KZ         SK2  KZ   2       SK  KZ   2
 4 SK1  MZ         SK2  MZ
 5 SK1  HY   82     SK2  HY   4       SK  HY   86
 6 SK1  FR   11     SK2  FR          SK  FR   11
 7 VA1  KK   1516    VA2  KK   224      VA  KK   1740
 8 VE1  KK   9     VE2  KK   4       VE  KK   13
 9 VS1  10P   6192    VS2  10P   672      VS  10P   6864
 10 VS3  10P   1008                  VS  10P   1008  

 このデータシートに入力する際、今は最初からA〜B列、E〜F列は入力されていて、C列・G列に数値を入力するとその合計がJ〜L列に入ります。
 この時、上記の3行目のように枝番の一つが件数0の場合があります。
 しかし件数が0の場合も、その行を上に詰めて

   A   B   C   D  E   F   G  H  I  J   K   L
 1 SK作業                    合計
 2 記号 媒体名 件数    記号 媒体名 件数     記号 媒体名 件数
 3 SK1  HY   82     SK2  KZ   2       SK  KZ   2

 のようにA〜C列とE〜F列で「記号&媒体名」の組合せがずれてはいけないようになっています。
 なので、

   A   B   C   D  E   F   G  H  I  J   K   L
 1 SK作業                    合計
 2 記号 媒体名 件数    記号 媒体名 件数     記号 媒体名 件数
 3               SK2  KZ   2       SK  KZ   2
 4 SK1  HY   82     SK2  HY   4       SK  HY   86
 5 SK1  FR   11                    SK  FR   11
 6 VA1  KK   1516    VA2  KK   224      VA  KK   1740
 7 VE1  KK   9     VE2  KK   4       VE  KK   13
 8 VS1  10P   6192    VS2  10P   672      VS  10P   6864
 9 VS3  10P   1008                  VS  10P   1008  

 このように「片方に数値がある&片方が件数0」のところはその部分を空欄にしておく必要があります。

 また、普段は枝番は「1」か「2」しか無いのですが、ごく稀にイレギュラーなパターンで、「枝番」が3以上の場合があります。
 その時は上の8〜9列のように次の行に3以上の枝番を追加します。

 この条件分岐が思ったより難しくて転記するコードを書くのに悩んでいます・・・

 本当はここまでくると目視でベタ打ちの方が個人的には分かりやすいのですが上からの指示でユーザーフォームを作るように言われて困っています・・・

 ★書いていたら衝突しました

 (ぶらっと)様,(Bun)様

 ありがとうございます。
 今から試してみます。

 (peridot)

 追伸

 CommandButton1 が登場しているけど、これは何か対応する必要あり?
 要件が不明確だったのでコードには反映させていない。必要なら追加するけど。
 TextBoxが登場しているけど、これについても、何もしていないよ。

 (ぶらっと)

 (ぶらっと)様

 CommandButton1 は、ユーザーフォームに入力した内容を「箱サンプル」シートに転記させるためのボタンです。
 テキストボックスにはその日の作業件数を入力し、「箱サンプル」シートのC列またはG列に入力します。
 このボタンを押す際に、「箱サンプル」シートのどの部分に転記させるかを条件分岐で指定します。
 例えば

   A   B   C   D  E   F   G  H  I  J   K   L
 1 作業簿_SK                    合計
 2 記号 媒体名 件数    記号 媒体名 件数     記号 媒体名 件数
 3               SK2  KZ   2       SK  KZ   2
 4 SK1  HY   82     SK2  HY   4       SK  HY   86
 5 SK1  FR   11                    SK  FR   11
 6 作業簿_KK
 7 記号 媒体名 件数    記号 媒体名 件数     記号 媒体名 件数
 8 VA1  KK   1516    VA2  KK   224      VA  KK   1740
 9 VE1  KK   9     VE2  KK   4       VE  KK   13
 10 作業簿_その他
 11 記号 媒体名 件数    記号 媒体名 件数     記号 媒体名 件数
 12 VS1  10P   6192    VS2  10P   672      VS  10P   6864
 13 VS3  10P   1008                  VS  

 このように段落が分かれているので(すみません、前回のトピの途中で仕様変更があったのを忘れて記載していました)
 ComboBox3「分類」で「作業簿_XX」のいずれかを選び、その段落の中にユーザーフォームの内容を入力していくという感じです。

 ただ、先にも書きましたように条件分岐が複雑なので今コードを考えているところです…

 あと、ぶらっと様のコードを試しましたところ、ComboBox4以降に、「単価マスタ」の該当項目の最終行1項目しか表示されません…

 (peridot)

 >あと、ぶらっと様のコードを試しましたところ、ComboBox4以降に、「単価マスタ」の該当項目の最終行1項目しか表示されません…

 ひやぁぁ! 今からバグつぶしするね。

 (ぶらっと)

 おはずかしい!

 UserForm_Initializeプロシジャのコードの中の
 If Not dic.exists(myCode) Then _
 これを
 If Not dic(myCat).exists(myCode) Then _
 これにかえて。

 (ぶらっと)

 すみません、もう一つお聞きしたいのですが…

 ComboBox4〜11を全て、コントロールのプロパティでStyleを「2」にしてリスト以外からは選べないようにしたいのですが、
 その際、一度選んだリストを空白にできるように、プルダウンリストの先頭に空白項目を入れたいのですが、
 どのようにしたらよろしいでしょうか。

 「媒体名」(ComboBox4〜11)と「件数」を入力する部分はそれぞれ8個あるのですが、もし4つしか入力データが無い時に
 5つ目のComboBoxを選んでしまった場合、その部分が消せないので…

 たびたび申し訳ございません。よろしくお願いいたします。

 (peridot)

 >ComboBox4〜11を全て、コントロールのプロパティでStyleを「2」にしてリスト以外からは選べないようにしたいのですが、
 >その際、一度選んだリストを空白にできるように、プルダウンリストの先頭に空白項目を入れたいのですが、
 >どのようにしたらよろしいでしょうか。
 >
 >「媒体名」(ComboBox4〜11)と「件数」を入力する部分はそれぞれ8個あるのですが、もし4つしか入力データが無い時に
 >5つ目のComboBoxを選んでしまった場合、その部分が消せないので…

 此れに就いて、個人的には進めませんが(使い勝手が悪く成る様なきがします)?
 現在の状態でもBackSpaceキーやDeleteキーで消す事が出来ますし
 Listに無い物しか入力出来ない様にするなら、CommandButtonを押して転記する時どの道、
 ComboBox4〜11の入力確認を行うでしょうから、其の時ListIndexが-1かどうか確認すればいい事と思います
 何故なら、ComboBoxのTextBox部に入力が在っても其の値がComboBoxのListに無ければListIndexは-1なのですから
 逆に空白行を入れると此れが出来なくなります

 因って、「コントロールのプロパティでStyleを「2」にして」もやめた方がいいし、
 此れをやらなければ、空白行をListに入れる必要も無いと思います

 尚、私のコードで一部バグが有りましたので修正して下さい(★印の行を削除)
 此れが在ると、CoboBox4からComboBox1に戻った時、ComboBox4〜11のListが消されてしまって
 ComboBox3まで戻って選択をし直さなければならなく成ります

 Private Sub ComboBox1_Enter()

    Dim i As Long

    For i = 4 To 11
        With Controls("ComboBox" & i)
            .ListIndex = -1
'            .Clear '★削除
        End With
    Next i

 End Sub

 (Bun)


 >ComboBox4〜11を全て、コントロールのプロパティでStyleを「2」にしてリスト以外からは選べないようにしたいのですが

 Style でおこなうより MatchRequired をTrue にしておいたほうが操作性はいいと思うけど、
 そうすると、結果的にリストにない項目が選ばれた状態になって、矛盾が発生するからということなんだね。
 だから、MatchReqired は False にしておいて、Styleで。なんとなく意図はわかる。

 私のコードでもやろうと思えばやれるけど、説明したように、コンボボックス選択時の負荷をおさえるため
 最初に一回だけ、必要な全てのリストを生成している。
 だけど、新しい要件でいえば、ComboBox4〜 で選ばれたときに実行、ここはそんなにコード変更はないけど
 ComboBox1 や、その上のレイヤーのComboBox3 が選ばれたときには、また元に戻しておく必要があるので
 少しいじることになる。

 BunさんのコードでOKなら、それを使うことにしたらいいかな?
 面白そうなので、こちらでも書いてみて、トピが閉じられていなかったらアップするかも。

 (ぶらっと)


 一応対応したつもり。
 修正部分のみを連絡すると、帰ってややこしいので全コードアップ。

 Option Explicit

 Dim dic As Object

 Private Sub UserForm_Initialize()
    Dim c As Range
    Dim myCode As String
    Dim myCat As String
    Dim myMedia As String
    Set dic = CreateObject("Scripting.Dictionary")

    With Sheets("単価マスタ")
        For Each c In .Range("B3", .Range("B" & .Rows.Count).End(xlUp))
            With c.EntireRow
                myCode = .Range("B1").Value
                myCat = .Range("J1").Value
                myMedia = .Range("C1").Value
            End With
            If Not dic.exists(myCat) Then Set dic(myCat) = CreateObject("Scripting.Dictionary")
            If Not dic(myCat).exists(myCode) Then
                Set dic(myCat)(myCode) = CreateObject("Scripting.Dictionary")
                dic(myCat)(myCode)("") = True
            End If
            dic(myCat)(myCode)(myMedia) = True
        Next
    End With
    Me.Tag = "Skip"
    ComboBox3.Clear
    ComboBox3.List = dic.keys
    Me.Tag = Empty

 End Sub

 Private Sub ComboBox3_Change()
    Dim v As Variant
    Dim i As Long

    If Me.Tag = "Skip" Or ComboBox3.ListIndex < 0 Then Exit Sub

    Me.Tag = "Skip"
    ComboBox1.Clear
    ComboBox1.List = dic(ComboBox3.Value).keys
    For i = 4 To 11
        With Me.Controls("ComboBox" & i)
            .Value = Empty
        End With
    Next
    Me.Tag = Empty
 End Sub

 Private Sub ComboBox1_Change()
    Dim i As Long
    Dim v As Variant
    If Me.Tag = "Skip" Or ComboBox1.ListIndex < 0 Then Exit Sub
    v = dic(ComboBox3.Value)(ComboBox1.Value).keys
    Me.Tag = "Skip"
    For i = 4 To 11
        With Me.Controls("ComboBox" & i)
            .Value = Empty
            .List = dic(ComboBox3.Value)(ComboBox1.Value).keys
        End With
    Next
    Me.Tag = Empty
 End Sub

 Private Sub ComboBox4_Change()
    Call DeleteMedia(ComboBox4)
 End Sub
 Private Sub ComboBox5_Change()
    Call DeleteMedia(ComboBox5)
 End Sub
 Private Sub ComboBox6_Change()
    Call DeleteMedia(ComboBox6)
 End Sub
 Private Sub ComboBox7_Change()
    Call DeleteMedia(ComboBox7)
 End Sub
 Private Sub ComboBox8_Change()
    Call DeleteMedia(ComboBox8)
 End Sub
 Private Sub ComboBox9_Change()
    Call DeleteMedia(ComboBox9)
 End Sub
 Private Sub ComboBox10_Change()
    Call DeleteMedia(ComboBox10)
 End Sub
 Private Sub ComboBox11_Change()
    Call DeleteMedia(ComboBox11)
 End Sub

 Private Sub DeleteMedia(cb As MSForms.ComboBox)
    Dim i As Long
    Dim dicA As Object
    Dim dicB As Object
    Dim d As Variant

    If Me.Tag = "Skip" Then Exit Sub
    Me.Tag = "Skip"
    Set dicA = CreateObject("Scripting.Dictionary")
    Set dicB = CreateObject("Scripting.Dictionary")

    For i = 4 To 11
        dicA(Me.Controls("comboBox" & i).Value) = True
    Next

    For Each d In dic(ComboBox3.Value)(ComboBox1.Value)
        If Len(d) = 0 Or Not dicA.exists(d) Then dicB(d) = True
    Next

    For i = 4 To 11
        With Me.Controls("ComboBox" & i)
            .List = dicB.keys
        End With
    Next
    Me.Tag = Empty
    Set dicA = Nothing
    Set dicB = Nothing

 End Sub

 Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
    Set dic = Nothing
 End Sub

 (ぶらっと)

 (ぶらっと)様、(Bun)様ありがとうございます。

 お二人のご意見とコードでコンボボックスの問題は解決したのですが、ユーザーフォームの転記でどうしてもつまづいています…

 内容がタイトルと変わりますので別トピ立てました。
[[20120411160743]]

 昨日からこの転記でずっと悩んでいます。

 なかなかうまくいきません・・・

 (peridot)


コメント返信:

[ 一覧(最新更新順) ]


YukiWiki 1.6.7 Copyright (C) 2000,2001 by Hiroshi Yuki. Modified by kazu.