- ベストアンサー
ExcelVBAのチェックボックスの値を取得する方法
- ExcelVBAを使用して、ユーザーフォーム間でチェックボックスの値を取得する方法について説明します。
- ユーザーフォーム1には50個のチェックボックスがあり、ユーザーフォーム2でこれらの値を取得したいと考えています。
- 50個の値を取得するためには、ループを使用することで処理を短くすることができます。具体的な実装方法についても解説します。
- みんなの回答 (4)
- 専門家の回答
質問者が選んだベストアンサー
varCheck1とvarCheck(i)は全く別物です。 さらに言うと標準モジュールの先頭で定義する (1)Public varCheck1 as variant とプローシジャ内で同じ名前で定義する (2)Dim varCheck1 as variant は別物にです。 きちんとヘルプなりインターネットで調べるなりして 理解しましょう。 余計なことを書いたので混乱したのかもしれませんので 話をもとに戻しましょう。 そもそもvarCheck1,varCheck2と言う変数では きちんと思う通りの動作していたのでしょうか。 それならvarCheck1のところをvarCheck(1) varCheck2をvarCheck(2)。。。以下略 に置き換えて動かして見ましょう。 きちんと動いたらそこで 最初の質問、チェックボックスの値の取得の部分を For Each con In ユーザーフォーム1.Controls If TypeName(con) = "CheckBox" Then varCheck(i) = con.Value i = i + 1 End If Next に置き換えればよいだけです。
その他の回答 (3)
- o_chi_chi
- ベストアンサー率45% (131/287)
まず最初にVBEツール→オプションの編集タブで "変数の宣言を強制する"にチェックを入れてください。 また、標準モジュール等先頭に "Option Explicit"が付いてないときは自分で入力してください。 (意味はヘルプなりで確認してください。) 変数varCheck(1 To 50)と varCheck1、varCheck2の使い方があいまいです。 配列は使わずとりあえずvarCheck1を使いましょう。 varCheck1は標準モジュールでPublicで定義しているので フォーム1でもフォーム2でもアクセスできるはずです。 (4)で状態を維持してとありますが、ちゃんとvarCheck1に 保存されていますか? まず、 varCheck1 = ユーザーフォーム1.CHECKBOX1.Value にブレイクポイントを設定してそこで変数にきちんと値が 入っているか確認することをおすすめします。 ひとつひとつ動いているかスッテップ実行で確認しながら勧めていかないと。 一通りうまく処理できるようになってからチェックボックスを増やしたり 効率よく処理できるよう配列化したりしましょう。
補足
度々の御回答有難うございます。 御指摘の通り、varCheck1に保存されているかブレークポイントを設定して 確認しましたが、値は取得されていました。 その後のユーザーフォーム2に記載の下記コード Dim con As Variant Dim i As Long i = 1 For Each con In ユーザーフォーム1.Controls If TypeName(con) = "CheckBox" Then varCheck(i) = con.Value i = i + 1 End If Next を確認すると、varcheck(i)で値が取れていませんでした。 varCheck1とvarCheck(1)は、異なるものなのでしょうか? なぜ値が取得できないか知識不足で解決できません。 再三の御回答、御手数ですが宜しくお願い致します。
- o_chi_chi
- ベストアンサー率45% (131/287)
(1)標準モジュールで問題ないです。 ただ、保存したvarCheckをユーザフォーム2内で処理したいのであれば varCheckを引数として関数に渡すかグローバル変数にするかしないと うまく動きません。 (2)con.Nameでいま処理しようとしているオブジェクトの名前です。 Dim n As String n = con.Name でnに名前が取得できます。 (3)取得順は保障されないって書きましたが、張り付けた順で取得できる かもしれません。(確認は取れていないですが。) ただ、住所・性別・年齢等の場合は連想配列を使えば処理が楽かもしれません。 その場合の名前の取得がcon.Nameです。
補足
度々の御回答ありがとうございます。 ユーザーフォーム2の中にANO.1のコードを記載して 動作するようになりましたが、ユーザーフォーム1の値が取れません。 質問が的確でなく、不足している部分があるかもしれませので 再度、動作について以下に記載致しますので御教示下さい。 (1)最初にユーザーフォーム2を開く (2)次にユーザーフォーム1を開く (3)ユーザーフォーム1のチェックボックスをチェックする。 (4)その状態を維持して、ユーザーフォーム1を閉じる。 【ユーザーフォーム1に記載のコード】 Dim varCheck(1 To 50) As Variant varCheck1 = ユーザーフォーム1.CHECKBOX1.Value Unload ユーザーフォーム1 (チェックボックスの値をvarCheck1に代入) (5)ユーザーフォーム2でチェックボックスの状態を ループを使用して、状態を取得して処理を実施。 (現状は、varCheck1、2、3と1つずつ処理している) (以下のような処理をユーザーフォーム2で実施) If varCheck1 = True Then 処理(2) = 処理(1) + チェック有(1) Else 処理(2) = 処理(1) End If ユーザーフォーム間は、標準モジュールに Public varCheck1 Public varCheck2 と記載しています。 varCheck1を変数にして扱えれば良いのですが やり方が分かりません。 Dim varCheck(1 To 50)としても、標準モジュールで 設定できません。 色々試していますがどのようにしていいのか 同じ事を長々と記載しましたが 宜しくお願い致します。
- o_chi_chi
- ベストアンサー率45% (131/287)
たとえば --- Dim con As Variant Dim i As Long i = 1 For Each con In ユーザーフォーム1.Controls If TypeName(con) = "CheckBox" Then varCheck(i) = con.Value i = i + 1 End If Next コントロールの取得順は保障されなかったような気がします。 なので名前の数字を取得してそれを配列の添え字に利用する とよいと思います。 コントロールの名前は con.Name で取得できます。
補足
VBA初心者なので、簡単な質問かもしれませんが 追加で質問させて頂きます。 (1)記載されたコードのユーザーフォーム2に記載するのでしょうか? (2)con.Nameの取得とはどのようにするのでしょうか? (3)質問ではCHECKBOX1,2,3・・・としましたが、チェックボックスのオブジェクト名に数字が入っていないような場合の方法があるのでしょうか? 例)チェックボックスのオブジェクト名が、住所、性別、年齢等である場合
お礼
多くのアドバイス有難うございました。 試行錯誤を繰り返しながら、やっとできるようになりました。