エクセル2003です。
ワークシート上に複数個のチェックボックスを配置し、オンの場合、その左隣のセルの値を返すマクロを作成する場合についての質問です。
普段はフォームのCheck boxを使っています。
フォームのCheck boxなら
Sub ChkBx()
With ActiveSheet.CheckBoxes(Application.Caller)
If .Value = xlOn Then
MsgBox .TopLeftCell.Offset(0, -1).Value
End If
End With
End Sub
と、標準モジュールに一つだけプロシージャを書いて、複数個のCheck boxに同一のマクロを登録すれば簡単に出来ます。
ところがこれをOLEObjectのCheckboxでやってみようと思ったところ、フォームのように一つのプロシージャを使いまわすことができず、シートモジュールに以下のように各Checkboxごとのマクロを書かなくてはいけないようです。
Private Sub CheckBox1_Click()
With OLEObjects("CheckBox1")
If .Object.Value Then
MsgBox .TopLeftCell.Offset(0, -1).Value
End If
End With
End Sub
Private Sub CheckBox2_Click()
With OLEObjects("CheckBox2")
If .Object.Value Then
MsgBox .TopLeftCell.Offset(0, -1).Value
End If
End With
End Sub
Private Sub CheckBox3_Click()
With OLEObjects("CheckBox3")
If .Object.Value Then
MsgBox .TopLeftCell.Offset(0, -1).Value
End If
End With
End Sub
3つや4つくらいならどうってことはないのですが十数個もあるとかなり面倒です。
OLEObjectのCheckboxでももっと簡単にする方法はないのでしょうか?
それともわたしが何かOLEObjectのCheckboxの使い方について思い違いをしているのでしょうか?
ご教示をお願いいたします。
No.1ベストアンサー
- 回答日時:
プロシージャChkBkに引数を持たしたらどうでしょうか。
'----------------------------------
Private Sub CheckBox1_Click()
Call ChkBx(1)
End Sub
Private Sub CheckBox2_Click()
Call ChkBx(2)
End Sub
'-----------------------------------
Sub ChkBx(N)
With ActiveSheet.OLEObjects("CheckBox" & N)
If .Object.Value = True Then
MsgBox .TopLeftCell.Offset(0, -1).Value
End If
End With
End Sub
'---------------------------------------------
しかしこれでもコントロールが数十もあると大変ですので
クラスを使用するといいでしょう。
”VBA コントロール 疑似配列”などをキーにして検索すると
サンプルコードがたっぷりヒットします。
質問者のレベルであれば当然クラスに挑戦することになるでしょう。。。(^^;;;
onlyromさま、ありがとうございます。
クラスを勉強してみるつもりではおりますが、自分でよく理解出来てないものを今、実装するわけにはいきませんので今回はプロシージャChkBkに引数を持たせることで対処しようと思います。
幸いWendy02さまのアドバイスで、シートモジュールに書くコードも簡単に出来そうです。
これからもご指導の程、よろしくお願い申し上げます。
No.6
- 回答日時:
こんにちは。
そのままになっているようですから、ちょっと割り込ませていただきます。
特に、Sub プロシージャは、標準で「参照渡し」となるので、明示的というか可読性のために、ByRef が必要な場合のみです。同じシートモジュールに書く限りは、オブジェクトを渡すのでも、あまり変わりがないように思います。確かに、オブジェクトを再取得する場合の、タイム・ロスを否定はできませんが、この程度では差が見られません。
takana_さんの、Sub ChkBx(ByRef N As MSForms.CheckBox)は、CheckBoxというオブジェクトを「参照渡し」させるために明示的に書いている。
onlyromさんの、 Sub ChkBx(N)も明示的には書いていないが「参照渡し」で「値渡し」ではないという理解でいいですね。
ありがとうございます。
No.5
- 回答日時:
#2です。
参考までにonlyromさんのコードを、以下のように引数でチェックボックスを渡すように変更すると
CheckBoxの名前と位置を意識しないで自由に作成することができるようになります。
'----------------------------------
Private Sub CheckBox1_Click()
'クリックされたCheckBoxを設定
Call ChkBx(ActiveSheet.OLEObjects("CheckBox1").Object)
End Sub
Private Sub CheckBox2_Click()
Call ChkBx(ActiveSheet.OLEObjects("CheckBox2").Object)
End Sub
'-----------------------------------
Sub ChkBx(ByRef N As MSForms.CheckBox)
With N
If .Value = True Then
MsgBox .TopLeftCell.Offset(0, -1).Value
End If
End With
End Sub
ご丁寧にありがとうございます。
onlyromさまのコードは省略しないで書くと
Sub ChkBx(ByVal N As Integer)
With ActiveSheet.OLEObjects("CheckBox" & N)
If .Object.Value = True Then
MsgBox .TopLeftCell.Offset(0, -1).Value
End If
End With
End Sub
と、「値渡し」していますが、それを「参照渡し」にするとサブルーチンの中にわざわざActiveSheet.OLEObjects("CheckBox" & N)と長々と書く必要がなくなるという意味に理解してよろしいでしょうか?
No.4
- 回答日時:
>ということは、BOOK起動時にWorkbookOpenイベントなどで必ずSub SetCheckBox()を走らせなくてはいけないということなのでしょうか?
はいその通りです。
クラスのインスタンスを作成し、それぞれのインスタンスとチェックボックスを関連付けないとクリックイベントは発生しません。
なんらかのコードで、クラスのインスタンスを作成させかつ、インスタンスを保持しなければなりません。
Private cChkbox(1 To 3) As Class1
が関数内ではなく、モジュール内変数として、宣言しているのはそのためです。
No.3
- 回答日時:
こんにちは。
以前、Class のインスタンスのお話はあまり興味を示されなかったようですので、こちらが書くのは控えておきますが、Class インスタンスのコードは、二重・三重になるので、多少、コードは複雑になるのはやむをえないです。
VBAでは一般的というか、私自身、#1さんのように、コードの共通部分だけ抜き出し、サブルーチン化してしまい、個々のオブジェクトのイベントを書くことになります。だから、コントロールツールの名称は、必ず枝番のように最後に数字をつけるわけですね。
面倒であるとかないとかは、この際はあまり重要でないというか、ある程度、複雑になり数が増えてくると、テキストエディタやワークシートの数式や関数を使い、コードを作ってしまってから、VBEditor 側に貼り付けるというのが、私のやり方です。
コントロール配列自体が、コントロールツール(OLEオブジェクト)では持たない性質上やむをえないのと、Classでは、イベント形式で、通常のワークシートなどにつけるものよりも、結果的に、内容によって煩雑というか、ややこしくなりがちなのです。また、インスタンスの恒常化も問題になります。欲を言えば、カプセル化についても考えなくてはなりません。プロの仕事(公開されたものという意味)では、アドインは別として、Class によるインスタンスを設けたものを見た記憶がありません。
Wendy02さま、いつもありがとうございます。
すみません、以前のClass のインスタンスのお話は興味がなかったのではなく不勉強なわたしには理解が出来なかったのです。
でも今回、No2のtakana_さまから具体的なコードのご教示があり、何もわからぬままにやってみたら作動したのでこれから勉強していきたいと思ってます。インスタンスの恒常化の問題?カプセル化?・・・もう何のことやら想像もつきません。すみません。
というわけで今回はクラスはほとんど理解できていませんのでNo1のonlyromさまからご教示のあったサブルーチン方式をWendy02さまの「ワークシートの数式や関数を使い、コードを作ってしまってから、VBEditorに貼り付ける」方法を使って行いたいと思います。
ありがとうございました。
No.2
- 回答日時:
まず、クラスモジュールを1つ作成してください。
例では、Class1としますそのクラスの中で、WithEventsをつけて、チェックボックスオブジェクトを宣言します。
そうすると、クラスの中でそのオブジェクトのイベントを記述することが出来るようになります。
中身の例です
Option Explicit
Private WithEvents objCheckBox As MsForms.CheckBox
Public Sub SetCheckBox(ByRef InCheckBox As MsForms.CheckBox)
Set objCheckBox = InCheckBox
End Sub
Private Sub objCheckBox_Click()
MsgBox objCheckBox.Name & "が" & objCheckBox.Value & "にチェックされました"
End Sub
このクラスを利用する例です
Option Explicit
Private cChkbox(1 To 3) As Class1
Sub SetCheckBox()
Dim i As Long
For i = 1 To 3
Set cChkbox(i) = New Class1
Call cChkbox(i).SetCheckBox(ActiveSheet.OLEObjects("CheckBox" & i).Object)
Next
End Sub
ワークシート上にCheckBox1、CheckBox2、CheckBox3という名のチェックボックスが
作成されていることが前提です。
takana_さま、ありがとうございます。
今回はNo1のonlyromさまの方法で対処することにしました。
ただ、クラスというものをやってみるのは今回が初めてですので後学のために以下の点をお教え願いたいのです。
「中身の例です」以下のコードをクラスモジュール
「このクラスを利用する例です」以下のコードを標準モジュールにコピペしました。
そのままCheckboxをクリックしましたが何も起こりませんでした。
それで標準モジュールのSub SetCheckBox()を実行させてみたところCheckboxをクリックすると作動するようになりました。
ところが一旦、BOOKを終了し、再度開いたら、また作動しません。
それでまた標準モジュールのSub SetCheckBox()を実行させてみたところ作動するようになりました。
ということは、BOOK起動時にWorkbookOpenイベントなどで必ずSub SetCheckBox()を走らせなくてはいけないということなのでしょうか?
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Visual Basic(VBA) EXCEL VBAにて動的にCheckBOXを複数作成し、同BOXにイベントを追加したい 1 2023/03/16 07:05
- Visual Basic(VBA) Excel VBAの解読について質問があります。 概要は、マクロでチェックボックスにチェックすると日 1 2023/02/10 07:50
- Visual Basic(VBA) VBA Userformで一部別シートに転記がしたいのですが 2 2023/05/24 13:08
- Visual Basic(VBA) VBAが止まります。 3 2022/08/31 14:09
- Visual Basic(VBA) VBAでoutlook365が起動しません。 4 2022/08/25 13:31
- Visual Basic(VBA) excel2021で実行できないマクロ。どこを直したらいいのか 2 2022/03/28 03:40
- Excel(エクセル) 並べ替え、ソートの構文がわからない。 お世話になります。VBA超初心者です。 エクセルでワークシート 2 2023/06/28 21:00
- Visual Basic(VBA) シートを選択して、1つのPDFにしたいのですが。 5 2022/10/03 20:18
- Visual Basic(VBA) Excel VBA ユーザーフォーム 複数のユーザーフォームの閉じ方。 2 2022/04/27 11:29
- Excel(エクセル) VBAについて 3 2022/06/19 18:19
このQ&Aを見た人はこんなQ&Aも見ています
-
性格の違いは生まれた順番で決まる?長男長女・中間子・末っ子・一人っ子の性格の傾向
同じ環境で生まれ育っても、生まれ順で性格は違うものなのだろうか。家庭教育研究家の田宮由美さんに教えてもらった。
-
EXCEL VBAにて動的にCheckBOXを複数作成し、同BOXにイベントを追加したい
Visual Basic(VBA)
-
Excel VBAでCheckboxの名前を変数にとって値を調べたい
Visual Basic(VBA)
-
【VBA】シート上の複数のチェックボックスのうちどれか一つでも変更した場合のイベント
Visual Basic(VBA)
-
-
4
エクセル・VBA CheckBoxのオブジェクト名に変数を使うことは可能でしょうか?
Excel(エクセル)
-
5
エクセルVBAでセル番地を指定してオブジェクト名取得
Excel(エクセル)
-
6
エクセルVBAでOptionButtonのオンオフ取得
Excel(エクセル)
-
7
エクセル VBA CheckBox名に変数を使用
Excel(エクセル)
-
8
UserForm1.Showでエラーになります。
工学
-
9
ExcelのVBA・チェックボックスの操作を教えて下さい。
Visual Basic(VBA)
-
10
(VBA)チェックボックスのclickのイベントが、プログラムからの操作でも反応してしまいます。
Visual Basic(VBA)
-
11
VBAでワークシートを引数としてサンプル関数に渡したい
Visual Basic(VBA)
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
インスタンス参照でアクセスで...
-
変数名の付け方
-
C#において、同じインスタンス...
-
private static という変数の修飾
-
VB.NET getとsetの概念がわかり...
-
VC++コンソールアプリでのイン...
-
データベースから日付型を取得...
-
C#デストラクタが走る理由がわ...
-
インスタンスとスレッドの違い
-
newしないインスタンス?実体化...
-
ファイル読み込み/書き込み速度...
-
生成したインスタンスを削除す...
-
フォームの存在をチェックする方法
-
別のフォームでインスタンスを使う
-
C#の構造体の開放のしかた
-
複数の変数を宣言する時、同時...
-
C# インスタンスの破棄
-
メソッドの引数としてのthisの意味
-
SAPでいう「インスタンス」って...
-
PHPExcel使用で2枚目のシートを...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
変数名の付け方
-
インスタンス参照でアクセスで...
-
private static という変数の修飾
-
複数の変数を宣言する時、同時...
-
VB.NET getとsetの概念がわかり...
-
生成したインスタンスを削除す...
-
C# インスタンスの破棄
-
C#において、同じインスタンス...
-
「インスタンス」の意味をわか...
-
変数の参照でエラーが出てしま...
-
SQLを連続発行する時の正しい(?...
-
オブジェクト参照がオブジェク...
-
文字列を日付に変換でParseExce...
-
VB6.0で、DLLを動的に参照したい
-
javaのクラスの作り方、エラー...
-
インスタンスを同じ名前で作成...
-
エクセル(複数インスタンス)...
-
フォームの存在をチェックする方法
-
C#「オブジェクト参照が必要で...
-
newしないインスタンス?実体化...
おすすめ情報