ActiveSheetよりSet Sh = ActiveSheet【ExcelVBA】
あちこちのExcelVBAのサイトを見ていて、昔私がはまったActiveSheetの罠を思い出したので、誰かの役に立つよう、書いてみます。VBA初心者向けです。
ActiveSheetは現在アクティブなワークシート
当たり前のことですが、ActiveSheetというのは、現在アクティブなワークシートのことを指します。
アクティブかどうかは、コーディングしている段階では、初心者には分かりません(操作に慣れてくれば、分かるようになります。でも、最初のときは全然分かりませんでした)。
例えば、ActiveSheetに対して操作をしている途中で、別のブックをAdd(追加)したとします。
すると、アクティブなシートはそのAddしたブックのシートに移ります。
ところが、そのことに気が付かず、同一のシートに対して操作しているつもりでActiveSheetをうかつに使ってしまうと、思わぬ誤動作を招きます。
Public Sub 実験()
ActiveSheet.Range("A2").Value = "テスト"
MsgBox ActiveSheet.Range("A2").Value
Workbooks.Add
MsgBox ActiveSheet.Range("A2").Value
End Sub
これを実行した結果は、こうです。
変数に入れてしまう
じゃあどうしたらよいかというと、変数に入れてしまえばよいのです。
変数に入れるには、最初に変数を宣言しておきます。
変数を宣言するにはDim(Dimentionの意味)を使います。
Dim Sh As Object
Asの後ろは変数の型を指定します。変数の型は2つだけ覚えてください。Object と Variant の2つです。
Object:めんどくさい方
Variant:普通の方
と私は昔覚えました。
Objectというのは、特別な変数でして、代入するときにSetというオペラントを使います。初心者のときはそれだけ覚えていればよいです。めんどくさいことは慣れてくればだんだん覚えてきます。シートとかブックとか、ちょっと特殊なものを変数に入れたいときに使います。どれがObjectでどれがObjectでないかは、おいおい覚えるから大丈夫です。
Variantというのは、実は覚えなくてよいです。なぜなら、Asを省略すると、VBAではすべて勝手にVariant型にしてくれるからです。
つまり、Objectにしたい変数だけAs Objectをつければよく、他の変数はすべて型指定を省略してしまえばよいのです。
宣言しておいたObject変数Shに、ActiveSheetを代入するには、次のように書きます。
Set Sh = ActiveSheet
数学と違って、プログラミングの「=」というのは代入の意味を持っています。
右側のActiveSheetが左側のShという変数に代入されます。
Object型ですのでSetが必要です。Setを書かないとコーディングの段階では怒られませんが、実行したときに怒られます。
先ほどのコードをSh変数を使って書き直すと、下記のようになります。
Public Sub 実験()
Dim Sh As Object
Set Sh = ActiveSheet
Sh.Range("A2").Value = "テスト"
MsgBox Sh.Range("A2").Value
Workbooks.Add
MsgBox Sh.Range("A2").Value
Set Sh = Nothing
End Sub
これで実行すると、今度はちゃんと「テスト」というメッセージボックスが表示されます。
Set Sh = Nothing というのは、メモリ解放のために書いてあるのですが、別に書かなくてもよいです。動作に違いはありません。
よくある間違い
別の言語に慣れている方がよくする間違いに、次のようなコーディングがあります。
Dim intCount,intSize,intWidth,intHeight As Integer
多分このコードを書いた方は、intCountもintSizeもintWidthもintHeightもすべてInteger型にしたかったのだと思うのですが、このコーディングでInteger型になるのはintHeightだけです。
それ以外の変数は、すべて型が省略されたと解釈され、Variant型になります。
VBAはそれほど優秀ではありません。他の優秀な開発環境に慣れたプロフェッショナルなSEさんにはびっくりするくらい低スペックで低速で融通がきかないのです。
正しく書き直すと下記のようになります。
Dim intCount As Integer,intSize As Integer,intWidth As Integer,intHeight As Integer
でも、初心者だったらこう書いてもOKです。
Dim intCount,intSize,intWidth,intHeight
開き直って、最初から型を書きません。これだとすべてがVariant型になります。
Integer型だろうとVariant型だろうと、動作にそんなに差はありません。速度が違うという人もいるけど、速度を気にするならVBAなんて不自由なモノを使ってはいけません。
変数宣言は省略してはいけない
じゃあ、変数宣言(Dim)も省略したい!と思うかもしれませんが、Dimは省略してはいけません。なぜなら、コーディングミスにつながりやすいからです。
Option Explicitは使っていますか?変数宣言を強制するオプションです。VBAを使い始めたら、最初に設定すべきだと私は思っています。
まだVBAのオプションで「変数の宣言を強制する」をチェックしていないなら、今すぐチェックすべきです。
VBE→ツール→オプションで設定することができます。
最初はOfficeTANAKAさん
私は最初はOfficeTANAKAさんで学びました。
豊富なVBAコードが載っていて、大変勉強になります。
変数の宣言についてはこちらのページです。
型の宣言ではなく、変数の宣言をするということに、当時目からうろこでした。
-
前の記事
MacBook Airの設定【Windowsとの違い】 2022.06.10
-
次の記事
【外国人技能実習生】玉掛の特別教育と技能講習 2022.06.12