ActiveSheetよりSet Sh = ActiveSheet【ExcelVBA】

  • [記事公開]2022.06.11[最終更新]2022.06.30
  • Excel

あちこちの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を書かないとコーディングの段階では怒られませんが、実行したときに怒られます。

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→ツール→オプションで設定することができます。

VBEのオプション。私は自動構文チェックはうざいので外しています。変数の宣言を強制するは必ずチェックします。

最初はOfficeTANAKAさん

私は最初はOfficeTANAKAさんで学びました。

OfficeTANAKA

豊富なVBAコードが載っていて、大変勉強になります。

変数の宣言についてはこちらのページです。

変数の宣言

型の宣言ではなく、変数の宣言をするということに、当時目からうろこでした。