VBA初学者の方を混乱させるポイントとして、
「Setステートメント」があります。
セルをRange変数に入れる(代入する)時に使う、
Set セル = Range("A1")
この記述のことですね。
このSetステートメントが必要なケースとその理由について解説します。
混乱しないように先に答えだけを書いておきますと、
- SetはVBAさんがコードを見分けるためのただの目印
- Setがなにか特別な処理をしているわけではない
- Range.やWorksheet.など「"."が使える変数」にはSetを使う
と理解しておけば実務的には困りません。
それを踏まえた上で、以下の解説を読んでいただければと思います。
オブジェクト変数とは
先に簡単に「オブジェクト変数」とはなにかをおさらいしておきましょう。
例えば「A1セルの値を1、背景色を黄色、文字色を赤」にするとします。
このとき、変数を使わない場合は
Worksheets("○○").Range("A1").Value = 1 Worksheets("○○").Range("A1").Interior.Color = RGB(255, 255, 0) Worksheets("○○").Range("A1").Font.Color = RGB(255, 0, 0)
こんな風に書くことになります。
簡単なコードですが、セルの指定がちょっと煩わしいですね。
これを変数を使ってこんな風にコードを整理することができます。
Dim 処理セル As Range Set 処理セル = Worksheets("○○").Range("A1") 処理セル.Value = 1 処理セル.Interior.Color = RGB(255, 255, 0) 処理セル.Font.Color = RGB(255, 0, 0)
綺麗なコードになりましたね!
変数の中見には「数値:Long」や「文字列:String」だけでなく、
「シート:Worksheet」や「セル:Range」などを設定することもできます。
このようにただの値(数値や文字)よりも大きいもの、
より正確には「.○○」というコードが書けるものを「オブジェクト」と呼び、
それを代入する変数をオブジェクト変数と呼びます。
まずはこれを抑えておいてください。
オブジェクトは"."が使える & ものによっては省略もできる
先ほどオブジェクトは「.○○」が使えるものと説明しました。
そこで先ほどのこのコードを見てください。
処理セル.Value = 1
セルの値を「1」にしているストレートなコードですね。
さてこのコード、「Rangeオブジェクトは.Valueを省略できる」仕様を使って、
↓このように書くことも可能です。
処理セル = 1
これもよくある省略形ですね。
さてこれを踏まえて、セルの値に1ではなく別のセルの値を入れてみましょう。
処理セル.Value = Worksheets("△△").Range("B1").Value
これもストレートなコードですね。
それではこのコードの「.Value」も省略してみましょう。
処理セル = Worksheets("△△").Range("B1")
これでも同じ処理が実行できます。
実はこのコードこそが「Setが必要な理由」を表すコードですので、
よーく眺めてみて下さい。
Setを使ってVBAさんに「=の代入先」を示してあげる
さて先ほどのコードをもう一度よく見てみましょう。
処理セル = Worksheets("△△").Range("B1")
このコード、よくよく考えると、
- 「処理セルの値」にB1セルの値を代入
- 「処理するセル」をB1セルに設定
どっちの意味にも取れてしまうんですよね。
このままではどっちで処理して良いかVBAさんは判断がつかないわけです。
と、そこでまさにSetステートメントの出番になるわけですが、
上記の2つのコードを区別するために、
- Setをつけなかったら"="の代入先は「.Value」
- Setをつけたら"="の代入先は「変数そのもの」
こんな風に書き分けるルールになっているのです。
実際のコードで説明すると、
処理セル = Worksheets("△△").Range("B1") ' ↑SetがないのでVBAさんは↓のコードであると判断する 処理セル.Value = Worksheets("△△").Range("B1").Value Set 処理セル = Worksheets("△△").Range("B1") ' ↑SetがあるのでVBAさんは「.Value」ではないと判断し、 ' 「処理セル」という変数の中身を△△シートのB1セルに設定する
こんな風になっています。
要するに「これは.Valueではないよ」という目印がSetなわけですね。
なので冒頭で説明した通り、Set自体に何か処理があるわけではありません。
Setはもうおまじないだと思って、
- LongやStringなどただの値の時はSetは不要
- RangeやWorksheetなどオブジェクトの時はSetが必要
- Setを書かない場合は「.Value」に代入されることになる
単にこう覚えてしまえばOKです。
先ほど説明した通り、対象がオブジェクトかどうかは
「.○○」のようにドット"."を使ったコードが利用できる
かどうかで判断できます。
逆に言えば「.○○」が使えるもののことをオブジェクトと呼びますので、
オブジェクトがイマイチわからなかった方はこんな風に捉えてみてください。
ついでに説明してしまうと、
オブジェクトを使うコード「○○.△△」において、
- ○○はオブジェクト(または親オブジェクト)
- △△が値や設定ならプロパティ
- △△が何かを実行する機能ならメソッド
と呼びますので、こちらもこの機会に覚えてしまいましょう。
これを読んだ後だと、
- Rangeオブジェクト(セル)のValueプロパティ(セル値)
- Rangeオブジェクト(セル)のInteriorプロパティ(背景色の設定)
- Rangeオブジェクト(セル)のCopyメソッド(コピー機能)
という用語がスッと入ってくるかもしれません。
このあたりなんとなくでいいので理解しておくと、
今後のExcelVBAの勉強が捗るんじゃないかと思います。
以上でオブジェクト変数とSetステートメントの解説を終わります。
まとめると、
- SetはVBAさんがコードを見分けるためのただの目印
- Setがなにか特別な処理をしているわけではない
- Range.やWorksheet.など「"."が使える変数」にはSetを使う
- Setを使わなかった場合は省略時のプロパティ(RangeならValue)が呼ばれる
ということでしたね。
最初は困惑するかもしれませんが、一度分かってしまえば単純な話かと思います。
オブジェクト、プロパティ、メソッドの話と合わせて、
この機会に覚えてしまってください。