プロが教えるわが家の防犯対策術!

タイトルの通りシート上に複数のチェックボックスがあった場合、そのうちどれか一つでもチェックの値が変更した時に、グローバル変数の値を変更したいと考えているのですが、何か良い案はありますか?
一つ一つのチェックボックスのchangeイベントに書くのも大変なため、質問させて頂きました。
ご回答お願いします。

質問者からの補足コメント

  • 回答ありがとうございます。

    ACTIVEXのチェックボックスを考えてます。

    >シートに連動させておいて、シートの値が変わった時に処理とかでは

    ですが、No.2で回答していただいたチェックボックスをセルにリンクさせるということでしょうか?

    No.1の回答に寄せられた補足コメントです。 補足日時:2018/07/25 22:32

A 回答 (5件)

No2、No4です



セルのリンクで変化を取得する方法を考えてみました。

No2でセルのリンクではイベントが発生しないと書きましたが、少し工夫をすることでイベントを発生させることが可能なので、必ずしも監視する方法に頼る必要はなさそうです。

例えば、別に専用シートを設けておいて、そのA列に各チェックボックスをリンクさせておきます。
このままではNo2に記したように、Changeイベントは発生しません。
そこで、B列に =A1 のような関数式をフィルコピーしておきます。
これによって、シートのCalculateイベントが発生しますが、こちらであれば取得することが可能です。

どのチェックボックスが変化したかまでを知りたいような場合は、イベント処理終了時にA列をC列にコピーしておけば、イベント発生時にA列とC列を比較することで、どのチェックボックスが変わったのかも確認できるようになります。
    • good
    • 0
この回答へのお礼

助かりました

複数回の回答ありがとうございました。
本日も考えてて、別の専用シートまでは考えてたのですが、changeイベントで検出できないことを知りどうしたものかと悩んでおりました。
おっしゃる通りセルを参照させてcaluculateイベントで検出させればできますね。
すごく勉強になりました。
ベストアンサーに選ばせて頂きます。

お礼日時:2018/07/28 00:37

No2です。



>ACTIVEXのチェックボックスを考えてます。
フォームのチェックボックスが利用できない理由がわかりませんが、ActiveXの場合は、実際の内容は同じルーチンを呼ぶにしても、イベントのキャッチは個々に記述しないとできない仕組みになっていますよね?

ですので、面倒でも
>一つ一つのチェックボックスのchangeイベントに書くのも大変なため~~
を行わざるを得ないかと思います。
あるいはNo2の後半で示した方法によるかですが、この程度の内容のために監視の為のプログラムを常時走らせておくというのもなんだか・・・と思います。
(セルへのリンクを一つ一つ設定していくのも面倒ですし、個別にコードを記述するのとたいして手間は変わらないでしょう)


どうしても、ActiveXオブジェクトを利用なさりたいのであれば、コードの設定そのものをVBAでできないかと試してみました。
>グローバル変数の値を変更したい
とのことですから、処理としては1行で済む程度と考えますので、オブジェクト名を変えながら同じコードをチェックボックスの数だけ記述すればすむものと想像します。

下記のVBAは、下に示すようなコードをActivesheet上のチェックボックス(ActiveX)全部に対して設定するものです。
  Private Sub CheckBox1_Click()
   MsgBox "CheckBox1 Clicked"
  End Sub

※ イベント処理用のコードのダブりはチェックしていませんので、すでに何らかのコードが設定されていたり、VBAを2度実行したりすると2重設定になってしまいます。
その際には、エディタ表示時やチェックボックスのクリック時にエラーになりますのでご注意。

(標準モジュールに記述)
Sub Sample()
 Dim cmp As Object
 Dim obj As Object
 Dim code As String

 code = "Private Sub *Name*_Click()"
 code = code & vbNewLine & "MsgBox ""*Name* Clicked"""
 code = code & vbNewLine & "End Sub"

 Set cmp = ThisWorkbook.VBProject.VBComponents(ActiveSheet.CodeName)
 For Each obj In ActiveSheet.OLEObjects
  If obj.progID = "Forms.CheckBox.1" Then
   cmp.CodeModule.AddFromString Replace(code, "*Name*", obj.Name)
  End If
 Next obj
End Sub
    • good
    • 1

ユーザーフォーム上なら楽なのかも知れません(事前設定・事後解放が)けど、それをマニュアルで操作させるとかであれば



>シート上に複数のチェックボックスがあった場合

これをコントロール配列のようにしてイベントをクラスモジュールで作成するってのは昔見かけましたよ。
結構丁寧に解説されていたサイトもあったのですがリニューアルの際に無くなってしまいました。

方法としてない訳ではないですが余り解説してないんですよね。
10年位前ならともかくVisualStudio.NET の時代になってからかそっちの解説なら増えたのですが。
    • good
    • 0

こんにちは



>一つ一つのチェックボックスのchangeイベントに書くのも大変なため~~
フォームのチェックボックスであれば、個別のクリックイベントではなく、任意のマクロを登録することができます。
マクロを登録したチェックボックスを作成しておいて、これをコピーすると、同じマクロが登録された状態で複製することができます。

このマクロは、チェックボックスをクリックすることで実行されますが、チェックボックスをクリックすることは、同時にチェックの状態を変える操作となりますので、
>どれか一つでもチェックの値が変更した時に~
の代用とすることが可能ではないでしょうか。

チェックボックスをセルにリンクさせておく方法もありそうですが、この場合はセルの値が変わってもシートのチェンジイベントは発生しないようですので、定期的に値を監視するようなマクロを作成して動作させておく必要がありそうです。
    • good
    • 0

> シート上に複数のチェックボックスがあった場合、



フォームのチェックボックスと、ActiveXのチェックボックスがあると思いますがどっちでしょう?


> どれか一つでもチェックの値が変更した時に、

シートに連動させておいて、シートの値が変わった時に処理とかでは。

それとも、チェックボックス以外のセルの内容が変わった時に処理しちゃマズイとかでしょうか?
または、どのチェックボックスが変わったのか分からなきゃ、グローバル変数の値が決められない?
この回答への補足あり
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています


このQ&Aを見た人がよく見るQ&A