Excel VBA | 変数にオブジェクトを代入 (Set文)

Excel VBA VBA
スポンサーリンク

初心者向けにやさしく、例題つきで詳しく説明します。読みやすく段階を追って進めますね。コピーしてそのまま実行できるサンプルコードも含めます。

1. まず全体像(ざっくり)

  • オブジェクトとは「ワークシート」「セルの範囲(Range)」「ブック(Workbook)」など、属性や動作を持つデータのかたまりです。
  • Excel VBAでは、こうしたオブジェクトを操作するためにオブジェクト変数を使います。
  • オブジェクト変数に代入するときは、必ず Set を使います(=だけだとエラーになります)。

2. なぜ Set が必要か(イメージ)

  • 普通の数値や文字列は「値」を直接代入します:num = 10(10そのものを格納)
  • オブジェクトは「モノ(実体)」への参照を格納します。Setは「この変数にこのオブジェクトへの参照を入れてね」と明示するためのキーワードです。
  • 例えるなら:数値は「紙に書かれた数字」を持つのに対し、オブジェクトは「机の場所(ポインタ)」を持つ、みたいな違いです。

3. 基本の書き方(例付き)

例 1:セル(Range)をオブジェクト変数に代入して操作する

Sub Example_Range()
    Dim r As Range       ' Range型の変数を宣言
    Set r = ThisWorkbook.Worksheets("Sheet1").Range("B2") ' Setが必須

    r.Value = "こんにちは"  ' 代入したオブジェクトを使って操作
    r.Font.Bold = True     ' 書式も変えられる

    Set r = Nothing        ' 後片付け(メモリ解放の意味)
End Sub
VB
  • ポイント:Set r = Range("B2") のように Set を忘れると実行時エラーになります。

例 2:ワークシートを変数に入れて複数処理する

Sub Example_Worksheet()
    Dim ws As Worksheet
    Set ws = ThisWorkbook.Worksheets("Sheet1")

    ws.Range("A1").Value = "日付"
    ws.Range("A2").Value = Date

    Set ws = Nothing
End Sub
VB
  • 何度も ThisWorkbook.Worksheets("Sheet1") を書かずに済むので、コードが読みやすく速くなります。

例 3:別のブックを開いて変数で扱う(Workbook オブジェクト)

Sub Example_Workbook()
    Dim wb As Workbook
    Set wb = Workbooks.Open("C:\Temp\sample.xlsx")

    MsgBox "シート数: " & wb.Worksheets.Count

    wb.Close SaveChanges:=False
    Set wb = Nothing
End Sub
VB
  • 外部のブックを開くときも Set で参照を持ちます。

4. Object 型と早期バインド / 遅延バインド(少しだけ中級)

  • Dim obj As Object と宣言すると、どんな種類のオブジェクトでも入れられます(遅延バインド)。柔軟ですが、補完(IntelliSense)が効かず実行時エラーになりやすい。
  • Dim ws As Worksheet のように具体的な型で宣言するのが安全(早期バインド)。補完が効き、ミスに気づきやすい。
  • 外部ライブラリ(例:Scripting.FileSystemObject)を使うときは、参照を追加して早期バインドで使うか、As ObjectCreateObject(...)で遅延バインドにする方法があります。

例:遅延バインドでDictionaryを使う(参照設定不要)

Sub Example_Dictionary()
    Dim dict As Object
    Set dict = CreateObject("Scripting.Dictionary")
    dict.Add "A", 1
    MsgBox dict("A")
    Set dict = Nothing
End Sub
VB

5. Set を忘れたときの典型エラーと対処法

  • エラー内容オブジェクト変数または With ブロック変数が設定されていません(Run-time error ’91’)
  • 原因Set を使わずにオブジェクトを代入した、あるいは変数に何も入っていない(Nothing)のままプロパティにアクセスした、など。
  • 対処
    • オブジェクト変数に代入する箇所を探し Set があるか確認する。
    • 値が Nothing かどうかを If Not obj Is Nothing Then でチェックする。
If Not r Is Nothing Then
    Debug.Print r.Value
Else
    Debug.Print "r is nothing"
End If
VB

6. 後片付け(Set ... = Nothing)は必要?

  • 小規模マクロでは省略してもたいてい問題ありません(VBAのガベージコレクションが働くため)。
  • しかし、外部ブックや大量のオブジェクトを扱うときは、明示的に Set obj = Nothing をして参照を切るのが安全です(Excelがブックを閉じられない等の不具合を防ぐ)。

7. With ブロックとの組み合わせ(便利)

With を使うと同じオブジェクトに対する複数操作を簡潔に書けます:

Sub Example_With()
    Dim r As Range
    Set r = ThisWorkbook.Worksheets("Sheet1").Range("C3")

    With r
        .Value = "合計"
        .Offset(0, 1).Value = 100
        .Font.Italic = True
    End With

    Set r = Nothing
End Sub
VB

8. 実践的な例題(初心者向け、手を動かそう)

練習問題1 — セルを参照して値を加算する

シート “Sheet1” の A1 と A2 の値を足して A3 に書くマクロを書け(オブジェクト変数を使うこと)。

解答例

Sub Task1_AddCells()
    Dim ws As Worksheet
    Dim r1 As Range, r2 As Range, rOut As Range

    Set ws = ThisWorkbook.Worksheets("Sheet1")
    Set r1 = ws.Range("A1")
    Set r2 = ws.Range("A2")
    Set rOut = ws.Range("A3")

    rOut.Value = Val(r1.Value) + Val(r2.Value)

    Set r1 = Nothing: Set r2 = Nothing: Set rOut = Nothing: Set ws = Nothing
End Sub
VB

練習問題2 — 空セルの検査

“Sheet1” の列Bの1〜10行を調べ、空のセルがあれば赤で塗る(Range オブジェクトを使うこと)。

解答例

Sub Task2_HighlightEmpty()
    Dim ws As Worksheet
    Dim r As Range
    Dim i As Long

    Set ws = ThisWorkbook.Worksheets("Sheet1")

    For i = 1 To 10
        Set r = ws.Cells(i, "B")
        If Trim(r.Value & "") = "" Then
            r.Interior.ColorIndex = 3 ' 赤
        Else
            r.Interior.ColorIndex = xlNone
        End If
    Next i

    Set r = Nothing: Set ws = Nothing
End Sub
VB

9. 便利なチェックリスト(コーディング時)

  • Option Explicit をモジュールの先頭に書いて変数宣言を強制する。
  • オブジェクト変数には 必ず Set を使う。
  • 使い終わったら Set obj = Nothing で参照を切る(特に外部ブックやライブラリを使ったら)。
  • Dim はできるだけ具体的な型で(例:Worksheet, Range, Workbook)。
  • 実行時エラーが出たらエラー行を確認し、変数に Nothing が入っていないかチェック。

10. よくある質問(FAQ)

Q
Set を使わないと何が起きる?
A

エラーが出るか、意図しない挙動になります(オブジェクト参照が設定されない)。

Q
Variant でもオブジェクトを扱える?
A

はい。ただし Variant は柔軟すぎてミスを見逃しやすい。As Range 等、具体型が推奨。

Q
Set obj = Nothing を毎回書かないとダメ?
A

小さなスクリプトは大丈夫なことが多いが、他ブックの自動操作や長時間動く処理では明示的にクリアするのが安全。

VBA
スポンサーリンク
シェアする
@lifehackerをフォローする
スポンサーリンク
タイトルとURLをコピーしました