【実行時エラー438】オブジェクトは、このプロパティまたはメソッドをサポートしていません。
エラー表示
このエラーが発生すると、マクロ起動時(コンパイル時)に次のエラーが表示されます。
実行時エラー '438'
オブジェクトは、このプロパティまたはメソッドをサポートしていません。
エラーの発生理由について
Microsoft公式の解答
Microsoft公式によると次のようにあります。
すべてのオブジェクトで、すべてのプロパティとメソッドがサポートされているわけではありません。 このエラーの原因と解決策は次のとおりです。
- このオートメーション オブジェクトに存在しないメソッドまたはプロパティを指定しました。オブジェクトの詳細については、オブジェクトのドキュメントを参照し、プロパティとメソッドの綴りを確認してください。
- Friend プロシージャを遅延バインディング呼び出しとして指定しました。 Friend プロシージャの名前は、コンパイル時にわかっていなければなりません。 遅延バインディング呼び出しには使用できません。
1つ目はメソッド名や、プロパティ名をタイプミス等していないか、です。
このページでは、本項目について深堀りします。
2つ目は少し特殊な状況です。始めに、用語の説明をします。
「Friend プロシージャ」とは、同じプロジェクト内の他のモジュール等からは使用できるが、外部のプロジェクトからは使えない修飾子です。
「遅延バインディング」とは、Object型やVariant型で変数を宣言し、後で型を決定する手法です。対して、変数宣言時にObject型やVariant型を使用せず、型を宣言するのは「早期バインディング」と呼びます。
クラス内でFriend修飾子を使用する時は、早期バインディングでなければなりません。
実行時にメソッドやプロパティを探しますが、遅延バインディングだと、Friendは外部公開されないため見つけられないのです。
このエラーは発生頻度が低いものの、クラス間の参照や外部プロジェクトとのやり取りで起こる可能性があります。
【原因1】メソッド名やプロパティ名のタイプミス
入力ミスが原因で発生することがあります。
ケアレスミスをしていないか、見直してみましょう。
Sub ErrSample1_1()
'Cells(1, 1).Copy が正しい
Cells(1, 1).Cppy '← ここでエラーが発生する
End Sub
【原因2】存在しないメソッドやプロパティを呼び出した
存在しないメソッドやプロパティを呼び出した場合や、別オブジェクトの専用メソッド(専用プロパティ)を誤って使用した場合に本エラーが発生します。
例1:存在しないメソッドやプロパティを呼び出した。
Sub ErrSample2_1()
'.CopyFormat というメソッドは存在しない
ActiveSheet.Range("A1").CopyFormat '← ここでエラーが発生する
End Sub
例2:別オブジェクトの専用メソッドを使用した
Sub ErrSample2_2()
' Rangeオブジェクトに「Protect」メソッドは存在しない _
※ Worksheetオブジェクトに「Protect」メソッドがあります
ActiveSheet.Range("A1").Protect '← ここでエラーが発生する
End Sub
「ActiveSheet.Range("A1").protect」と入力すると、『ActiveSheet.Range("A1").Protect』と ”p” が大文字に自動変換されるので、「正しいのでは?」となるかもしれませんが、間違いです。
【原因3】オブジェクトのプロパティやメソッドの記載漏れ
オブジェクトの後ろにプロパティやメソッドを記載していないと、本エラーが発生します。プロパティやメソッドを省略できるのは、Rangeオブジェクト等の一部のオブジェクトのみです。
例1:ブック名を表示させたかった
Sub ErrSample3_1()
Dim wb As Workbook
Set wb = ThisWorkbook
'wb.Name の記載漏れ
Debug.Print wb '← ここでエラーが発生する
End Sub
例2:シート名を表示させたかった
Sub ErrSample3_2()
Dim ws As Worksheet
Set ws = ThisWorkbook.Worksheets(1)
'ws.Name の記載漏れ
Debug.Print ws '← ここでエラーが発生する
End Sub
【原因4】新しいエクセル関数を古いエクセルで使用した
Microsoft 365(Office 365)など、新しいエクセルは新規関数が追加されています。 例えば、TextSplit関数は、Microsoft365(Office365)か、Excel2024以降でないと使用できません。 このため、「自分の環境だと動いたけど、客先だと動かない!」といった状況になりえます。 新しい関数をVBAで使用する時は、バージョンにも気を付けるようにしましょう。
例:TextSplit関数を使用(Excel2024はエラーなし、Excel2021ならエラー発生)
Sub ErrSample4_1()
Dim var As Variant
'TextSplit関数 は Excel2024は使用可能だが、Excel2021はエラー
var = Application.WorksheetFunction.TextSplit("A,B,C", ",")
End Sub
どうしても新しい関数を使用したい場合は、エラートラップを併用しましょう。
● 関連リンク:エラートラップ(エラーキャッチ)の方法!
Sub ErrSample4_2()
On Error GoTo ErrTrap
Dim var As Variant
'TextSplit は Microsoft365 用の関数のため、Excel2021等ではエラー
var = Application.WorksheetFunction.TextSplit("A,B,C", ",")
Exit Sub
ErrTrap:
If Err.Number = 438 Then
'関数が使用できなかった場合の処理
'エラー情報の消去
Err.Clear
Else
'想定外のエラー
MsgBox "エラー番号:" & Err.Number & vbNewLine & _
Err.Description, vbCritical
End If
End Sub
【原因5】自作関数でオブジェクトを返す際、Setをつけ忘れた
自作関数でオブジェクトを返す際、型を指定せず、かつ「Set」をつけ忘れると、本エラーが発生します。
'引数でシート名を指定、シートオブジェクトを返す
Function GetSheetObj(ByVal wsName As String)
'Setのつけ忘れ _
※ Set GetSheetObj = ThisWorkbook.Worksheets(wsName) が正しい
GetSheetObj = ThisWorkbook.Worksheets(wsName)
End Function
Sub ErrSample5()
Dim ws As Worksheet
Set ws = GetSheetObj("Sheet1")
End Sub
改良版がコチラです。
Function GetSheetObj(ByVal wsName As String) As Worksheet
Set GetSheetObj = ThisWorkbook.Worksheets(wsName)
End Function
Sub ErrSample5()
Dim ws As Worksheet
Set ws = GetSheetObj("Sheet1")
End Sub
GetSheetObj関数で返す型(Worksheet)を指定しました。
また、2行目の文頭に「Set」を付け足しました。
余談ですが、GetSheetObj関数で返す型(Worksheet)を指定した状態で、2行目の「Set」がないと『実行時エラー91』になります。
● 関連リンク:実行時エラー91 について
このエラーの予防策
まず、メソッド名・プロパティ名を正確に記述してください。また、オブジェクトの種類に合ったメソッド・プロパティを使用してください。
マクロを作成したエクセルと異なるバージョンでマクロを使用する可能性がある場合、新しいエクセル関数は、下位バージョンで動作するか確認してください。
このエラーはテストをすれば、見つかるはずです。リリース前にはテストを忘れずに行いましょう。