VBAのDimとSetの違いとは?初心者が混乱しやすいポイントを徹底解説
生徒
「先生、VBAで変数を使うとき、普通に代入する場合と、Set(セット)を使う場合があって混乱しています。何が違うんですか?」
先生
「それは非常に重要なポイントですね。VBAには『普通のデータ』と『オブジェクト』という、種類の違うデータがあるんです。」
生徒
「オブジェクト…?なんだか難しそうです。使い分けを間違えるとどうなるんですか?」
先生
「エラーが出てマクロが止まってしまいます。でも大丈夫、身近な例えを使えば、未経験の方でもすぐに理解できますよ。さっそく見ていきましょう!」
1. DimとSetの役割をスッキリ整理
Excel VBA(エクセル・ブイビーエー)の世界では、何か値を保存しておくために「変数(へんすう)」という名前の付いた「箱」を用意します。この箱を用意する命令が Dim(ディム)です。
そして、その用意した箱の中に「何を入れるか」によって、その後の書き方が変わります。ここが初心者が一番つまずきやすいポイントです。
- 普通のデータ(数値や文字)を入れる場合: そのまま「変数 = 値」と書きます。
- 特別なデータ(シートやセルそのもの)を入れる場合:
Set(セット)という言葉を頭に付けて「Set 変数 = オブジェクト」と書きます。
この「特別なデータ」のことをプログラミング用語でオブジェクトと呼びます。まずはこの二つの違いを意識することから始めましょう。
2. 「値」と「オブジェクト」の違いを例え話で理解する
プログラミングを全く触ったことがない人でもわかるように、身近なもので例えてみましょう。
「普通のデータ(値)」は、例えば「りんごの値段(100円)」や「名前(田中さん)」のような情報そのものです。これらは紙に書いて箱にポイっと入れることができます。だから Set はいりません。
一方、「オブジェクト」は、例えば「冷蔵庫そのもの」や「テレビそのもの」だと思ってください。冷蔵庫そのものを小さな箱に入れることはできませんよね?そこで、箱には「あのキッチンにある冷蔵庫を指していますよ」という「リモコン(操作権)」を入れるイメージになります。このように、物そのものを扱うときに「この箱はこの物を操作する専用にしますよ」と決めるのが Set の役割です。
Excelでいうと、セルに入っている「100」という数字は「値」ですが、セルという「枠組みそのもの」やシート全体、ブック全体は「オブジェクト」になります。
3. Setを使わない「普通の変数」の書き方
まずは Set を使わない、基本の書き方をおさらいしましょう。数字や文字を扱うときは、これだけでOKです。
Sub SimpleValueExample()
' Dim(ディム)で箱の名前と種類を決める
Dim price As Integer
Dim message As String
' 値を入れる(Setはいりません)
price = 500
message = "こんにちは"
' 実行結果を表示
MsgBox message & "。価格は" & price & "円です。"
End Sub
ここで使っている Integer(インテジャー)は整数のこと、String(ストリング)は文字のことです。これらは「情報そのもの」なので、そのままイコールで結んで代入できます。
4. Setを使う「オブジェクト変数」の書き方
次に、いよいよ Set を使った書き方です。特定のワークシートやセル(レンジ)を変数に代入するときに使います。これをオブジェクト変数と呼びます。
Sub ObjectSetExample()
' ワークシートという「物」を入れるための箱を用意
Dim mySheet As Worksheet
' Set(セット)を使って、特定のシートを箱に割り当てる
Set mySheet = Worksheets("Sheet1")
' 箱(mySheet)を通じてシートを操作する
mySheet.Range("A1").Value = "ここはSheet1です"
mySheet.Name = "基本データ"
End Sub
もし、このコードの Set を忘れて mySheet = Worksheets("Sheet1") と書くと、VBAは「えっ、シートそのものをどうやって普通の箱に入れればいいの?」と困ってしまい、実行時エラーが発生します。
5. なぜSetを使って変数にシートやセルを入れるの?
「わざわざ変数に入れなくても、そのまま Worksheets("Sheet1").Range("A1").Value = ... と書けばいいのでは?」と思うかもしれません。しかし、Set を使うことには大きなメリットがあります。
- コードが読みやすくなる:
Worksheets("売上データ_2024年度_最新版")と何度も書くより、Set ws = Worksheets(...)と一度書いてwsで操作したほうがスッキリします。 - ミスが減る: 長い名前を何度も打つと、一文字間違えるだけでエラーになります。変数にセットしておけば安心です。
- 動作が速くなる: パソコンが「どのシートだっけ?」と探す手間が一回で済むため、大量のデータを処理するときに速度の差が出ます。
6. Setで代入した中身を空にする「Nothing」
オブジェクト変数は、普通の変数とは違ってパソコンのメモリ(作業領域)を少し多めに使います。そのため、使い終わった後に「この箱はもう空っぽですよ」と明示的に片付ける習慣をつけると、上級者への一歩となります。その時に使うのが Nothing(ナッシング)という言葉です。
Sub CleanUpExample()
Dim targetRange As Range
' A1セルをセット
Set targetRange = Range("A1")
targetRange.Value = "作業中"
' 使い終わったので空にする(お片付け)
Set targetRange = Nothing
End Sub
これも Set とセットで使います。Nothing を代入することで、プログラムに「この物はもう使わないからメモリを解放していいよ」と伝えることができるのです。
7. 初心者が絶対にはまる「Set忘れ」のエラー対策
VBAを書いていて、以下のようなメッセージが出たことはありませんか?
実行時エラー '91':
オブジェクト変数または With ブロック変数が設定されていません。
これは、9割以上の確率で「Setを書き忘れている」か「Setしたつもりが中身が空っぽ」なのが原因です。特にシートやセルを扱うコードでこのエラーが出たら、まず自分のコードに Set があるか確認しましょう。
反対に、数字や文字を入れるときに Set age = 20 と書いてしまうと、「オブジェクトが必要です」という別のエラーが出ます。頭の中の整理として、「Excelの画面で見える『物(シート、セル、グラフなど)』を扱うときだけ Set を使う」と決めておくとスムーズです。
8. セル操作におけるDimとSetの組み合わせ実践
最後に、実際の仕事でよく使う「シートとセルの操作」を組み合わせたコードを見てみましょう。別のシートから値をコピーしてくるような処理です。
Sub CopyDataWithSet()
' 二つのシートを操作するための箱を用意
Dim wsSource As Worksheet
Dim wsDest As Worksheet
' それぞれのシートをセット
Set wsSource = Worksheets("入力シート")
Set wsDest = Worksheets("出力シート")
' 値そのものを扱う変数を宣言(Setはいらない)
Dim tempValue As String
' 入力シートのB2セルの「値」を取得
tempValue = wsSource.Range("B2").Value
' 出力シートのB2セルに「値」を書き込む
wsDest.Range("B2").Value = tempValue
' 完了報告
MsgBox "転記が完了しました!"
End Sub
このプログラムでは、シートを扱うときには Set を使い、セルの「中身の文字(値)」を扱うときには Set を使っていません。この違いこそが、VBAを使いこなすための最大の鍵です。これが理解できれば、複雑なマクロも自信を持って書けるようになりますよ!