Excel・VBA

Excel VBA実行時エラー13「型が一致しません」の原因と修正ポイント

Excel VBAの開発や運用中に突然発生する「実行時エラー13:型が一致しません(Type Mismatch)」は、プログラムが想定しているデータの形式と、実際に処理しようとしたデータの形式が異なるときに発生する代表的なエラーです。この記事では、プログラミング初心者の方でも迷わず解決できるように、エラーの原因特定方法から具体的な修正コード、さらにはエラーを未然に防ぐためのベストプラクティスまで、実務に役立つノウハウを網羅して詳しく解説します。

公開日:2026年7月8日 更新日:2026年7月8日
Excel VBA実行時エラー13「型が一致しません」の原因と修正ポイント
目次

この記事で分かること

  • 実行時エラー13「型が一致しません」が発生する根本的な原因と仕組み
  • エラーが発生した箇所を特定し、デバッグ機能を用いて原因を追究する手順
  • 実務でよくある4つの原因パターンと、それぞれの具体的な修正コード例
  • エラー値を安全に処理する関数や、開発時にエラーを防ぐためのプログラミング習慣

実行時エラー13「型が一致しません」の概要とデータ型の基礎知識

Excel VBAにおける「型が一致しません(Type Mismatch)」は、VBAが変数やプロパティ、関数の引数などにデータを格納しようとした際、受け取り側の「データ型」と渡されたデータの種類が一致しておらず、自動的な変換(キャスト)も行えなかった場合に発生するエラーです。VBAはプログラムを実行する際、メモリを効率的に使用し処理を正確に行うために、データの「型(種類)」を厳格に管理しています。この厳格な管理のルールから逸脱したデータ操作が行われた瞬間に、システムは処理を安全に中断し、実行時エラー13を報告します。

例えば、電話番号や金額などの「数値(Long型やDouble型)」を格納するために宣言した変数に対し、セルから取得した「未定」や「調整中」といった「文字列(String型)」を無理やり代入しようとした場合にこのエラーが発生します。まずは基本となるデータ型と、どのような操作を行うとエラー13の原因になりやすいのかを表で整理してみましょう。

データ型 格納できるデータの種類 エラー13が発生しやすいデータ・操作例
Integer / Long
(整数型 / 長整数型)
整数のみ(小数は自動的に丸められます) 「未定」「N/A」「-」などの文字列、または空白に見えるがスペースが含まれるセル値の代入。
Double
(倍精度浮動小数点数型)
実数(小数を含む数値全般) 数値として解釈できない「1,500円」のような単位付き文字列、またはセル内のエラー値(#VALUE!など)の代入。
Date
(日付型)
日付や時刻(例: 2023/10/01 12:00:00) 「2023.13.45」のような存在しない日付、または「未発送」などのテキストデータの代入。
Boolean
(論理型)
True(真)または False(偽) 「はい」「いいえ」「10」などの論理値として直接解釈できない日本語テキストの代入。
Variant
(バリアント型)
すべての種類のデータ(未定義時の初期値) 基本的には何でも入りますが、複数のセル(Rangeオブジェクト)を直接比較演算子「=」で比較しようとした際などにエラーが発生します。

このように、各データ型が受け入れられる範囲を超えたデータが入り込んだ瞬間に、エラー13は引き起こされます。VBAは一部の型において「暗黙の型変換(例えば、String型の “123” を Long型変数に代入すると自動で数値の 123 に変換してくれる機能)」を行ってくれますが、これに依存しすぎると予期せぬ文字の混入によって突然システムがクラッシュする原因となります。

実行時エラー13が発生する4つの代表的な原因

実務でマクロを使用している際、実行時エラー13が発生するシーンは大きく分けて以下の4つのパターンに分類されます。これらを頭に入れておくことで、エラーが発生した際の初期対応が非常にスムーズになります。

原因1:数値型や日付型の変数に不適切な文字列を代入した

最も典型的な原因です。プログラムの設計段階では「このセルには必ず売上金額(数値)が入る」と想定して、変数を Dim salesAmount As Long のように宣言していたとします。しかし、実際の業務で運用するExcelシートにおいて、担当者が金額の代わりに「未入力」や「計測不能」、あるいは「-(ハイフン)」と入力してしまうことがあります。この状態でマクロを実行すると、VBAは文字列を数値に変換できず、代入処理のタイミングで「型が一致しません」を発生させます。

原因2:セル内のエラー値(#N/A、#VALUE!、#DIV/0! など)を直接変数に取得した

Excelのセル内で数式がエラー(例えば、VLOOKUP関数が該当データを見つけられずに #N/A を返している状態や、ゼロ除算による #DIV/0! など)になっている場合、VBAでそのセルの値を直接変数に取得しようとするとエラーが発生します。セルの値がエラーになっている場合、セルの内部データは通常の「文字列」や「数値」ではなく、Excel固有の「エラー値(Errorオブジェクト)」として保持されています。これを String 型や Long 型などの通常の変数に代入しようとすると、型変換が行えないためエラー13が発生します。

原因3:オブジェクト変数への代入時に「Set」キーワードを忘れた

VBAでワークシート(Worksheet)やセル範囲(Range)などの「オブジェクト」を扱う場合、変数への代入には必ず Set キーワードを使用しなければなりません。例えば、Dim targetSheet As Worksheet と宣言した変数に対し、targetSheet = Sheets("売上データ") のように Set を省略して代入しようとすると、VBAは右辺のワークシートオブジェクトのデフォルト値(多くの場合、シートそのものではなくシート内のデータなどの評価値)を取得しようとし、結果として型が噛み合わずに「型が一致しません」のエラーになります。

原因4:複数セルの範囲(Range)を一度に比較・処理しようとした

特定のセル範囲が空欄かどうかを確認したいとき、If Range("A1:A10").Value = "" Then のようなコードを記述してしまうケースがあります。Range("A1:A10").Value のように複数セルを指定して .Value を取得すると、返される値は単一の値ではなく、セルの数に応じた「二次元配列」データとなります。配列データを、単一の文字列("")と直接 = で比較することはできないため、比較の瞬間にVBAは「型が一致しません」のエラーを出して停止します。

修正で済むか、作り直すべきか迷ったら

現状を確認し、修正・保守・刷新のどれが現実的かを整理します。

実行時エラー13を特定して解決するためのデバッグ手順

実際にエラーが発生してプログラムが停止してしまった場合、慌てずにどこに不具合があるのかを探るデバッグ手順を解説します。VBA開発においてデバッグスキルは、不具合解決のスピードを劇的に向上させる最も重要な要素です。

ステップ1:「デバッグ」ボタンをクリックしてエラー行を特定する

マクロ実行中に「実行時エラー13:型が一致しません」のダイアログウィンドウが表示されたら、まず「終了(E)」ではなく「デバッグ(D)」ボタンをクリックしてください。これにより、VBAのエディタ画面(VBE)が自動的に開き、エラーが発生してプログラムがストップしている該当のコードが黄色くハイライトされて表示されます。エラーの発生源はこの黄色い1行の中にあることが確定します。

ステップ2:変数の現在値とデータ型を確認する

エラーが発生している行が特定できたら、その行で使われている変数やオブジェクトに「現在どのようなデータが入っているか」を調査します。調査方法には以下の2つがあります。

  1. マウスホバーによる確認: 黄色くハイライトされた行に記述されている変数名の上に、マウスカーソルをそっと合わせます。データが入っていれば、ツールチップで 変数名 = "値" のように現在の値が表示されます。ここでセルのエラー値(Error 2042 など)や、想定外の文字列("未定" など)が入っていることが一目で確認できる場合があります。
  2. ローカルウィンドウの活用: VBEのメニューから「表示」→「ローカル ウィンドウ」を選択します。画面下部にローカルウィンドウが表示され、現在実行中のプロシージャ内で宣言されているすべての変数、その現在の「値(Value)」、および「型(Type)」がリアルタイムで一覧表示されます。ここで変数のデータ型と、実際に代入しようとしているデータの整合性を詳細にチェックできます。

ステップ3:イミディエイトウィンドウでセルの真の状態を調べる

セルの値が何であるかをより詳細に調べたい場合は、VBEの「イミディエイトウィンドウ」を使用します(Ctrl+Gキーで表示可能)。イミディエイトウィンドウに ? TypeName(Range("A1").Value) と入力してEnterキーを押すと、そのセルが現在どのようなデータ型として認識されているか(例:Double、String、Errorなど)を直接出力させることができます。また、? Range("A1").Value と打てば、実際の値を確認できます。これによって、見た目は空白なのに実は数式エラーや不要スペースが入っている、といった隠れた原因を暴き出すことができます。

【逆引き】原因別の具体的な修正コード例と解説

エラーの原因が特定できたら、それに応じた適切なコードの書き換えを行います。実務で頻出する3つのパターンについて、非推奨な「悪いコード例」と、エラーを安全に回避する「良いコード例」をセットでご紹介します。

パターンA:セルからの数値取得時に文字列の混入を回避する

セルに数値以外の情報が入力される可能性がある場合、事前にデータの種類をチェックする処理を挟みます。

【不具合が発生するコード例(悪い例)】

Sub ProcessSalesBad()
    Dim salesAmount As Long
    ' A1セルに「1,500円」や「未定」といった文字列が入力されていると、ここでエラー13が発生する
    salesAmount = Range("A1").Value
    MsgBox "売上は " & salesAmount & " 円です。"
End Sub

【エラーを回避する安全なコード例(良い例)】

Sub ProcessSalesGood()
    Dim rawValue As Variant
    rawValue = Range("A1").Value
    
    ' IsNumeric関数を使用して、値が数値として認識可能かどうかを判定する
    If IsNumeric(rawValue) Then
        Dim salesAmount As Long
        salesAmount = CLng(rawValue) ' 安全に明示的にLong型へ変換
        MsgBox "売上は " & salesAmount & " 円です。"
    Else
        ' 数値でない場合の適切なユーザー対応
        MsgBox "A1セルの値(" & rawValue & ")は数値ではありません。" & vbCrLf & _
               "数値を正しく入力してください。", vbExclamation, "入力エラー"
    End If
End Sub

解説: まず変数を何でも受け取れる Variant 型(rawValue)で受け取り、IsNumeric 関数を使って数値としての妥当性を評価します。数値であると判断できた場合のみ、明示的な型変換関数 CLng を用いて本来の数値型変数に格納するため、エラー13を完全にシャットアウトできます。

パターンB:セル内の数式エラー(#N/Aなど)によるクラッシュを防ぐ

Excelのセルに #N/A#VALUE! が出ている場合でも、システムが強制終了しないようにガードをかけます。

【不具合が発生するコード例(悪い例)】

Sub CheckStatusBad()
    Dim statusValue As String
    ' A1セルがエラー値の場合、String型の変数に格納しようとした時点でエラー13になる
    statusValue = Range("A1").Value
    If statusValue = "完了" Then
        MsgBox "処理は完了しています。"
    End If
End Sub

【エラーを回避する安全なコード例(良い例)】

Sub CheckStatusGood()
    Dim rawValue As Variant
    rawValue = Range("A1").Value
    
    ' IsError関数を使用して、セル自体がエラー値になっていないかを確認
    If IsError(rawValue) Then
        MsgBox "対象のセルに数式エラーが発生しています。シートの数式を確認してください。", vbCritical, "エラー検知"
        Exit Sub
    End If
    
    ' 安全であることが確認された後で、文字列として処理を行う
    If CStr(rawValue) = "完了" Then
        MsgBox "処理は完了しています。"
    Else
        MsgBox "処理は未完了です。"
    End If
End Sub

解説: IsError 関数は、値がExcelのエラー値(Errorオブジェクト)である場合に True を返します。先にこのチェックを行うことで、後続の文字列比較処理でエラーが発生するのを防ぎ、ユーザーにエラーの存在を優しく通知できます。

パターンC:複数セルの判定における二次元配列エラーを回避する

セル範囲を一括で処理したい場合は、適切な範囲操作を行うか、ループ処理を適用します。

【不具合が発生するコード例(悪い例)】

Sub CheckRangeBad()
    ' A1からA10のセル範囲がすべて空白かどうかを直接比較しようとしてエラー13が発生
    If Range("A1:A10").Value = "" Then
        MsgBox "すべて空欄です。"
    End If
End Sub

【エラーを回避する安全なコード例(良い例)】

Sub CheckRangeGood()
    Dim targetRange As Range
    Set targetRange = Range("A1:A10")
    
    ' ExcelのWorksheetFunction(COUNTBLANK)を活用してスマートに判定
    Dim blankCount As Long
    blankCount = WorksheetFunction.CountBlank(targetRange)
    
    If blankCount = targetRange.Cells.Count Then
        MsgBox "指定された範囲はすべて空欄です。", vbInformation
    Else
        MsgBox "範囲内に値が入力されているセルが " & (targetRange.Cells.Count - blankCount) & " 個あります。", vbInformation
    End If
End Sub

解説: 複数セル範囲のデータ(二次元配列)を直接文字列と比較することは不可能なため、Excelの組み込み関数である COUNTBLANK(指定範囲内の空白セルの数を数える)を利用します。範囲のセル総数と空白の数が一致すれば「すべて空欄」と安全かつ高速に判定できます。

エラー13を未然に防ぐための堅牢なコーディング習慣

エラーが発生してからデバッグするだけでなく、コードを書く段階から「エラーが絶対に発生しない、発生しても安全に制御できる」構造にしておくことが、プロのVBA開発において極めて重要です。以下の4つのアプローチを習慣化しましょう。

1. 「Option Explicit」を必ず記述し、変数の型宣言を徹底する

モジュールの最上部(先頭行)に必ず Option Explicit を記述してください。これにより、変数宣言を行っていない変数の使用が禁止され、コンパイル時にスペルミスなどのエラーを検知できます。VBEのメニュー「ツール」→「オプション」の「編集」タブ内にある「変数の宣言を強制する」にチェックを入れておくことで、新規モジュール作成時に自動でこの記述が挿入されるようになります。型を曖昧にせず、すべての変数に対して適切なデータ型(LongStringDate など)を明示的に宣言することが、バグを未然に防ぐ第一歩です。

2. 暗黙の型変換を排除し、明示的にキャスト関数を使う

VBAが良かれと思って裏で行う自動的な型変換(暗黙のキャスト)に依存していると、少しのデータのブレでシステムが止まります。データ型を変換する際は、開発者が明確な意図を持って型変換関数(キャスト関数)を記述してください。

  • CStr(値):値を明示的に文字列型(String)に変換する
  • CLng(値):値を明示的に長整数型(Long)に変換する
  • CDbl(値):値を明示的に浮動小数点数型(Double)に変換する
  • CDate(値):値を明示的に日付型(Date)に変換する

これらを使用することで、コードの可読性が高まると同時に、どの処理でどのような型変換が行われているのかが明確になり、メンテナンス性が飛躍的に向上します。

3. 予期しない事態に対応するエラーハンドリングを導入する

どれだけ厳密にデータチェックを実装していても、ユーザーが思いもよらない操作をすることは避けられません。プログラムが突然強制終了して「デバッグ」画面に入ってしまうと、一般ユーザーはパニックに陥ってしまいます。そのため、プロシージャの要所に On Error GoTo ErrorHandler などのエラーハンドリング構造を組み込みましょう。

Sub RobustProcedure()
    On Error GoTo ErrorHandler
    
    ' --- メインの処理 ---
    Dim dataVal As Long
    dataVal = CLng(Range("A1").Value)
    MsgBox "値は " & dataVal & " です。"
    
    Exit Sub ' メイン処理が正常終了した場合はここで抜ける

ErrorHandler:
    ' エラーが発生した場合の処理
    If Err.Number = 13 Then
        MsgBox "エラーが発生しました。" & vbCrLf & _
               "【原因】入力データの形式(型)が正しくありません。入力内容を見直してください。", _
               vbCritical, "実行時エラー13"
    Else
        MsgBox "想定外のエラーが発生しました。" & vbCrLf & _
               "エラー番号: " & Err.Number & vbCrLf & _
               "エラー内容: " & Err.Description, vbCritical, "システムエラー"
    End If
End Sub

このように構築しておけば、万が一エラー13が発生した場合でも、ユーザーに対して分かりやすい日本語で解決アクションを提示でき、業務の混乱を防ぐことができます。

修正で済むか、作り直すべきか迷ったら

現状を確認し、修正・保守・刷新のどれが現実的かを整理します。

よくある質問(FAQ)

「IsNumeric」関数は、全角の数字がセルに入っていても正しく数値として判定してくれますか?

はい、VBAの IsNumeric 関数は非常にスマートに作られており、全角で入力された「12345」のような数字も数値として認識し、True を返します。ただし、全角の数字をそのまま Long などの数値型変数に代入すると、VBAが暗黙的に半角数値へと自動変換して処理してくれますが、記号や特殊な文字、単位(例: 「100円」の「円」)などが混ざると数値として判定できなくなり(False を返す)、無理に代入しようとすればエラー13「型が一致しません」の原因になります。可能な限り、入力規制等を用いて半角数値のみを受け入れる設計にするか、代入前に不要な文字列を除去する処理を記述することをおすすめします。

すべての変数を「Variant」型で宣言すれば、エラー13を完全に防ぐことができますか?

いいえ、結論から申し上げますと、すべての変数を Variant(バリアント)型にしても実行時エラー13を防ぐことはできません。Variant型はどのようなデータでも格納できるため、変数にデータを代入する「最初の瞬間」における型ミスマッチによるエラーは回避できます。しかし、例えば「あいうえお」という文字列が格納されたVariant型変数 varData に対し、varData * 2 のような掛け算の計算を行おうとしたり、日付処理を行おうとしたりした段階で、やはりデータ形式としての計算が成り立たないため、エラー13が発生します。型を曖昧にすることは根本的な解決にならず、むしろバグの原因が隠蔽されてデバッグが困難になるため、極力具体的なデータ型を指定して開発を行うべきです。

セルの値が完全に「空欄(空白)」の場合、数値型変数に代入するとどうなりますか?

セルが完全に何も入力されていない「真の空白(Empty)」である場合、VBAの IntegerLongDouble といった数値型変数に代入すると、VBAはこれを自動的に「0」に変換して格納します。そのため、この場合はエラー13は発生しません。しかし、注意が必要なのは「数式によって ""(空文字)が出力されている場合」や「スペース(半角または全角)だけが入力されている場合」です。これらはVBA上では「長さ0の文字列」または「スペースという文字データ」として認識されるため、数値型変数に代入しようとした瞬間に「型が一致しません」のエラーが発生します。実務では、事前に Trim(セル値) = "" などのチェックを行うことで、このような見た目上の空白によるエラーを未然に防ぐことが可能です。

オブジェクト変数への代入で「Set」を忘れた場合、必ずエラー13になりますか?

Set キーキーワードを忘れた場合の挙動は、受け取る側の変数の「型宣言」によってエラー内容が変化します。もし Dim ws As Worksheet のように具体的なオブジェクト型で宣言していた場合、ws = Sheets(1) のように Set なしで代入しようとすると、右辺のワークシートオブジェクト(あるいはその中のデフォルトプロパティ)をオブジェクト型変数に直接代入しようとすることになり、互換性がないため即座に「型が一致しません(エラー13)」が発生します。一方、変数を Dim ws As Variant のように万能型で宣言していた場合、Set なしで代入すると、右辺のシートオブジェクトではなく「シート内のデータ(セルの値の二次元配列など)」が代入されてしまいます。このときは代入自体はエラーにならずに通ってしまいますが、その後 ws.Name のようにシートのプロパティを操作しようとした段階で「オブジェクト変数または With ブロック変数が設定されていません(エラー91)」という別の不具合が発生します。混乱を防ぐためにも、オブジェクトを代入するときは「常に Set を書く」というルールを徹底しましょう。

社内の古いExcelマクロでエラー13が頻発しています。原因が特定できないため、外部への修正依頼は可能ですか?

はい、十分に可能です。特に社内で長年使い回されているマクロや、作成者が既に退職してしまって中身がブラックボックス化しているマクロの場合、どこを触れば直るのか、そもそもなぜエラーが起きているのかを自社で解明するのは非常に困難であり、多くの時間と労力を浪費してしまいます。開発の専門会社(システム開発会社やVBAのスペシャリスト)に相談することで、専門ツールや高度なデバッグ技術を用いてエラーの原因となっているコード箇所とデータ条件を迅速に特定し、根本的な修正とデータのバリデーション(事前チェック機能)の追加を行ってもらえます。今後の安定運用や保守性の向上のためにも、一度専門家へ相談されることを強くお勧めします。

Excel・VBAについてのご相談

Excel・VBAについてのご相談を受け付けています

現状の課題をお聞きし、最適な進め方をご提案します。まずはお気軽にご相談ください。