作成日 2004/10/17
最終更新日 2005/10/22

エクセルVBAで複数のコントロールをまとめたものを、1つのコントロールとして扱いたい

 VBではユーザーコントロールというものがあってそれで実現できるけど、残念ながらVBAにはユーザーコントロールという機能がない。
じゃあ、どうするか。
だるまはクラスモジュールでその代わりをさせている。

※1:かなり無理がある。ユーザーコントロールで作ったものと、全く同じものは作れない。
※2:例えば、REALbasicを使って、エクセルのマクロを作ると言うならこんな事、考えなくてもいいかもしれない。でも金がかかる、、、。(だるま は使った事が無いので間違っているかもしれない。)

1.具体的に、どんなときにやるのか
2.どうやって、やるの?
3.やると何がよくなるのか(利点)
4.やると悪くなることはないのか(欠点)

1.具体的に、どんなときにやるのか

 やると何がよくなるのか(利点)も読んでほしいけど、とりあえず、下の絵を見てくれ。
複数のコントロールをまとめて扱いたい
複数のコントロールをまとめて、1つのコントロール
として扱いたい。

 上の図の青まるでくくった部分は、2つのラベルから出来てるけど、1つのコントロールとして扱いたい。
 それと、上の図の赤まるでくくった部分だけど、これは、フォームモジュールに貼付けるコントロールの数を減らし、コードを書く際、1つのモジュールに書 くコードの行数を減らして、コードを読み易くしたいので、1つのコントロールとして扱いたい。
このページのトップへ

2.どうやって、やるの?

 ここでは、簡単に説明する。(なんで、だるまがそんな事を考えたのか、なぜそうするのか、といったことは説明しない。)

クラスの作り方
  1. クラスモジュールを作る。(ここではクラス名をClass1とする)
  2. Class1にAdd(Byval containerClassObject as Object)メソッドを作る。
  3. 作ったaddメソッドにcontainerClassObjectにオブジェクトを追加するコードを書く。(Controlコレク ション のAddメソッドを使う)
  4. Deleteメソッドも作る。
使い方
  1. フォームモジュールの先頭に"Dim class1Object as Class1"とでも入力する。
  2. イニシャライズイベントで、"set class1Object = new Class1"とでも入力し、そのすぐ下に、"Call Class1Object.Add(Me)"とでも入力する。
  3. 最後に、ターミネイトイベントに"Call Class1Object.Delete"とでも入力しておく。
このページのトップへ

3.やると何がよくなるのか(利点)

 複数のコントロールをまとめたものを、1つのコントロールとして扱うと、以下の利点がある。(だるまが把握している範囲)
  1. フォームモジュールに貼付ける部品数が減り、コードが読み易くなる。
  2. 同じようなコードを書かなくてよくなる。書くコードの行数も減る。
  3. 再利用がし易くなる。

  1. フォームモジュールに貼付ける部品数が減り、コードが読み易くなる。
    とりあえず、下の絵を見てくれ。
    左はObjectBoxが役に立ってない
    左の場合、[オブジェクト]ボックス(赤でくくったところ)が役に立たない。

     上の図の[オブジェクト]ボックス(赤でくくったところ)を見てほしい。
     そもそも、[オブジェクト]ボックスというのは、あるプロシージャを探すのを楽 にする為のものだとだるまは考えている。
     しかし、上の図の左の場合、オブジェクトの数が多過ぎ。見るだけでうんざりする。
     [オブジェクト]ボックスをスクロールさせるだけで結構時間がかかる。
     [オブジェクト]ボックスに表示されているオブジェクトの半分はイベントを1つも実装していない。はっきり言って邪魔。
     こういう状態になると、せっかくの[オブジェクト]ボックスが使えなくなる。
    ※左のはエクセルのマクロ”特定の色のついた行だけ残す”の古いバージョン(ver2.1.0)のソースコード。オブジェクトの数は約140。この頃はほぼ全ての機能をフォームモジュールに実装して いた。右のは2004/10/11現在の最新バージョン(ver2.2.3)のソースコード。フォームに貼付けるオブジェクトの数が減って、見やすくなったと思う。

  2. 同じようなコードを書かなくてよくなる。書くコードの行数も減る。
    とりあえず、下のコードを見てよ。
    同じようなコードがある
    エクセルのマクロ”特定の色のついた行だけ残す”の
    古いバージョン(ver2.1.0)のソースコードの一部。
     同じようなコード57ヶ所もあった。

     上のコードを見てほしい。これはボタンが押されたときに、ボタンの背景とボタンのonoffを記憶する値を変更するコードなんだけど、これと同じような コードが57カ所もあった。たったそれだけで、700行以上にもなる。おいおい。
    ※1:今見ると、上のコードがかなり下手クソに見える、、、。このコードに関しての質問はしないで下さ い。
    ※2:もし、VBAにコントロール配列なるものがあったら、こんな事にはならない。


  3. 再利用がし易くなる。
     理由はよくわからないけど、確かに再利用がし易くなっている様に思える。
このページのトップへ

4.やると悪くなることはないのか(欠点)

 無い、と言いたいけど、実はある。(当然、だるまが把握している範囲)
  1. 余計なコードを書くハメになる。
  2. コントロールの位置、大きさがわかりにくくなる。
  3. 使い方を間違えるとエクセルが強制終了する。
  4. カプセル化が完全に出来ない。

  1. 余計なコードを書くハメになる。
     ユーザーコントロールが使えれば、この負担が多少減る。
     クラスモジュールでやる際には、ControlsコレクションのAddメソッドを使って、コンテナクラスにコントロールを追加するコードを書くハメにな る。
     貼付けたら当然、位置や大きさなんかのプロパティも変更しなくちゃいけない。これが以外と面倒くさい。
     さらに、ClearもしくはRemoveメソッドを使って、コントロールの削除をするコードも書くハメになる。これも面倒。
     イベントが必要な場合はEventステートメントを使ってコードを書くハメになる。面倒だ。(Macではイベントの作成は出来ない。
     自動でコードを作ってくれるツールを、誰かが作ってくれれば話は別。

  2. コントロールの位置、大きさがわかりにくくなる。
     ユーザーコントロールが使えれば、この負担が全くない。
     デフォルトでのコントロールの位置や大きさをコードで書くことになる。
     実行して初めて、コントロールの位置や大きさが目に見えるようになる。これはコードの可読性や保守性を悪くする。
     これも、誰かがそれ用のツールをタダで作ってくれれば、、、。

  3. 使い方を間違えるとエクセルが強制終了する。
     だるまのコーディングが悪いだけなのかもしれない。
     実行時に貼付けたコントロールをちゃんと削除してから、マクロを終了させないとエクセルが100%の確率で強制終了する。(※Mac X用の場合。他のバージョンのエクセルでは未調査)

  4. カプセル化が完全に出来ない。
     これもだるまのコーディングが悪いだけなのかもしれない。
     ControlsコレクションのItemメソッドを使用すると、まとめる前の個々のコントロールに直にアクセスできてしまう。これは非常に困る。
     もし、Controlsコレクションを使って、まとめる前の個々のコントロールにアクセスし、プロパティを変更するようなコードを 書いた場合、変なことが起こる。
Prev Up Next  Top
このページのトップへ


このページの利用によって発生した、いかなる損害について、このホームページの作成者は責任を負いません。
このページの間違いや嘘を見つけた方、このページに書いて欲しい情報がある方はメールをお願いします。

Microsoft 、Windows 、Visual Basic および Excel は米国Microsoft Corporationの米国およびその他の国における登録商標または商標です。
ここではExcel® をエクセル、Visual Basic® for Applications をVBAと表記する場合があります。
Mac 、Mac OS 、Mac OS X は米国Apple Computer,Inc.の登録商標または商標です。
REALbasic はREAL Software社の登録商標です。
その他、社名および商品名、システム名称などは、一般に各社の商標または登録商標です。

このホームページの作成者はこれらの会社とはいっさい関係がありません。