VBAテクニック集 VBA一覧 オブジェクト変数 文法・構文

【VBA】オブジェクト変数とは?宣言・Setの使い方と参照の仕組みを解説

VBAでは、数値や文字列を変数に格納するだけでなく、セルやワークシート、ブックなどの「オブジェクト」を変数として扱うことができます。

このとき使用するのが「オブジェクト変数」です。

オブジェクト変数を利用すると、同じシートやセル範囲を何度も指定する必要がなくなり、コードを読みやすく整理できます。一方で、通常の変数と同じ感覚で代入しようとすると、エラーが発生したり、意図したオブジェクトを参照できなかったりすることがあります。

特にVBAを学び始めた段階では、「Rangeも変数に入れられるの?」「なぜSetが必要なの?」「Object型とWorksheet型は何が違うの?」と混乱しやすい部分です。

この記事では、VBAにおけるオブジェクト変数の基本から、宣言方法、Setを使った参照の設定、通常の変数との違いまでを実務で扱いやすい形で解説します。

✅ VBAのオブジェクト変数とは?

VBAのオブジェクト変数を理解するときに最初につまずきやすいのが、「変数の中にシートそのものが保存されている」と考えてしまうことです。実際には、オブジェクト変数は対象となるオブジェクトを扱うための「参照」を保持します。この違いを曖昧なままにすると、SetやNothingを使う理由も分かりにくくなります。

また、数値や文字列を扱う通常の変数と同じ感覚でコードを書くと、思わぬエラーにつながります。実務ではWorksheetやWorkbook、Rangeなどを変数に格納する機会が多いため、基本的な仕組みを早い段階で押さえておくことが重要です。まずは通常の変数との違いから整理していきましょう。

・オブジェクト変数が保持しているもの

VBAでは、Excelを構成するさまざまな要素がオブジェクトとして扱われています。

代表的なものには、次のようなオブジェクトがあります。

  • Workbook:Excelブック
  • Worksheet:ワークシート
  • Range:セルやセル範囲

たとえば、特定のワークシートを何度も操作する場合、そのワークシートへの参照をオブジェクト変数に設定できます。

Dim targetSheet As Worksheet

Set targetSheet = ThisWorkbook.Worksheets("売上")

ここでは、targetSheetというWorksheet型のオブジェクト変数を宣言し、「売上」シートへの参照を設定しています。

その後は、

targetSheet.Range("A1").Value = "商品名"

のように、Worksheets("売上")を何度も記述せずに対象シートを操作できます。

コードが短くなることだけがメリットではありません。

「どのシートを操作しているのか」が変数名から分かるため、処理の意図を読み取りやすくなる点が実務では特に重要です。

・通常の変数とオブジェクト変数の違い

通常の変数では、文字列や数値などの「値」を格納します。

Dim customerName As String
Dim salesAmount As Long

customerName = "株式会社ABC"
salesAmount = 100000

一方、オブジェクト変数では、WorkbookやWorksheet、Rangeなどのオブジェクトへの参照を保持します。

Dim targetRange As Range

Set targetRange = ThisWorkbook.Worksheets("売上").Range("A1:C10")

この違いは、オブジェクト変数を理解するうえで非常に重要です。

targetRangeにA1のセルの値をコピーしているわけではありません。

A1というRangeオブジェクトを参照できる状態にしています。

そのため、

targetRange.ClearContents

とすれば、実際に参照しているA1の内容が削除されます。

「データそのものを変数へコピーする」のではなく、「操作対象を変数から参照できるようにする」と考えると理解しやすくなります。


✅ VBAでオブジェクト変数を宣言する基本

オブジェクト変数は、何でもObject型にすればよいわけではありません。初心者のうちはAs Objectでまとめたほうが簡単に見えますが、実務では対象が明確なら具体的な型を指定したほうがコードを管理しやすくなります。型を適切に指定すると、変数が何を表しているのかコードだけでも判断しやすくなります。

また、VBEの入力支援を利用できるため、プロパティやメソッドを確認しながら実装できます。反対に型の選び方を曖昧にすると、コード量が増えたときに変数の役割を追いにくくなります。オブジェクト変数では、宣言時の「型」と「変数名」の両方を意識することが大切です。

・Worksheet型のオブジェクト変数を宣言する方法

ワークシートを扱う場合は、次のようにWorksheet型として宣言できます。

Dim targetSheet As Worksheet

ただし、宣言しただけでは操作対象となるシートは設定されていません。

次のようにSetを使用して参照先を設定します。

Dim targetSheet As Worksheet

Set targetSheet = ThisWorkbook.Worksheets("売上")

実際の処理では、次のように利用できます。

Dim targetSheet As Worksheet

'操作対象となるワークシートを明示的に設定する
Set targetSheet = ThisWorkbook.Worksheets("売上")

'設定したワークシートを基準にセルを操作する
targetSheet.Range("A1").Value = "商品名"
targetSheet.Range("B1").Value = "数量"
targetSheet.Range("C1").Value = "金額"

この書き方では、処理対象を最初にtargetSheetへ設定しています。

各行で、

ThisWorkbook.Worksheets("売上").Range(...)

と繰り返す方法もありますが、対象シートを変数にまとめておけば、後からシートを変更する場合も修正箇所を減らせます。

特に処理が長くなるほど、オブジェクト変数を使うメリットが大きくなります。

・Range型のオブジェクト変数を宣言する方法

セル範囲もオブジェクト変数として扱えます。

たとえば、売上データの入力範囲を変数として保持する場合は次のように記述できます。

Dim targetSheet As Worksheet
Dim salesRange As Range

'処理対象のシートを設定する
Set targetSheet = ThisWorkbook.Worksheets("売上")

'対象シート内のデータ範囲を設定する
Set salesRange = targetSheet.Range("A2:C100")

'対象範囲をまとめてクリアする
salesRange.ClearContents

ここでは、

  1. targetSheetをWorksheet型として宣言する
  2. salesRangeをRange型として宣言する
  3. targetSheetへ「売上」シートの参照を設定する
  4. salesRangeへA2の参照を設定する
  5. salesRangeを通して対象範囲を操作する

という流れになっています。

このように処理対象を段階的にオブジェクト変数へ設定すると、「どのブック・どのシート・どの範囲を操作しているのか」が分かりやすくなります。

実務では処理対象の取り違えが不具合につながることも多いため、単にコードを短くするためではなく、操作対象を明確にする目的でオブジェクト変数を利用することが重要です。

Rangeオブジェクトの作成方法や、セル範囲を指定するさまざまな書き方については「【VBA】Rangeオブジェクトを作成する方法|セル範囲を自在に操作する基礎と応用」で詳しく解説しています。


✅ VBAのオブジェクト変数でSetを使う理由

オブジェクト変数で特に混乱しやすいのが、代入時にSetが登場する点です。StringやLongなどではSetを使わないため、「なぜオブジェクトだけ必要なのか」と疑問に感じやすい部分でしょう。ここを単なるVBAの決まりとして暗記すると、後でValueプロパティなどが絡んだコードを読んだときに混乱しやすくなります。

さらに、Setを書き忘れることでエラーになるケースもあります。重要なのは、通常の値の代入とオブジェクトへの参照設定を区別することです。両者の違いが分かれば、Setを使う場面も判断しやすくなります。

・Setでオブジェクトへの参照を設定する

通常の変数への代入では、次のように記述します。

Dim salesAmount As Long

salesAmount = 100000

一方、オブジェクト変数へオブジェクトの参照を設定する場合はSetを使用します。

Dim targetSheet As Worksheet

Set targetSheet = ThisWorkbook.Worksheets("売上")

実務では、Setを単に「オブジェクト変数につける命令」と暗記するより、

値を代入しているのか、オブジェクトへの参照を設定しているのか

を意識すると理解しやすくなります。

たとえば、Rangeを使った次の2つのコードは似ていますが、意味が異なります。

Dim cellValue As String
Dim targetCell As Range

cellValue = Range("A1").Value
Set targetCell = Range("A1")

cellValueにはA1セルの「値」を代入しています。

一方、targetCellにはA1セルを表すRangeオブジェクトへの「参照」を設定しています。

この違いを理解することが、オブジェクト変数を正しく扱う第一歩です。

なお、Setそのものの仕組みや、オブジェクト変数を使った具体的な設計方法まで一度に覚えようとすると、かえって混乱しやすくなります。

まずは、

オブジェクト変数を宣言する → Setで参照先を設定する → 変数を通してオブジェクトを操作する

という基本の流れを押さえておくとよいでしょう。

オブジェクト変数への参照設定で使用するSetについて、基本構文や参照の仕組みから整理したい場合は「【VBA】Setとは?オブジェクト変数の基本と参照の仕組み」もあわせて確認してみてください。


✅ VBAでオブジェクト変数を活用する実務的な使い方

短いマクロでは、オブジェクト変数を使わなくても処理を書けることがあります。しかし、処理するブックやシート、セル範囲が増えてくると、対象を直接指定するコードばかりでは読みづらくなります。さらに、似た名前のシートを扱う処理では、参照先を間違えることで別のシートを書き換えてしまう可能性もあります。

実務では「コードを短くできるから」という理由だけでオブジェクト変数を使うわけではありません。操作対象を明確にし、後からコードを読んだ人が処理を追いやすくすることも大きな目的です。特に複数のWorkbookやWorksheetを扱う場合は、オブジェクト変数を適切に設定することで処理対象を整理できます。

・Workbook・Worksheet・Rangeを変数で管理する方法

実務では、Workbook、Worksheet、Rangeを組み合わせて処理することがあります。

たとえば、現在のブックにある「売上」シートのデータ範囲を取得する場合は、次のように記述できます。

Dim targetBook As Workbook
Dim targetSheet As Worksheet
Dim dataRange As Range
Dim lastRow As Long

'処理対象となるブックとシートを明確にする
Set targetBook = ThisWorkbook
Set targetSheet = targetBook.Worksheets("売上")

'データが入力されている最終行を取得する
lastRow = targetSheet.Cells(targetSheet.Rows.Count, "A").End(xlUp).Row

'実際に処理する範囲を設定する
Set dataRange = targetSheet.Range("A2:C" & lastRow)

'対象範囲の背景色を解除する
dataRange.Interior.Pattern = xlNone

処理の流れは次のとおりです。

  1. targetBookに処理対象のブックを設定する
  2. targetSheetに処理対象のシートを設定する
  3. A列を基準にデータの最終行を取得する
  4. dataRangeに実際の処理範囲を設定する
  5. dataRangeを使用してセル範囲を操作する

このようにブック、シート、セル範囲をそれぞれ意味の分かる変数に分けると、どのオブジェクトを操作しているのか判断しやすくなります。

たとえば後から「売上」ではなく「売上明細」シートを対象に変更することになっても、参照先を設定している部分を中心に修正できます。

実務では仕様変更や他の担当者による改修も考えられるため、単に処理を動かすだけでなく、変更箇所を見つけやすい構造にしておくことが重要です。

・同じオブジェクトを繰り返し使う処理で活用する

同じシートを何度も操作する場合も、オブジェクト変数が役立ちます。

たとえば、次のように毎回シートを指定することもできます。

ThisWorkbook.Worksheets("売上").Range("A1").Value = "商品名"
ThisWorkbook.Worksheets("売上").Range("B1").Value = "数量"
ThisWorkbook.Worksheets("売上").Range("C1").Value = "金額"

処理自体は分かりやすいものの、対象シートの指定が何度も繰り返されています。

オブジェクト変数を使えば、次のように整理できます。

Dim targetSheet As Worksheet

'以降の処理で使用するシートを最初に設定する
Set targetSheet = ThisWorkbook.Worksheets("売上")

targetSheet.Range("A1").Value = "商品名"
targetSheet.Range("B1").Value = "数量"
targetSheet.Range("C1").Value = "金額"

対象となるシートがtargetSheetに統一されるため、コードの意図を追いやすくなります。

ただし、短い処理まで無理に大量のオブジェクト変数へ分割すると、逆にコードが複雑になることがあります。

繰り返し使用する対象や、処理上の役割を明確にしたい対象を変数にするという考え方で使い分けるとよいでしょう。

Setを実際の処理でどのように使い分けるのか知りたい場合は「【VBA】Setのわかりやすい活用方法と活用場面」で、実務を想定した使い方を紹介しています。


 

✅ VBAのオブジェクト変数では具体的な型を使い分ける

VBAにはObjectという型があるため、「オブジェクト変数ならすべてAs Objectで宣言すればよい」と考えてしまうことがあります。しかし、Excel内の操作対象が最初から分かっている場合、必ずしもObject型を使う必要はありません。何を参照する変数なのか分からないコードは、後から見直したときの負担が大きくなります。

また、具体的な型を指定することで、VBEの入力支援を利用しながらコードを書きやすくなります。一方でObject型が適している場面もあるため、どちらか一方だけを使えばよいわけではありません。オブジェクト変数を実務で活用するなら、対象に応じて型を選ぶことが大切です。

・対象が決まっている場合は具体的な型を指定する

ワークシートを扱うことが分かっている場合は、

Dim targetSheet As Worksheet

セル範囲であれば、

Dim targetRange As Range

ブックであれば、

Dim targetBook As Workbook

のように具体的な型を指定できます。

変数名と型を見るだけでも、

Dim salesSheet As Worksheet
Dim salesRange As Range

なら「売上シート」と「売上データのセル範囲を扱う変数だろう」と推測しやすくなります。

これはコードが長くなるほど重要になります。

特に複数人でマクロを保守する環境では、作成者だけが理解できるコードではなく、別の担当者でも変数の役割を追えるようにしておくことが大切です。

・Object型は必要な場面を判断して使用する

オブジェクト変数は、次のようにObject型として宣言することもできます。

Dim targetObject As Object

ただし、Worksheetを扱うことが最初から分かっているにもかかわらず、すべてObject型に統一する必要はありません。

Dim targetSheet As Worksheet

のように具体的な型を指定したほうが、コード上でも用途が明確になります。

一方で、処理の設計によってはObject型を利用したほうが柔軟に扱えるケースもあります。

重要なのは、

「オブジェクトだからObject型にする」のではなく、どの種類のオブジェクトを扱う変数なのかを考えて型を選択すること

です。

Object型そのものの特徴や具体的な使い分けについては別途理解しておくと、オブジェクト変数をより柔軟に扱えるようになります。

WorksheetやRangeなどの具体的な型とObject型の違いをさらに詳しく知りたい場合は「【VBA】オブジェクト型(Object 型)とは?使い方と注意点」も参考にしてください。


✅ VBAでオブジェクト変数を使うときの注意点

オブジェクト変数は便利ですが、宣言しただけでは対象のオブジェクトを操作できません。また、参照先が設定されていると思い込んで処理を進めると、実行時エラーにつながることがあります。特に長い処理では、どのタイミングで参照を設定したのか分からなくなるケースがあります。

さらに、複数のブックを扱うマクロでは、ActiveWorkbookやActiveSheetに依存すると想定外の対象を操作する危険性があります。オブジェクト変数を利用すること自体が安全性を保証するわけではなく、参照先を明確にする設計とセットで考える必要があります。実務では、変数の宣言だけでなく「いつ・何を設定するのか」まで分かるコードを意識しましょう。

・宣言しただけのオブジェクト変数は使用しない

次のコードではWorksheet型の変数を宣言しています。

Dim targetSheet As Worksheet

しかし、この時点ではtargetSheetに具体的なWorksheetへの参照は設定されていません。

その状態で、

targetSheet.Range("A1").Value = "テスト"

のような処理を実行すると、正常に操作できません。

使用する前に、

Set targetSheet = ThisWorkbook.Worksheets("売上")

のように参照先を設定する必要があります。

そのため実務では、宣言部分だけを見るのではなく、Setによってどこで参照先が設定されているかを確認することが重要です。

・ActiveSheetに依存しすぎないようにする

たとえば、

Set targetRange = Range("A1:C10")

というコードでは、どのシートのA1なのかがコードから明確ではありません。

処理中に別のシートがアクティブになれば、想定していないセル範囲を参照する原因にもなります。

実務では可能な限り、

Dim targetSheet As Worksheet
Dim targetRange As Range

Set targetSheet = ThisWorkbook.Worksheets("売上")
Set targetRange = targetSheet.Range("A1:C10")

のように、親となるオブジェクトを明示すると安全です。

オブジェクト変数のメリットはコードを省略できることだけではなく、「何を操作しているのか」を固定して明確にできることにもあります。

・不要になった参照とNothingの関係を理解する

オブジェクト変数にはNothingという状態があります。

たとえば、

Set targetSheet = Nothing

とすると、targetSheetが保持していたオブジェクトへの参照を解除できます。

ただし、オブジェクト変数を使ったら何でも機械的に最後へSet ~ = Nothingを書けばよい、と覚える必要はありません。

重要なのは、Nothingが「シートを削除する」「セルを消去する」といった命令ではなく、オブジェクト変数が参照している対象との関係を理解するための概念だということです。

参照が設定されているかを判定する処理などでもNothingは重要になるため、オブジェクト変数の扱いに慣れてきたら、参照の初期化や判定方法も合わせて理解しておくとよいでしょう。

Nothingによる参照の解除や、オブジェクト変数がNothingかどうかを確認する考え方については「【VBA】Nothingとは?オブジェクト変数の初期化と解放をわかりやすく解説」で詳しく解説しています。


✅ VBAのオブジェクト変数を使いやすいコードにするポイント

オブジェクト変数を使えば、自動的に読みやすいコードになるわけではありません。変数名がobj1やws1ばかりでは、処理が長くなったときに役割を判断しづらくなります。また、必要以上に多くのオブジェクトを変数化すると、どの変数がどの参照を持っているのか追跡する作業が増えてしまいます。

実務ではコードを書く時間だけでなく、数か月後に修正する時間まで考える必要があります。別の担当者が改修する可能性がある場合は、なおさら意図が伝わる構成が重要です。オブジェクト変数は、処理対象を整理するための道具として適切な粒度で利用しましょう。

・役割が分かる変数名を付ける

たとえば、

Dim ws As Worksheet
Dim rng As Range

という名前でも処理できます。

しかし、複数のシートやRangeを扱う処理では、

Dim sourceSheet As Worksheet
Dim destinationSheet As Worksheet
Dim sourceRange As Range

のように役割まで分かる名前にすると、コードを読みやすくできます。

たとえば、

Dim sourceSheet As Worksheet
Dim destinationSheet As Worksheet

'転記元と転記先を明確に分けて管理する
Set sourceSheet = ThisWorkbook.Worksheets("売上")
Set destinationSheet = ThisWorkbook.Worksheets("集計")

sourceSheet.Range("A2:C10").Copy _
    Destination:=destinationSheet.Range("A2")

とすれば、どちらが転記元でどちらが転記先なのかを変数名から判断できます。

特に業務マクロでは、コードを書いた本人以外が保守する可能性もあります。

そのため、変数名を短くすることよりも、何を参照している変数なのかが分かることを優先すると保守しやすくなります。


 

✅ まとめ:VBAのオブジェクト変数を理解して処理対象を明確にしよう

VBAのオブジェクト変数は、WorksheetやWorkbook、Rangeなどを扱ううえで欠かせない基本要素です。しかし、「Setを付ければ使える」という書き方だけを覚えてしまうと、通常の変数との違いやNothingの意味が分からなくなりやすい部分でもあります。重要なのは、オブジェクト変数が対象となるオブジェクトへの参照を保持していることを理解することです。

また、実務では具体的な型や分かりやすい変数名を使用することで、処理対象を明確にできます。コードが長くなったときや複数のシートを扱うときほど、この設計が保守性に影響します。基本的な仕組みを理解したうえで、SetやNothingなど周辺の知識へ広げていくとよいでしょう。

  • オブジェクト変数はWorkbook、Worksheet、Rangeなどへの参照を保持する
  • 通常の値の代入と、オブジェクトへの参照設定は意味が異なる
  • オブジェクトへの参照を設定するときはSetを使用する
  • 対象が明確ならWorksheetやRangeなど具体的な型を指定する
  • ブック・シート・セル範囲を変数化すると処理対象を明確にできる
  • ActiveSheetなどに依存しすぎず、親となるオブジェクトを明示する
  • 変数名は処理上の役割が分かる名前にすると保守しやすい
  • Nothingはオブジェクト変数の参照状態を理解するうえで重要になる

オブジェクト変数を使いこなせるようになると、単にVBAコードを短くするだけでなく、「どのブックの、どのシートの、どの範囲を操作するのか」を整理して記述できるようになります。

まずはWorksheetやRangeなど身近なオブジェクトから変数に設定し、参照先を明確にする書き方を身につけていきましょう。

    -VBAテクニック集, VBA一覧, オブジェクト変数, 文法・構文