2016
9
14

ExcelVBAのクラスモジュールって何?という人向けの使い方まとめ

なかなか上手に使いこなせなかったクラスモジュールが、ようやく頭の中で氷解してきた気がするので、自分のためにまとめてみました。めちゃくちゃ長いです。


目次

  1. はじめに
  2. VBAクラスモジュールの簡単な使い方
    1. クラスを書く
    2. 標準モジュールからクラスを使う
    3. どう便利なの?
  3. クラスを便利に使う
    1. 複数のプロパティを持つクラスを作る
    2. クラスを使った複数のインスタンスを作ってみる
    3. 2次元配列と比較してみる
  4. プロパティに制限をつける
    1. 「隠蔽」されているプロパティ
    2. プロパティを読み取り専用にする
    3. プロパティを一度だけ設定可能にする
  5. 制限のないプロパティ設定/取得を簡単に書く
    1. Public変数で簡易的なプロパティに
    2. 制限の有無で書きわける
  6. クラスモジュールでサブルーチンを使う
    1. 引数を指定して同じ処理をさせる
    2. 複数のプロパティの設定をまとめて行う
    3. イベントプロシージャを共通化する
  7. コンストラクタとデストラクタ
    1. 書き方
    2. 呼び出されるタイミング
  8. もっとクラスモジュールを活用したい
    1. クラスモジュールを使った例

1. はじめに

VBAにもクラスはあるのですが、常々あんまり活用できてないなーと思ってました。それが先日、データベースから吐き出したCSVファイルを2次元配列に格納したのをきっかけに、2次元配列の構造をよくよく考えたら、これこそクラスで実現できるところなんじゃ…? と思い至り、やっっと自分の中で曖昧だった部分がすっきりした気がするので、その経緯を書き綴っておきます。

今回の思いに至るまで、VBAでクラスモジュールの記事を多数扱うthomさんのブログを読み漁り、twitterに突撃にしてご本人に質問したら快く教えてくださって、本当に本当にお世話になりました。

記事中でもその都度ご紹介させていただきますが、まずはこの場にて、厚くあつーく、御礼申し上げます!!! thomさん、ありがとうございましたー! ヽ(゜´Д`)ノ゜。

2. VBAクラスモジュールの簡単な使い方

まずは基礎的なところから。新規のxlsmファイルをVBEで開いて、標準モジュールとクラスモジュールを作成してみましょう。

160914-01

「挿入」から「標準モジュール」と「クラスモジュール」をクリックして、

160914-02

このように標準とクラスのモジュールができました。慣れてきたらクラスの名前を任意のものに変更すると更に可読性も良くなるんですが、今回は説明のため、デフォルトのClass1で進めていきます。

2-1. クラスを書く

作成したClass1に、以下のように書いてみます。

Class1に「Value」という数値型のプロパティ(属性)の設定・取得を「するための」記述をします。設定するProperty Letと、取得するProperty Getプロシージャ、その間の値を受け渡すためのValue_という変数。ひとつの属性に対して、この3つがワンセットです。(例外もありますが、とりあえず基本として。)

オブジェクト型のプロパティを設定したい場合は、LetではなくSetになります。

この時点ではまだピンと来ないかもしれませんが、Class1にこの記述をすると、こんなイメージになります。

160914-03

Class1さんの運営する配車センターです。現在は、Class1さんが「この形の車、配車うけたまわります」と言っているだけで、実際にはまだ、車はありません。

標準モジュールからClass1さんにお願いして、車を手配してもらいましょう。

2-2. 標準モジュールからクラスを使う

Module1にこのように書きます。

これが一連の流れです。ひとつずつイメージ図と一緒に見ていきましょう。

インスタンスの生成

160914-04

インスタンスというのは「実体」という意味です。Class1さんにお願いしてobj1という車を1台用意してもらいました。

プロパティの設定

160914-05

ここで、さっきClass1に書いたProperty Letプロシージャが呼び出され、手配してもらった車の「Value」という荷台に荷物が載せられます。

プロパティの取得

160914-06

荷物を載せたあと荷台の中身を尋ねると、Class1のProperty Getプロシージャが呼びだされ、何が載っているのか教えてくれます。

インスタンスの破棄

160914-07

使わなくなったobj1という車を、荷物を捨てて廃車にしちゃいます。本物の車だったらその都度廃車にするなんてもったいなさすぎですが、プログラム上では使わなくなったものを残しておくと、不具合を起こしたり効率が悪くなったりする場合もあるので、片付けてキレイにします。

追記:正しくは「インスタンスへの参照の破棄」

この記事では全体的に「インスタンスの破棄」と書いてしまっているのですが、実際にはこの記述では参照を破棄しているのであって、直接オブジェクトを破棄しているわけではありません。こちらの記事でthomさんが解説してくださってます!

参照されなくなったオブジェクトは最終的に破棄されます。ここから先は「参照」が省略されてるんだなーと思って読んでいただけると幸いです!

ちなみに、破棄の記述は場合によって省略できます。上記の例はひとつのプロシージャ内だけで使うものであり、その場合はプログラムが終了する際に自動的に破棄されるので、この1文は書かなくても問題ありません。

ただし、もちろん省略できない場合(プロシージャを超えて大きな範囲で使うなど)もありますので、省略されていたとしても、「破棄という手順がある」ということだけは覚えておきましょう。

破棄の記述については「省略できるところは省略しちゃおう派」と「意味がなかろうと作法としてちゃんと書いとくべきだろ派」があるようです。

2-3. どう便利なの?

さて、ここまでがひととおり基礎的な使い方なのですが、これだとイマイチ便利に感じないですよね。ひとつ変数を用意して、それに中身を入れればいいだけなのに、なんでわざわざクラスを作ってめんどくさいことをするの? って思っちゃいます。

クラスは、ひとつの車にひとつのプロパティ(属性)を持つだけだったら、全然便利じゃありません。プロパティを複数持っていて、その形の車がたくさん必要というときにはじめて、「なにこれ便利!!!」が実感できるのです。

3. クラスを便利に使う

それでは今度は、Class1さんの配車センターの車をグレードアップしてみましょう。

3-1. 複数のプロパティを持つクラスを作る

さっきの例を参考にして、今度はClass1に3つのプロパティの設定/取得のプロシージャを書いてみます。

160914-08

Class1さんの配車センターが新装開店しました。プロパティが3つ載せられる車を手配してくれます。

3-2. クラスを使った複数のインスタンスを作ってみる

では今度は、この形の車をClass1さんに複数用意してもらいましょう。標準モジュールに以下を書きます。

160914-09

18行目までのコードで、3台の車を手配してもらって、それぞれのプロパティに荷物を載せました。

160914-10

この後20~22行目のDebug.Printを通ると、イミディエイトウィンドウに、このように表示されます。

このように、ひとつのオブジェクトに対して名前や値段などの好きな形のプロパティを自分で設定して使うことができて、更にそれをたくさん作ることができるんです。

Range("A1").ValueRange("A1").Addressのようなことを、自分で作れちゃうわけです。内容を端的にあらわすプロパティ名にしておけば、書くときに直感的にわかりやすいですし、書いた後の可読性も高いですよね。

3-3. 2次元配列と比較してみる

ここまで例として挙げたデータは、2次元配列でも表せます。

Name Price Number
いちご 150 5
りんご 200 3
みかん 180 10

試しに、このデータを2次元配列で表現してみましょう。

配列は0から数えるので、モノの数が3つ、それぞれのプロパティ(属性)が3つで、ary(2, 2)という2次元配列に格納したとします。この中のデータをひとつ指定したいとき、配列にNameやPriceなどの要素名は保持できないので、

  • 1つめのモノの名前は? → ary(0, 0)
  • 2つめのモノの個数は? → ary(1, 2)
  • 3つめのモノの値段は? → ary(2, 1)

このように要素の位置を数値で指定しなければなりません。Numberの要素は何番目だっけ…、実際コードに書いた後も、どの要素を表しているのかわかりにくいです。

しかも配列はあらかじめ、格納する要素の数がいくつなのかを先に指定して定義してやらなくちゃいけないので、要素数が不確定な場合はめんどくさいんです。

しかしクラスモジュールを使ってプロパティを作り、インスタンスを生成して書いてみると、

  • 1つめのモノの名前は? → obj1.Name
  • 2つめのモノの個数は? → obj2.Number
  • 3つめのモノの値段は? → obj3.Price

このように書けるので、めちゃめちゃわかりやすい!!! のです。しかも必要なときに必要なだけ作ることができる。とっても扱いやすいです。

そして更にスゴイところはココ。クラスを使ってインスタンスを生成した変数は、

160914-11

自分で作ったプロパティが候補として出てくるんです! すてき!!

4. プロパティに制限をつける

さて、使い方が分かってきたところで、もうちょっと突っ込んだ特性を見ていきましょう。

4-1. 「隠蔽」されているプロパティ

クラスモジュールに、以下のような「Name」というプロパティの設定/取得をするPropertyプロシージャがあったとします。

Propertyプロシージャ間の値を受け渡す変数Name_は、Privateで宣言されており、このクラスモジュール内でしか使えません。

変数の適用範囲に関する過去記事

そして、どのモジュールでもそうですが、プロシージャのPublicは省略することができます。逆に言えば、プロシージャの先頭に何も記述されていない場合はPublicと判断されます。

つまり、先ほどのコードはこういうことになります。

プロパティの値が入っているName_はPrivate変数なので、クラスモジュールの外側からは直接操作することができません。外部からは、PublicであるLet/Getのプロシージャを介さないとプロパティを操作できないのです。

これは、オブジェクト指向プログラミングの説明で言われる、「カプセル化」「隠蔽」という手法です。中身を隠して操作を制限することで個々の独立性が高まり、それにより保守性やコードの可読性などが向上し、いろいろと効率が上がるのです。(ざっくりした説明)

VBAはオブジェクト指向言語ではありませんが、クラスが使えるので似たようなことができる、というニュアンスです。

とはいえ、上記のコードは値を「隠蔽」させる形はしていますが、ただ値を引き渡しているだけです。この形にもっと処理を加えることで、値を「隠蔽」させる意義が出てきます。

4-2. プロパティを読み取り専用にする

それでは、プロパティに制限を設けてみましょう。さきほどのクラスモジュールのコードを、このようにしてみます。

Property Getプロシージャだけにしてみました。こうすると、Nameプロパティは取得はできても設定はできなくなるので、読み取り専用となります。

したがって、標準モジュールにこのように書いても、上記のハイライト部分でエラーになります。

160914-12

この場合、インスタンスを複数作成しても、Nameプロパティは全部「ぶどう」です。

4-3. プロパティを一度だけ設定可能にする

インスタンスごとに違う名前を設定したい、でも上書きできないようにしたい! ということもできます。

基本形のProperty Let(設定)プロシージャにIf文が入りました。Name_の中身をチェックして、空じゃなかったら(既に設定されていたら)エラーを出すことができます。

標準モジュールにこのように書くと、最初の「いちご」は設定できても、更に「りんご」を上書きしようとするとエラーになります。

160914-13

他にも使い方はいろいろで、教えてくださったthomさんからは

LetにIf文を持たせることで、設定できる文字数や、数値の範囲などを判定させ、不正な処理をハンドリングできます。

というお言葉もいただいております! いろいろ便利な使い方ができそうです。

たとえばプロパティに「月」を持たせたい場合、数値以外はダメ、1~12の範囲内じゃないとダメ、整数じゃないとダメ、などのチェック処理をしなきゃいけないですよね。これを実行側のプロシージャではなく、Property Letプロシージャ側に書いてあげれば、実行側のプロシージャはとても簡潔になります。

5. 制限のないプロパティ設定/取得を簡単に書く

上述したように、Propertyプロシージャは制限を設けて隠蔽させることでメリットがあるわけですが、制限不要なプロパティを作りたい場合は、実はもっと簡単に書けるんです。

5-1. Public変数で簡易的なプロパティに

まずは、クラスモジュールでのPropertyプロシージャの基本形。(何度も書いてますが、おさらい。)

この形は、設定も取得も無制限で行えるので、隠蔽させる意味はそんなにありません。この場合、

と、代わりに書くことができます。

わたしは、thomさんのブログではじめてこれを見たとき、あまりの短さに、マジかっっ!!!Σ(゚д゚lll)ってなりましたw

この書き方はプロパティに制限をつけられませんし、Publicで宣言しているので外部からのアクセスは自由で「隠蔽」の形ではありません。しかし制限を設ける必要のないプロパティならば、この書き方のほうが効率的ですよね。

ここでまたthomさんからのひとこと。

VBAでは制限のないPropertyに意味はないので、Public変数で作ってしまったりしますが、VB.NETなら、クラスを継承することでプロシージャのオーバーライドが使えるので、あえてPropertyプロシージャにしておく意味はあります。

VBAならではってこと、結構ありますよね。

5-2. 制限の有無で書きわける

というわけで、せっかく短く書ける方法があるのだから、読み書き制限を設けないプロパティと制限を設けるプロパティで、書き方を変えればいいのです。クラスモジュールに、以下のように書いてみます。

NamePriceNumberプロパティは自由に設定/取得ができますが、Saleプロパティは計算した値を取得するGETプロシージャしかないので、値を書き替えることはできません。

これで標準モジュールにこのように書けば、それぞれのプロパティが簡単に取得できます。売上であるobj1.Saleは、obj1.Price×obj1.Numberと書いても同じ値をとることはできますが、クラスにプロパティとして登録してしまったほうがスマートに扱えますよね。

6. クラスモジュールでサブルーチンを使う

ここまで、Class1を配車センターに例えて、クラスモジュールでプロパティを設定/取得する方法について書いてきました。でも、重要なことがあります。このままでは、この車は荷物を載せ降ろしするだけで、動かないんです。

せっかくなら、いろんな荷物を載せて動いて欲しいですよね。その「動き」は、標準モジュールでよく使う、サブルーチンを使います。(もちろん関数も使えます。)

160914-14

サブルーチンをクラスに書くと、Class1さんの配車センターが更にグレードアップし、みんなに同じ動きをさせることができます。この車を複数台手配して動かしてみると、載っている荷物がそれぞれ違うので、省コードで多様な結果を得ることができるんです。

書き方は、クラスに書いたサブルーチンを、実行側のモジュールでオブジェクト名.サブルーチン名と、ドットで区切って指定します。プロパティの書き方と同じですが、

  • Range(“A1”).Name → Range(“A1”)「の」Name(属性/プロパティ)
  • Range(“A1”).Select → Range(“A1”)「を」Select(働き/メソッド)

ちょうどこのように、サブルーチンで書いたものは、上記の「メソッド」になります。

6-1. 引数を指定して同じ処理をさせる

それでは例として、クラスモジュールに以下のように書いてみます。

制限を設けないプロパティを3つと、Workという名前のサブルーチンを1つ作ってみました。サブルーチンでは、2つの引数を持ってくるようにします。

次に標準モジュールへ次のように書きます。

3つのインスタンスを生成してプロパティを指定した後、ハイライト部分でさっき作ったサブルーチンの処理をさせます。それぞれに違う引数を与えています。

160914-15

実行すると、このように表示されます。

160914-10

サブルーチンを作る前はこのような結果だったので、名前に装飾、値段が×1.08、個数が指定値で乗算されているのがわかります。

3つとも同じサブルーチンを通っていても、プロパティの値も、指定した引数も違うので、それぞれ違った結果が得られていますよね。

6-2. 複数のプロパティの設定をまとめて行う

ここまでプロパティに値を設定するときは1つずつ記述していましたが、サブルーチンを使って、複数のプロパティを一度に設定することもできます。

クラスモジュールに以下のように書いてみます。

これまではプロパティが3つあったら、設定用と取得用プロシージャがそれぞれ3つずつありましたよね。このうち3つのLet(Set)プロシージャを、このように1つのサブルーチンで書くこともできます。

無制限のプロパティで良ければ、変数をPublicで宣言しちゃえばGetがなくても使えます。

このサブルーチンを標準モジュールから使う場合は、

このように書きます。クラスに書いたサブルーチンの形に合うように、プロパティの値を引数として指定します。プロパティがたくさんあっても1行で書けるので楽ですよね。

6-3. イベントプロシージャを共通化する

もうひとつ、クラスモジュールとサブルーチンの組み合わせを使って、ユーザーフォームのイベントを共通化してみましょう。

イベントプロシージャは通常1コントロールにつき1つなので、複数同じ処理をしたいときに同じことを何度も書かなければならなくなります。これをクラスを使って共通化させると便利です!

またしてもthomさんの記事を参考にしております。ありがとうございます!

カレンダーコントロールを作る記事を書いたのですが、今回はそれを例に「フォーム上のいずれかのラベルがクリックされたら、そのコントロール名とキャプションを取得」するコードを書いてみます。

140804-16

ラベル番号がこのように並んでいるフォームがあって、

140804-24

最終的にはこんな形のユーザーフォームがあるとします。実際のカレンダーコントロールでは曜日や年月もラベルのため、Label1~42だけに適用させるために配列を使ったのですが、ここではもっと汎用的に、すべてのコントロールをループさせて、ラベルだけコレクションに格納してみます。

このフォームをCalenderFormという名前だとして、まず標準モジュールへ以下を書きます。

フォームを表示するだけです。次にクラスモジュールへ以下を書きます。

WithEventsでラベルオブジェクト変数を宣言しておきます。イベントが発生したときに通るプロシージャは変数名_イベントという名前で、共通化させたい内容を書いておきます。

最後にCalenderFormのフォームモジュールへ以下を書きます。

7~14行目でフォーム内のすべてのコントロールをループさせ、ラベルだったときだけ9~12行へ入り、コレクションへ追加していきます。インスタンス変数objはループの中で何度も使われるため、その都度破棄しないとならないので、12行目は省略できません。

これで、さきほど標準モジュールに書いたプロシージャを実行してカレンダーフォームを表示させ、

140804-27

試しに「20」をクリックしてみると、

160914-16

イミディエイトウィンドウに、クリックされたコントロール名とそのキャプションが入って、フォームが閉じます。ラベル以外のコントロールをクリックしても何も起こりません。

7. コンストラクタとデストラクタ

クラスモジュールの機能として、インスタンスの生成時と破棄時に自動で呼び出されるプロシージャがあります。生成時に呼び出されるプロシージャをコンストラクタ、破棄時に呼び出されるプロシージャをデストラクタと呼びます。

7-1. 書き方

クラスモジュールに以下のように書くと、インスタンスが生成されたときに呼び出されます。

インスタンスが生成されたときにこのプロシージャを通るので、ここへプロパティの値を書いておくと初期値を設定することができます。

コンストラクタに引数を渡せる言語の場合、インスタンス生成と同時に値の代入までまとめて書くことができるのですが、VBAはコンストラクタに引数が渡せないので、基本的にはこの中に書いた値しか使えません。初期値というより規定値という感じかも。

VBAで引数つきコンストラクタを実現させるためにいろんな手法を開発している上級者の方々もいらっしゃいますので興味があれば調べてみてください!

デストラクタの場合は以下のように書きます。インスタンスが破棄されたときに呼び出されます。

自動で破棄されないオブジェクトの確実な後始末や、ログを残したいときなどに、ここに処理を書いておきます。

7-2. 呼び出されるタイミング

ここまで、クラスを使ったオブジェクト変数を、宣言とインスタンス生成で1行ずつ、このように書いていました。

これを、以下のように1行でまとめて書くこともできます。

1行で書けるので楽なんですが、ちょっと使い方に癖があります。

こちらのサイトにあるとおり、VBAはオブジェクトに実際にアクセスが発生した際にインスタンスが生成されるため、書き方によってコンストラクタを通るタイミングが違うんです。そして、宣言等の記述があっても実際にインスタンスが生成されなかったオブジェクトを破棄した場合はデストラクタを通りません。

実際に挙動を見てみましょう。下記をクラスモジュールに書きます。

コンストラクタで3つのプロパティに規定値を入れる、という形です。次に標準モジュールへ、このクラスを使うコードを書いてみます。

このように書くと、2行目はただの宣言なので、インスタンスが生成される3行目が実行されるときにコンストラクタを通ります。

宣言とインスタンス生成の記述をひとつにまとめてみました。しかしこれだと、実は2行目ではインスタンスは生成されていないそうなんです!! 動かしてみると4行目の実行時にコンストラクタを通ってから値の取得を行っているので、ここで生成されているのがわかります。記述的には「New」でインスタンスを生成してるっぽく感じるのですが、このあたりVBA独特な挙動のようです。

この書き方でも、2行目では実際にはインスタンスは生成されません。3行目の実行時に生成されるので、そこでコンストラクタを通ってからプロパティを上書きするSetPropプロシージャを通ります。

この書き方だと、やっぱり2行目では実際にはインスタンス生成がされていない状態です。このまま4行目でこのオブジェクトを破棄する記述をすると、インスタンスができていないので、デストラクタを通りません。

インスタンスが生成されていてNothingの記述がない場合は、サブルーチンを抜けたりプログラムが終了するなどの、「自動で破棄されるタイミング」でデストラクタが呼び出されます。

このように、宣言とNewの書き方によって挙動が異なるので、きちんと確認しておくのが良さそうです!

追記:宣言とNewを1行で書くの、なんと公式では非推奨らしい…!

一緒に書いてしまうことで、上述のようにコンストラクタ/デストラクタのタイミングが変わったり、Nothingで破棄したオブジェクトが参照できてしまったりと、不安定な挙動を見せるようです。というわけで、これから勉強していこうと思っている方は宣言とNewを分けて書く方向で覚えるのがお勧めです。

8. もっとクラスモジュールを活用したい

ものすっごい長い記事を、ここまで読んでいただいてありがとうございます。

一応、自分の中の溜まりに溜まったインプットは吐き出せたかな、という感じですが、これを踏まえて実務にどう活かすかを考えていきたいですね。

自分の業務で一番活かせそうなのはデータベースに絡めた使い方かなと思っているので、そのへんをまた書きたいと思っているのですが、わたしはひとつの(しかもIT系でない)企業にずっと属している人間なので、他の方のクラスモジュールの使い方には大変刺激を受けます。

例えばこちら。

ちょ、ちょうちょ飛んでるー!!! Σ(゜Д゜;

フローチャートがほぼ自動で!!?? Σ( ̄□ ̄|||)

追記:こちらのプログラム、わたしが勘違いしていたのですがクラスモジュールは使っていなくて、シートモジュールに記述されていました。すみません…! でもPropertyプロシージャを巧みに使っておられて、とっても勉強になります!

などなど、世界は広いです…。こういうのを見ると、データよりも図形とかオブジェクトを動的に動かすのに向いているような、だから他の言語ではゲームとか作るのに使われているんだろうなー、と、なんとなく思いました。

クラスモジュールでできることはまだまだ想像もつかないくらいあるんでしょうが、まずは自分の業務で実用的だと思えることから頑張っていきたいと思います!

そして最後にもう一度、thomさんありがとうございました!!

8-1. クラスモジュールを使った例

その後、クラスを使って書いてみた記事を追記していきます。

ご参考になれば幸いです。

  • このエントリーをはてなブックマークに追加
  • follow us in feedly 618
  • RSSを登録

公開日:2016/09/14
更新日:2016/10/10


8件のコメント

  • イナカモノ
    2016年9月15日 2:37 PM

    こんにちわ。
    ExcelVBAとAccessの連携を調べていた所このHPを拝見しました。
    お陰で上手く連携出来て助かりました。

    クラスのお話が出ていたので…
    個人的にクラスで取っ付き易いのはWithEvents絡みかなと考えております。
    説明が上手く出来ないので参考ページを張っておきます。

    ・VB中学校 Visual Basic 6.0 初級講座
    http://homepage1.nifty.com/rucio/main/shokyu/jugyou30.htm

    ・hatena chips クラスで自作イベントを実装する
    http://hatenachips.blog34.fc2.com/blog-entry-174.html

    主にAfterUpdateイベントにて入力後の内容をTrimしたり、INSERT文を仕込んで入力ログを取るのに使ったりしています。
    Accessのフォームに連携させると、とても便利です。
    問題は、周りの同僚が付いていけないので難しいクラスを実装できない事です…

    • *you
      2016年9月15日 7:40 PM

      イナカモノさん、コメントありがとうございます!(わたしも田舎者ですw)

      Accessへの連携、お役に立て光栄です! やはりWithEvents絡みはもっと使えそうですね。わたしは業務ではExcelVBAを扱うことが多いのですが、AccessVBAならEventで動かすこと多いですもんね。参考になります、ありがとうございます(*゜ω゜*)

      追記:Propertyプロシージャだけじゃダメだろうと思って、サブルーチンの説明も追加しました。せっかくなのでイベントについても書かせていただきました!

  • イナカモノ
    2016年9月23日 9:12 PM

    こんばんわ、イナカモノです。追記、とても参考になりました。
    「Private LblClc As Collection~」の辺りは全く知りませんでした。
    thomさんのブログはマメにチェックしていたのですが…

    「ExcelVBAでControlオブジェクトのChangeイベントを一括制御する方法」も
    更新されているのを見つけました。
    私も40個位のTextBoxの入力ログを取る方法が分からなくて泣きながら
    Excelのセルに「=”Private Sub ” & TextBox1 & “_Exit(略”」と
    書いて無理やりコードを生成して誤魔化した覚えがあります。
    今日、まだそのフォームが動いているのを見つけて変な汗が出ました…

    さて本題ですが、ExcelVBAではWithEventsでExitが使えないと知り、
    昔のリベンジがてら、無理やり汎用クラスを書いてみました。
    自分のブログも無く、吐き出す場所が無いのですいませんがここで…長くなりますがご容赦下さい。
    気が付かない間違いもあるかも…

    一番左のシートのセルA~C列に入力ログを入れていきます。
    考えとしては、他の入力オブジェクトに入力をしたら、前の入力オブジェクトの
    データを入れるという考えです(MicroSoftのHPで前そういう内容を見かけたので)

    1:Form

    2:Module

    3:Class

    • *you
      2016年9月24日 4:49 PM

      ううわぁぁぁすごいコードありがとうございます! コード表示のため一部整形させていただきましたのでご了承くださると幸いです。こういうコードって結構需要がありますので是非ブログはじめてみてはいかがでしょうか(ΦωΦ)フフフ…

      涙なしでは語れないエピソード、わたしも心当たりがありすぎます。あるあるですよね!! そして息が長いところもあるある…(;´Д`)

  • イナカモノ
    2016年9月28日 10:32 PM

    こんばんわ、イナカモノです。
    コードの整形、有難う御座いました。自分のコード見てちょっと感動してました。

    ブログはどうしようかと暫く悩んでいたのですが
    仕事の小話とかで多少はネタがあり、前向きに考え中です。
    最近、私事で忙しいのですぐには無理ですがいずれは…
    出来たとしてもAccessとExcel(とVBA)の話が多くなりそうなので
    アクセス数は完全に度外視の趣味サイトになりそうです(;´・ω・)

    ではまた、いずれどこかで…

    • *you
      2016年9月29日 12:18 AM

      こんばんは! コード修正承りました。(修正事項はコメント欄には必要ないかと思って非公開にさせていただいちゃいますね。)綺麗に整形されていると自分のコードでも結構良さげに見えるものだと、わたしもいつも思ってますw

      AccessとExcelとVBA、まさにうちですよ! 言語としてはマイナー感ありますが利用者はとても多いので需要はあるものだと実感しています。ブログ始めたら是非教えてくださいねー!ヽ(゚∀゚)ノ

  • nao
    2016年9月30日 4:03 PM

    先日はありがとうございました(@^∇^@)
    おかげさまで出来ました!
    表はテーブル名や名前定義ではできないようで、範囲指定にてできました。
    皆にも喜ばれちょっと鼻高々~( ^ ≧^)フフーン
    (って、ほとんどyouさんが作ってくれたんだけどw)

    あのあと、ちょっと忙しすぎて出来た御礼も言えず申し訳ないです。

    この投稿もとってもわかりやすくていいですね!
    考え方がわかり易く、空っぽの頭でも(⌒^⌒)b なるほど!ってなります。

    さて、週末は仕事のこと忘れて遊びましょう!!

    • *you
      2016年9月30日 9:26 PM

      naoさん、コメントありがとうございます。できたんですねー! よかったです!

      この記事から、例のパワポコピペのコードにつなげて記事にしたいと思っているのですがなかなかたどり着けず…。。ゆっくり書いていきます(*`・ω・)ゞ わたしも今週末は娘の運動会がんばってきますー!

コメントを残す




*印は必須項目です。コメントは承認制ですので、反映までしばらくお待ち下さい。(稀にですがスパムの誤判定にて届かないこともあるようですので、必要な際はお問い合わせからお願い致します。)


back to top