TL;DR — VBA では、オブジェクトの代入に素の
=ではなくSetを使います。オブジェクト変数は 参照 — 実体を指し示すラベル — なので、Set ws = Worksheets("Data")はそのラベルをシートへ向けま す。Setを忘れると VBA は 実行時エラー 91、Object variable or With block variable not set を発 生させます。オブジェクトでないものにSetを使うと 実行時エラー 424、Object required が出ます。 値(Integer・String・Double)は=でコピーし、オブジェクトはSetで指し示します。
Sub ObjectsNeedSet()
Dim ws As Worksheet
Set ws = ThisWorkbook.Worksheets("Data") ' Set = ラベルをシートに向ける
ws.Range("A1").Value = 100 ' これで ws は実体を指す - だから動く
Dim total As Double
total = ws.Range("A1").Value ' 値は = を使う、Set は不要
End Sub
Set はオブジェクトのライフサイクルの要です。オブジェクトを New で作り、Set で
変数をそこへ向け、Nothing で解放します。Set を間違えれば、VBA 開発者が誰し
も最初に出会う二つのエラー — 91 と 424 — にぶつかります。だからこそ、オブジェクトに なぜ それが要る
のかを理解しておく価値があるのです。
この記事で学べること
- 考え方の軸 — オブジェクト変数は、コピーを入れる 箱 ではなく、参照(ラベル)である
- どれに
Setが要り(Range・Worksheet・Workbook・Dictionary)、どれに要らないか(Integer・String) - 第一の罠 —
Setの付け忘れで起きる実行時エラー 91、Object variable or With block variable not set - 実行時エラー 424、Object required、そしてそれが 91 とどう違うか
- なぜ
Set b = aは、コピーではなく 同じ 実体に二つの名前を付けるのか
考え方の軸:参照であって、箱ではない
値の変数は箱です。Dim n As Long: n = 5 は、数値 5 を n の中に入れます。m = n でコピーすれば
m は自分専用の 5 を持ち、m を変えても n はそのままです。単純ですね。
オブジェクトの変数は箱ではありません — ラベル です。Dim ws As Worksheet は、今はどのシートも指し
ていない空のラベルを作ります。Set ws = Worksheets("Data") は、ワークシートを ws の中にコピーするの
ではなく、既存のシート を ラベルに指し示させます。それこそが Set の存在理由です。オブジェクトの代入
は 指し示す という行為であり、VBA はそれを声に出して言わせるのです。
Dim ws As Worksheet
ws = Worksheets("Data") ' 誤り - Set がない - 実行時エラー 91
Set ws = Worksheets("Data") ' 正しい - ラベルがシートを指すようになる
この一文さえ押さえれば、あとはすべてそこから導かれます。値は = でコピーし、オブジェクトは Set で
指し示す。 これから挙げる二つの実行時エラーは、どちらも「ラベルをうまく指し示せなかった」と VBA が告
げているだけなのです。
第一の罠:実行時エラー 91
91 は、そのフルネーム — Object variable or With block variable not set — で人々を検索へ走らせるエラ
ーです。今は何も指していないオブジェクト変数を使ってしまった、という意味です。原因は二つあり、どちらも
Set の付け忘れに行き着きます。
一つめ。オブジェクトを宣言したものの一度も Set していないため、まだ Nothing のまま、それを使ってし
まった場合です。
Dim ws As Worksheet
ws.Range("A1").Value = 1 ' 実行時エラー 91 - ws は一度も Set されておらず、何も指していない
二つめ — こちらが厄介です — シートを代入するつもりは あった のに、Set を忘れた場合です。
Dim ws As Worksheet
ws = ThisWorkbook.Worksheets("Data") ' 実行時エラー 91 - 素の = ではオブジェクトのラベルを指せない
どちらも直し方は同じ一語です。Set ws = ThisWorkbook.Worksheets("Data")。Object variable or With
block variable not set を見たら、最初に問うべきはいつも同じです。このオブジェクトを Set したか、そ
して Set した先は本当に存在していたか? (もう一つの定番は、Nothing を返
す Find や検索です — 変数は 確かに Set されている、ただし Nothing に、それをそのまま使ってしまった、
というわけです。)
実行時エラー 424:Object required
424、Object required は、91 の裏返しです。91 が「空のオブジェクトの枠を使ってしまった」なら、424 は
「オブジェクトでは まったくない ものに Set(あるいはオブジェクトの構文)を使ってしまった」です。
Dim n As Long
Set n = 5 ' 実行時エラー 424 - 5 は値、Set はオブジェクトを求める
Set n = Range("A1").Value ' 実行時エラー 424 - .Value は数値であってオブジェクトではない
左辺の Set は、右辺にオブジェクトを要求します。数値や文字列、あるいは値を返すプロパティを渡せば、VBA
は Object required と言います。素の変数にオブジェクトの構文を使ったときにも 424 は出ます — x が
String なのに x.Cells(1, 1) と書いた場合や、綴りを間違えた変数名を VBA が黙って空の Variant とし
て扱った場合です。目安はこうです。91 は「まず Set せよ」、424 は「それはオブジェクトではない、Set を外
せ(または右辺を直せ)」。
Set はコピーではなく別名を作る
Set はコピーではなく指し示すので、二つのオブジェクト変数が 同じ 実体を指してしまうことがあります —
そして一方を通して書き込むと、もう一方から見える中身も変わります。
Dim a As Range, b As Range
Set a = Range("A1:B2")
Set b = a ' b は a と同じ range を指す - コピーではない
b.ClearContents ' これは a も消す。a と b は同一の range だから
値と比べてみましょう。こちらではコピーが本当にコピーです。
Dim x As Long, y As Long
x = 5: y = x ' y は自分専用の 5 を持つ
y = 9 ' x はまだ 5 - それぞれ独立した箱
この別名づけはバグではありません。参照の狙いそのものであり、オブジェクトを受け渡すのが軽い理由でもあり
ます(渡すのはラベルだけで、シート全体ではありません)。ただしこれは、「range を別の変数にコピーして編集
した」つもりが、静かに元を編集してしまう、ということでもあります。データ を複製したいなら、参照ではな
くセルをコピーしましょう(a.Copy)。
Set と Let
実は VBA には、値のための対になるキーワード Let があります。Let n = 5 は n = 5 と同じ — Let は
省略可能で、いまや誰も書かないため、値の代入は素の = に見えます。オブジェクトには、こうした近道があり
ません。Set は必須で、決して省けないのです。この非対称さこそ、Set の付け忘れがこれほど起きやすい理由
です — マクロの中のほかの代入はすべて素の = なのに、オブジェクトだけが、それでは足りない唯一の場所な
のですから。
ExcelMaster の活用
Set をめぐる話はすべて、代入のたびに下す一つの判断に尽きます — これはコピーする値か、それとも指し示す
オブジェクトか? — そして間違えれば、91 や 424 で派手に、あるいは思いがけない別名で静かに、失敗します。
ExcelMaster には、やりたいことをそのま
ま伝えられます — 「Data シートを取ってきて、最終行を見つけて、合計を書き込んで」 — すると、Set が要る
場所にはオブジェクト参照を Set で書き、各変数を正しい型で宣言し、Nothing を返しうる検索は結果に触れ
る前に守るので、実行時エラー 91 があなたのところへ届くことはありません。ブックとコードはあなたの手元に
残ります。
よくある質問
VBA の Set は何をするのですか?
Set はオブジェクト変数に参照を代入します — Range・Worksheet・Workbook・Dictionary といった実
体へ変数を向けるのです。値をコピーする素の = とは違い、Set はオブジェクトをコピーせず、既存のオブジ
ェクトを変数に参照させます。オブジェクトには Set が要り、値(Integer・String・Double)には要り
ません。
Object variable or With block variable not set と表示されるのはなぜですか?
それは実行時エラー 91 で、何も指していないオブジェクト変数を使った、という意味です。たいていは Dim で
宣言したものの Set で代入していない、Set の代わりに素の = を書いた(素の = ではオブジェクト変数
を指せません)、あるいは代入した相手 — たとえば Find の結果 — が Nothing を
返した、のいずれかです。Set を加え、代入するオブジェクトが本当に存在するかを確かめましょう。
実行時エラー 91 と 424 の違いは?
実行時エラー 91、Object variable or With block variable not set は、今 Nothing のオブジェクト変数を
使ったという意味で、直し方はまず Set することです。実行時エラー 424、Object required は、オブジェク
トでないものに Set(あるいはオブジェクトの構文)を使った — たとえば Set n = 5 — という意味なので、
直し方は Set を外すか、右辺に本物のオブジェクトを置くことです。
String や Integer にも Set は必要ですか?
いいえ。String・Integer・Long・Double・Boolean・Date などの値型は、参照ではなくコピーされる
ので、素の = で代入します。Set はオブジェクト型のためだけのものです。値に Set を使うと、実行時エラ
ー 424、Object required が発生します。
Set はオブジェクトをコピーしますか?
いいえ — Set は変数を既存のオブジェクトへ向けます。Set b = a は 同じ 実体を参照する二つの変数を与
えるので、b を通した変更は a からも見えます。元のデータを複製したいなら(たとえば range の場合)、参
照ではなくセルを a.Copy でコピーしましょう。
検証環境
動作確認: Excel 365 (Windows 11), VBA 7.1 — 最終確認 2026-09-19.
関連ガイド: VBA New · VBA Nothing · VBA Dim · VBA CreateObject · VBA With
