【入門編】Variant型変数に格納されたオブジェクトの型判定:TypeOfとTypeNameの使い分け – Excel VBA解析バイブル

スポンサーリンク

こんにちは!マクロの記録を卒業して、いよいよ本格的なVBAの自動化に挑んでいるあなたへ。

Excel VBAを書いていると、「いま、この変数の中にはいったい何が入っているんだ…?」と頭を抱えたくなる瞬間がやってきますよね。特に、何でも入れられる万能の箱である `Variant` 型(VBAで型を明示しないと、デフォルトでこれになります)を使っていると、シートなのか、セルなのか、グラフなのか、それともただの文字列なのか分からなくなりがちです。

今回は、そんな動的なオブジェクトの正体を暴き、実行時エラー(「オブジェクトが必要です」という冷酷なエラーメッセージです!)を華麗に回避するための極意をお伝えします。

ここをクリアすれば、あなたのVBAコードは一段と頑丈でプロっぽい仕上がりになりますよ。さあ、一緒に扉を開けましょう!

1. なぜVariant型とオブジェクトの型判定で悩むのか?

VBAでは、変数を宣言するときに `Dim x As Variant`(または単に `Dim x`)とすると、数値を入れようが、文字を入れようが、Excelのセル(Range)やワークシート(Worksheet)を入れようが、すべて受け入れてくれます。

Dim x As Variant
Set x = Selection ‘ 選択しているセル範囲を入れたり…
Set x = ActiveSheet ‘ アクティブなシートに入れ替えたり…

便利ですよね。しかし、この「何でも入る」という特性が裏目に出ることがあります。
例えば、ユーザーがセルを選択しているつもりが、何も選択していなかったり、図形をクリックしていたりした場合、そのまま処理を続行するとVBAは盛大にクラッシュします。

ここで重要になるのが、「処理を実行する前に、中身が何であるかを安全にチェックする技術」です。

2. 2つの強力な武器:`TypeName` と `TypeOf … Is`

VBAには、オブジェクトの型を調べるためのアプローチが2つあります。それぞれの特徴と使い分けをマスターしましょう。

① 文字列でズバリ教えてくれる! `TypeName関数`

`TypeName` は、変数の中身の「型名」を文字列(String)として返してくれる関数です。

  • 使い方: `TypeName(変数名)`
  • 戻り値の例: `”Range”`, `”Worksheet”`, `”Workbook”`, `”Nothing”`(何も入っていない場合)、あるいは `”String”` など

【イメージ図】

[ 変数 x ] ──(TypeNameへ)──> “Range” という文字列を返す!

② そのオブジェクトですか?と直接問う `TypeOf … Is演算子`

`TypeOf` は、そのオブジェクトが特定の型であるかどうかを True / False(真偽値) で判定する演算子です。こちらは `If` 文の条件式の中で使います。

  • 使い方: `If TypeOf 変数名 Is 型名 Then`
  • 注意点: `Variant` 型の変数や、特定のオブジェクト変数に対して使いますが、基本的には「オブジェクト」の判定に特化しています。

3. 【実戦】使い分けの極意とコード例

「じゃあ、どっちを使えばいいの?」という疑問がわきますよね。
結論から言うと、以下のように使い分けるのがプロの現場のスタンダードです。

  • `TypeName` が向いている場面: 変数が「何もない(Nothing)」状態なのか、それとも予期せぬデータ型(数値や文字列など)なのかを含めて、広く全般的に調べたいとき。
  • `TypeOf … Is` が向いている場面: 「このオブジェクトは確実に特定のオブジェクト(例:RangeやWorksheet)の仲間か?」をスマートに判定したいとき。

それでは、実務でそのまま使える安全設計のマクロを見てみましょう。

実用サンプルコード:選択中のオブジェクトを安全に料理する

以下のコードは、ユーザーがシート上で何を選択しているかを `TypeName` と `TypeOf` を使ってスマートに判別し、それぞれに応じたメッセージを表示するプログラムです。

Sub CheckObjecttypeSample()
Dim targetObj As Variant

‘ ユーザーが現在選択しているものを変数に代入
Set targetObj = Selection

‘ —————————————————-
‌【判定1】そもそも何も選択されていない、あるいは空っぽの場合
‘ —————————————————-
If TypeName(targetObj) = “Nothing” Then
MsgBox “何も選択されていません!”, vbExclamation
Exit Sub
End If

‘ —————————————————-
‌【判定2】TypeOf … Is を使ったスマートなオブジェクト判定
‘ —————————————————-
‘ 選択されているものが「セル範囲(Range)」であるか?
If TypeName(targetObj) = “Range” Then
MsgBox “セル範囲が選択されています。アドレス: ” & targetObj.Address, vbInformation

‘ 選択されているものが「図形(Shape)」であるか?
ElseIf TypeName(targetObj) = “DrawingObjects” Or TypeName(targetObj) = “Shape” Then
MsgBox “図形が選択されています。図形名: ” & targetObj.Name, vbInformation

‘ その他のオブジェクトや予期せぬ型の場合
Else
MsgBox “想定外のオブジェクトです。現在の型: ” & TypeName(targetObj), vbWarning
End If

End Sub

コードの解説とここがポイント!

1. `TypeName(targetObj) = “Nothing”` の安心感
オブジェクト変数が何も参照していない状態でプロパティにアクセスするとエラーになりますが、`TypeName` なら `”Nothing”` という文字列を返してくれるため、エラーを出さずに安全に回避できます。
2. 分岐の美しさ
「型が何か分からない恐怖」を `TypeName` で文字列化して確認することで、デバッグ(不具合探し)のときにも「今、何型になっているか?」がイミディエイトウィンドウなどで一目瞭然になります。

4. 初学者が陥りがちな「罠」

ここで、初心者がよくやってしまう失敗を一つご紹介します。

> ❌ やってしまいがちなミス
>
> Dim myCell As Range
> Set myCell = Selection
> ‘ ユーザーが図形を選んでいるのに、いきなりRangeに入れようとする
>
> これをやると、図形を選んだ瞬間に 「実行時エラー ’13’: 型が一致しません」 となり、マクロが強制終了してしまいます。

これを防ぐために、あえて変数を `Variant` にし、今回紹介した `TypeName` や `TypeOf` で「ガード(門番)」を置いてから処理を流すのが、エラーを出さない頑丈なマクロを作る最大のコツです。

まとめ

いかがでしたか?

  • `TypeName` は、変数の正体を文字列で暴く「万能チェッカー」。
  • `TypeOf … Is` は、特定のオブジェクトかどうかをスマートに問いかける「門番」。

この2つをシチュエーションに合わせて使い分けられるようになると、あなたの書くVBAコードの安全性は劇的に跳ね上がります。「エラーが出たらどうしよう…」という不安から解放され、自信を持ってコードを書けるようになりますよ。

ここをクリアしたあなたなら、もう「マクロの記録」だけの世界には戻れないはずです。
ぜひ、明日からの実務コードに取り入れてみてくださいね。応援しています!

タイトルとURLをコピーしました