[[20110821221004]] 『実行時エラー'91'がでます』(gohan) ページの最後に飛ぶ

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

 

『実行時エラー'91'がでます』(gohan)

 エクセル2003 WindowsXPです。
 1つめのコンボボックス(cmb)を選択すると、
 コンボボックス2からコンボボックス9まで同じリストが入るようにしたいです。
 With myCbox.Parent のところで、
 実行時エラー'91':オブジェクト変数または With ブロック変数が設定されていません
 のエラーがでます..

 'クラスモジュール
 Private Sub cmb_Change()
 Dim dic2 As Object
 Dim q As Long
 Dim skip As Boolean

 Set dic2 = CreateObject("Scripting.Dictionary")
 dic2.RemoveAll
 skip = True
 v = Sheets("List").Range("A1").CurrentRegion.Value
 For q = 2 To UBound(v, 1)
 If v(q, 1) = cmb.Value Then dic2(v(q, 2)) = True
 Next

 With myCbox.Parent
 .Controls("g名称" & myID2).Value = dic2.keys ←ここでエラー
 End With
 skip = False
 End Sub

 他の方のコードを参考に、
 切り貼りして作成しているため、クラスの概念もわかりません。
 どうぞよろしくお願いします。


 myCboxとは何ですか。変数の宣言も代入しているところもみあたりませんが。
 (semm)

 すみません。
 myCboxは、コンボボックス2からコンボボックス9を代入?しています。
 よろしくお願いします。 

 '標準モジュール
 Dim id2 As String, Ctrlcmb2 As Control
 Dim cBoxPool() As Class1
 Private Sub UserForm_Initialize()
 (略)
 コンボボックスを作成します
 (略)
 ReDim cBoxPool(1 To Me.Controls.Count) 
 For Each Ctrlcmb2 In Me.Controls
 If TypeName(Ctrlcmb2) = "ComboBox" Then
 If Ctrlcmb2.Name Like "g名称*" Then
 id2 = Replace(Ctrlcmb2.Name, "g名称", "")←Ctrlcmb2はコンボボックス2からコンボボックス9
 r = r + 1
 Set cBoxPool(r) = New Class1
 cBoxPool(r).Create2 Ctrlcmb2, id2
 End If
 End If
 Next
 End Sub

 'クラスモジュール
 Dim WithEvents myCbox As MSForms.ComboBox
 Dim myID2 As String

 Sub Create2(cbox As MSForms.ComboBox, id2 As String)
 Set myCbox = cbox
 myID2 = id2
 End Sub

 Private Sub cmb_Change()
 Dim dic2 As Object
 Dim q As Long
 Dim skip As Boolean

 Set dic2 = CreateObject("Scripting.Dictionary")
 dic2.RemoveAll
 skip = True
 v = Sheets("List").Range("A1").CurrentRegion.Value
 For q = 2 To UBound(v, 1)
 If v(q, 1) = cmb.Value Then dic2(v(q, 2)) = True
 Next

 With myCbox.Parent
 .Controls("g名称" & myID2).Value = dic2.keys ←ここでエラー
 End With
 skip = False
 End Sub

 (gohan)


 不可解な点がいくつかあります。

 >Private Sub cmb_Change()
 Class1というクラスモジュール内で上記のイベントが発生するには、
 cmbというコンボボックス型の変数が定義され、この変数にオブジェクトが
 登録されていなければなりませんが、その記述が見当たらないこと。

 >With myCbox.Parent
 >   .Controls("g名称" & myID2).Value = dic2.keys ←ここでエラー
 >End With 

 これは、何をしようとしているのですか?
 コンボボックスにメンバーリストを登録するなら、
 .Controls("g名称" & myID2).LIST=dic2.keys

 です。

 又、
 >With myCbox.Parent
 >   .Controls("g名称" & myID2)
 これは、どんなコントロールを取得するためなのですか?
 "g名称" & myID2 で取得できるコントロールですか?
 では、myCboxこのコントロールのオブジェクト名はなんですか?

 他にも不明な点はありますが、要するに・・・、

 この投稿では、

 >.Controls("g名称" & myID2).Value = dic2.keys ←ここでエラー

 というエラー箇所にたどり着くまで閲覧者を導く記述になっていない

 ということです。

 シート名Listには、コンボボックスに登録するメンバデータの元が記述されているみたいですが、
 その具体的なデータについて何ら記述されていません。

 又、実際には、このエラーにたどり着くまでにオぺレーティングもあるなら、
 その記述も必要です。

 この手の掲示板は、質問者と回答者が共同でわかりやすいナレッジベースを作ることも
 一つの目的です。質問自体がわからなければ、良いナレッジベースにはなりません。

 この事を念頭において、何もないExcelブックから、ご自分が問題にしている
 エラーに導く記述をしてください。

 ichinose


 すでに皆さんからの指摘もでている通りだけど、とりあえず。
コードそのものは、気になるところが山ほどあったりするけど、それにも目をつぶって。

 まず、標準モジュール って書いてあるところ、本来はユーザーフォームモジュールだよね。

 If v(q, 1) = cmb.Value Then dic2(v(q, 2)) = True

 このcmb はタイプミス。規定されているのは myCbox 。
なぜコンパイルレベルでエラーにならないかというと、Option Explicit 記述がされていないから。
デバッグを容易にするためにも、全てのモジュールの先頭に Option Explicitの記述をした上で
コンパイルをかけてみよう。これ以外にも宣言されていない変数が指摘される。
Option Explicit は、VBE画面のオプション設定で、変数宣言を必須にするを選んでおくと
モジュール挿入時に自動的に付加される。

 で、直接のエラーは

 With myCbox.Parent
   .Controls("g名称" & myID2).Value = dic2.keys ←ここでエラー
 End With

 だけど、コンボボックスの値として、dic2.keys??
dic2.keysは一次元配列。ValueじゃなくListにいれたいんだよね。(かつ、1列だけど、いいのかな?)
★リストとして格納したいシート上の列は何列あるのかな?
 (CurrentRegion となっていて、これからはいかがいしれない)

 さらにいえば 対象コンボボックスは、ここでは myCbox。従って、
対象コンボボックスの親(ユーザーフォーム)のコントロールで "g名称" & myID2 という参照は
非常に無駄だねぇ。この3行は、myCbox.Value = 何か という1行でいけるでしょ?

 9つあるコンボボックスのリスト格納でクラスを使ってみたいという「知的好奇心」については
おおいに評価するけど、もう少し、クラスそのものを勉強してからのほうがいいかも。
(ついでにDictionaryも。Changeイベントで毎回、オブジェクト生成してしかも不要なRemoveAll)

 というか、これをクラス処理しないで「ベタ」にコーディングしたとして、おかしなところは他にもかなりあるよ。

 (ぶらっと)

 上のレスで、アップされたコードをよく読んでいなかったための私の勘違い部分があった。
cmb というのは、その名前のコンボボックスなんだね。 で、その選択された値でしぼったリストを
g名称2〜g名称9 のリストとして入れたいということだったんだね。

 まぁ、その勘違いは勘違いとして、アップされたコードの構成そのものが間違っているよ。
各コンボボックス.Change イベントは(クラスで処理するにしろ、ユーザーフォーム内で処理するにせよ)
各コンボボックスの「値が変更されたら」、つまり一般的な操作でいえば、各コンボボックスのリストから「選択」されたら発生する。
だから「選択されたら、選択するためのリストをセットする」という構成というか、発想そのものが間違っているよ。

 クラスの勉強は別にして、本件は、ユーザーフォームモジュールの cmb のイベントで他のコンボボックスの値に
同じリストをセットすればいいというか、セットすべき。

 もう1つ。Changeイベントは、1文字入力されるごとに発生する。
上でもかいたように、ほとんどはリストからの選択だから、選んだら1回イベントが発生するんだろうけど
可能性としては、コンボボックスに直接入力もできるわけで、そうすると、1文字入力するたびにイベントが発生する。
これは無駄という前に、中途半端な文字列で、検索することで、不具合が発生する元になる可能性もある。
ここは Changeイベントではなく BeforeUpdate とか AfterUpDate 系のイベントを使うべき。

 (ぶらっと)

 たぶん、やりたいことは単純に以下?ユーザーフォームモジュールに。

 Private Sub cmb_BeforeUpdate(ByVal Cancel As MSForms.ReturnBoolean)
    Dim c As Range
    Dim v() As String
    Dim i As Long
    Dim x As Long

    With Sheets("List").Range("A1").CurrentRegion.Columns(1)
        x = WorksheetFunction.CountIf(.Cells, cmb.Value)
        If x = 0 Then
            MsgBox "cmbの値にマッチするものはありません"
            For i = 2 To 9
                Me.Controls("g名称" & i).Clear
            Next
            Exit Sub
        End If

        ReDim v(1 To x)
        For Each c In .Cells
            If c.Value = cmb.Value Then
                i = i + 1
                v(i) = c.Offset(, 1).Value
            End If
        Next

    End With

    For i = 2 To 9
        Me.Controls("g名称" & i).List = v
    Next

 End Sub

 (ぶらっと)

 semmさん、ichinoseさん、
 ぶらっとさん回答ありがとうございました。

 ぶらっとさんの回答をもとに、
 cmb_Changeを書き換えたところ、
 なぜだか?意図したように動くようになりました..

 Private Sub cmb_AfterUpDate()
 Dim dic2 As Object
 Dim q As Long
 Dim skip As Boolean

 Set dic2 = CreateObject("Scripting.Dictionary")
 dic2.RemoveAll
 skip = True
 v = Sheets("List").Range("A1").CurrentRegion.Value
 For q = 2 To UBound(v, 1)
 If v(q, 1) = cmb.Value Then dic2(v(q, 2)) = True
 Next

 For i = 2 To 9
 With UserForm1.Controls("g名称01010" & i) 'コンボボタン2〜9
 .List = dic2.keys
 End With
 Next i

 End Sub

 Listシートは下記のようなリストで、

 工種      名称      製品名
 電気設備	照明		koizumi
 電気設備	照明		national
 電気設備	インターフォン  アイホン
 電気設備	スイッチ       ・
 給排水設備	便器  	   ・
 給排水設備	便器        ・
 給排水設備	洗濯機用水洗
 給排水設備	ガーデンパン

 絞込みリストの作成は、こちらを参考にしました。
『VBA コンボボックスの連動について』(ひしょう)
 https://www.excel.studio-kazu.jp/kw/20110801145152.html

 VBAやクラスを理解してないために、
 うまく説明できなくてすみませんでした。
 ありがとうございました!
 (gohan)


コメント返信:

[ 一覧(最新更新順) ]


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