[ 初めての方へ | 一覧(最新更新順) | 全文検索 | 過去ログ ]
『実行時エラー'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.