「自分のPCでは完璧に動くExcelマクロが、別のPCに持っていったら動かない」――このトラブルは、VBAを業務で使っている現場で非常によく起きる問題です。エラーメッセージも「実行時エラー ‘1004’」「参照が不正または修飾されていません」「オブジェクトはこのプロパティまたはメソッドをサポートしていません」など様々で、一見すると原因が分かりにくいものばかりです。しかし原因は大きく分類すると参照設定の違い・ファイルパスのハードコード・Excelバージョンの差異・セキュリティ設定・環境依存の記述のいずれかに集約されます。本記事では、別のPCでマクロが動かなくなるすべての主要パターンを、その場でコピーして使える修正コードとともに体系的に解説します。


目次


別PCで動かない原因の全体像

マクロが別のPCで動かないとき、その原因は必ず「作成したPC固有の環境に依存したコードが書かれている」という点にあります。自分のPCでは当たり前に存在しているライブラリ・フォルダ・フォント・アプリケーションが、別のPCには存在しない、またはバージョンが異なるわけです。

原因を素早く分類するために、まずエラーメッセージを確認してください。エラーの種類によって原因を絞り込めます。

  • 「参照が不正または修飾されていません」(コンパイルエラー)→ 参照設定のMISSINGが原因である可能性が高い
  • 「ファイルが見つかりません」「パス名が無効です」(実行時エラー53・75)→ ファイルパスのハードコードが原因
  • 「オブジェクトはこのプロパティまたはメソッドをサポートしていません」(実行時エラー438)→ Excelバージョンの差異か、ライブラリのバージョン違いが原因
  • 「マクロが無効になっています」(実行自体ができない)→ セキュリティ設定の問題
  • 「ActivePrinter」「フォント名」関連のエラー→ プリンター・フォント依存の記述が原因
  • エラーなしだが動作がおかしい・結果が違う→ バージョン差異による関数の挙動の違いや、環境依存の値が問題

原因1:参照設定が切れている(MISSING)

別PCでマクロが動かない原因として最も多いのが、参照設定(ライブラリへの参照)が別のPCでは解決できないというケースです。作成したPCでは「Microsoft ActiveX Data Objects 6.1 Library」が入っていても、別PCには「6.0」しかなかったり、そもそもインストールされていなかったりします。この場合、VBAエディタの「ツール」→「参照設定」を開くと「MISSING: ○○ Library」という表示が出ます。

MISSINGの確認と対処手順

  • 別PCでファイルを開いてVBAエディタ(Alt+F11)を起動する
  • 「ツール」→「参照設定」を開く
  • 「MISSING:」と表示されているライブラリがあれば、それがエラーの原因
  • MISSINGのチェックを外し、代わりに別PCにインストールされているバージョンを探してチェックする

よくMISSINGになるライブラリと対処コード

' ========================================
' MISSING になりやすいライブラリ一覧と遅延バインディングへの書き換え例
' ========================================

' ----------------------------------------
' Microsoft Scripting Runtime(FileSystemObject)
' ----------------------------------------

' NG:早期バインディング(参照設定が必要)
' Dim fso As FileSystemObject
' Set fso = New FileSystemObject

' OK:遅延バインディング(参照設定不要・別PCでも動く)
Dim fso As Object
Set fso = CreateObject("Scripting.FileSystemObject")

If fso.FolderExists("C:\data") Then
    Debug.Print "フォルダあり"
End If

Set fso = Nothing

' ----------------------------------------
' Microsoft ActiveX Data Objects(ADODB)
' ----------------------------------------

' NG:早期バインディング
' Dim conn As ADODB.Connection
' Dim rs   As ADODB.Recordset

' OK:遅延バインディング
Dim conn As Object
Dim rs   As Object

Set conn = CreateObject("ADODB.Connection")
Set rs   = CreateObject("ADODB.Recordset")

' ----------------------------------------
' Microsoft Outlook Object Library
' ----------------------------------------

' NG:早期バインディング
' Dim olApp As Outlook.Application

' OK:遅延バインディング
Dim olApp As Object
Set olApp = CreateObject("Outlook.Application")

参照設定の状態を診断するマクロ

' ========================================
' 参照設定の状態を一覧で表示する診断マクロ
' 別PCで実行して MISSING を特定する
' ========================================
Sub DiagnoseReferences()

    Dim vbProj As Object
    Dim refs   As Object
    Dim r      As Object
    Dim ws     As Worksheet
    Dim row    As Long

    Set vbProj = ThisWorkbook.VBProject
    Set refs   = vbProj.References

    ' 診断結果をシートに出力
    Set ws = ThisWorkbook.Sheets.Add
    ws.Name = "参照設定診断_" & Format(Now(), "mmdd_HHmm")

    ws.Cells(1, 1).Value = "状態"
    ws.Cells(1, 2).Value = "名前"
    ws.Cells(1, 3).Value = "説明"
    ws.Cells(1, 4).Value = "バージョン"
    ws.Cells(1, 5).Value = "パス"
    ws.Range("A1:E1").Font.Bold = True

    row = 2

    Dim i As Integer
    For i = 1 To refs.Count
        Set r = refs.Item(i)

        ws.Cells(row, 1).Value = IIf(r.IsBroken, "MISSING", "OK")
        ws.Cells(row, 2).Value = r.Name
        ws.Cells(row, 3).Value = r.Description
        ws.Cells(row, 4).Value = r.Major & "." & r.Minor
        ws.Cells(row, 5).Value = r.FullPath

        ' MISSINGの行を赤くハイライト
        If r.IsBroken Then
            ws.Rows(row).Interior.Color = RGB(255, 200, 200)
        End If

        row = row + 1
    Next i

    ws.Columns("A:E").AutoFit

    MsgBox "参照設定の診断が完了しました。" & vbCrLf & _
           "「MISSING」と表示された行を確認してください。", vbInformation

    Set ws     = Nothing
    Set refs   = Nothing
    Set vbProj = Nothing

End Sub

原因2:ファイルパスがハードコードされている

「C:\Users\yamada\Documents\data.xlsx」のように、作成者のPC固有のパスをコード内に直接書き込んでいる(ハードコード)場合、別のPCではそのパスが存在しないためエラーになります。これは別PCでのエラー原因として2番目に多いパターンです。

エラーが起きるコード例

' NG:絶対パスのハードコード(別PCでは動かない)
Workbooks.Open "C:\Users\yamada\Desktop\売上データ.xlsx"

' NG:ユーザー名を含むパス
Dim path As String
path = "C:\Users\yamada\Documents\マクロ用フォルダ\template.xlsm"

' NG:ネットワークドライブのパスがドライブレターで書かれている
' (別PCではドライブレターが異なる場合がある)
Workbooks.Open "Z:\共有フォルダ\data.csv"

修正後のコード(動的パス解決パターン)

' ========================================
' パスを動的に解決するパターン集
' ========================================

' ----------------------------------------
' パターン1:マクロブック自身の場所を基準にする(最も推奨)
' ----------------------------------------
' マクロファイルと同じフォルダにあるファイルを開く
Dim basePath  As String
Dim dataFile  As String

basePath = ThisWorkbook.Path & "\"
dataFile = basePath & "売上データ.xlsx"

If Dir(dataFile) = "" Then
    MsgBox "ファイルが見つかりません:" & vbCrLf & dataFile, vbCritical
    Exit Sub
End If

Workbooks.Open dataFile
' ----------------------------------------
' パターン2:ファイル選択ダイアログで毎回選ばせる
' ----------------------------------------
Sub OpenFileWithDialog()

    Dim filePath As String

    filePath = Application.GetOpenFilename( _
                   FileFilter:="Excelファイル (*.xlsx;*.xlsm;*.xlsb),*.xlsx;*.xlsm;*.xlsb," & _
                               "CSVファイル (*.csv),*.csv," & _
                               "すべてのファイル (*.*),*.*", _
                   Title:="開くファイルを選択してください")

    If filePath = "False" Then
        MsgBox "キャンセルされました。", vbInformation
        Exit Sub
    End If

    Workbooks.Open filePath

End Sub
' ----------------------------------------
' パターン3:パスを設定シートで管理する
' ----------------------------------------
' 「設定」シートのB列にパスを記述して、コードから参照する
Sub ReadPathFromSettingSheet()

    Dim wsConfig  As Worksheet
    Dim dataPath  As String
    Dim outPath   As String

    ' 設定シートからパスを取得
    On Error Resume Next
    Set wsConfig = ThisWorkbook.Sheets("設定")
    On Error GoTo 0

    If wsConfig Is Nothing Then
        MsgBox "「設定」シートが見つかりません。", vbCritical
        Exit Sub
    End If

    dataPath = wsConfig.Range("B2").Value   ' データフォルダのパス
    outPath  = wsConfig.Range("B3").Value   ' 出力先フォルダのパス

    ' パスの末尾に \ がなければ追加
    If Right(dataPath, 1) <> "\" Then dataPath = dataPath & "\"
    If Right(outPath,  1) <> "\" Then outPath  = outPath  & "\"

    ' 存在確認
    If Dir(dataPath, vbDirectory) = "" Then
        MsgBox "データフォルダが存在しません:" & vbCrLf & dataPath, vbCritical
        Exit Sub
    End If

    Debug.Print "データパス: " & dataPath
    Debug.Print "出力パス  : " & outPath

    Set wsConfig = Nothing

End Sub
' ----------------------------------------
' パターン4:環境変数・特殊フォルダを使う
' ----------------------------------------
Sub UseSpecialFolders()

    ' Environ関数で環境変数を取得
    Dim userProfile  As String
    Dim desktopPath  As String
    Dim documentsPath As String
    Dim tempPath     As String

    userProfile   = Environ("USERPROFILE")         ' C:\Users\ユーザー名
    desktopPath   = Environ("USERPROFILE") & "\Desktop\"
    documentsPath = Environ("USERPROFILE") & "\Documents\"
    tempPath      = Environ("TEMP") & "\"

    Debug.Print "ユーザーホーム: " & userProfile
    Debug.Print "デスクトップ  : " & desktopPath
    Debug.Print "ドキュメント  : " & documentsPath
    Debug.Print "TEMPフォルダ  : " & tempPath

    ' Shellオブジェクトで特殊フォルダを取得(より確実な方法)
    Dim shell        As Object
    Dim specialFolders As Object

    Set shell = CreateObject("WScript.Shell")
    Debug.Print "デスクトップ(Shell): " & shell.SpecialFolders("Desktop")
    Debug.Print "AppData             : " & shell.SpecialFolders("AppData")

    Set shell = Nothing

End Sub

パス設定シートのひな形を自動作成するマクロ

' ========================================
' 設定シートを自動作成するマクロ
' ========================================
Sub CreateSettingsSheet()

    Dim ws As Worksheet

    ' 既に「設定」シートがある場合はスキップ
    On Error Resume Next
    Set ws = ThisWorkbook.Sheets("設定")
    On Error GoTo 0

    If Not ws Is Nothing Then
        MsgBox "「設定」シートは既に存在します。", vbInformation
        Exit Sub
    End If

    Set ws = ThisWorkbook.Sheets.Add(Before:=ThisWorkbook.Sheets(1))
    ws.Name = "設定"

    ' ヘッダー
    With ws
        .Range("A1").Value = "設定項目"
        .Range("B1").Value = "パス・値"
        .Range("A1:B1").Font.Bold = True
        .Range("A1:B1").Interior.Color = RGB(68, 114, 196)
        .Range("A1:B1").Font.Color = vbWhite

        ' 初期値の設定
        .Range("A2").Value = "データフォルダ"
        .Range("B2").Value = ThisWorkbook.Path & "\"

        .Range("A3").Value = "出力フォルダ"
        .Range("B3").Value = ThisWorkbook.Path & "\output\"

        .Range("A4").Value = "テンプレートファイル"
        .Range("B4").Value = ThisWorkbook.Path & "\template.xlsx"

        .Range("A5").Value = "ログフォルダ"
        .Range("B5").Value = ThisWorkbook.Path & "\log\"

        .Columns("A:B").AutoFit
        .Range("B:B").Interior.Color = RGB(255, 255, 220)   ' 入力欄をハイライト
    End With

    MsgBox "「設定」シートを作成しました。" & vbCrLf & _
           "B列の各パスを実行環境に合わせて変更してください。", vbInformation

    Set ws = Nothing

End Sub

原因3:ExcelバージョンによるAPI・関数の違い

作成したPC(例:Microsoft 365)と別PC(例:Excel 2016)でExcelのバージョンが異なる場合、新しいバージョンで追加されたAPIや関数が古いバージョンでは使えずエラーになります。また逆に、古いバージョンで使えた一部の関数が廃止されることもあります。

バージョン差異でよく問題になる機能

  • xlCSVUTF8(62):Excel 2016以降。旧バージョンでCSVをUTF-8保存しようとするとエラー438
  • スパークライン(SparklineGroups):Excel 2010以降
  • PowerQuery関連のAPI:Excel 2016以降
  • LET関数・XLOOKUP関数:Microsoft 365のみ。WorksheetFunctionから呼び出しでエラー
  • Forecast_ETS関数:Excel 2016以降
  • ThemeColor関連のプロパティ:Excel 2007以降(Excel 2003では使えない)

バージョン確認と分岐処理のコード

' ========================================
' Excelバージョンを確認して処理を分岐するパターン
' ========================================

' バージョン番号早見表
' 11.0 = Excel 2003
' 12.0 = Excel 2007
' 14.0 = Excel 2010
' 15.0 = Excel 2013
' 16.0 = Excel 2016 / 2019 / 2021 / Microsoft 365

Function ExcelVersion() As Double
    ExcelVersion = CDbl(Application.Version)
End Function

Function IsExcel2016OrLater() As Boolean
    IsExcel2016OrLater = (ExcelVersion() >= 16)
End Function

Function IsExcel2010OrLater() As Boolean
    IsExcel2010OrLater = (ExcelVersion() >= 14)
End Function

' ----------------------------------------
' UTF-8保存のバージョン分岐例
' ----------------------------------------
Sub SaveAsCSVWithVersionCheck()

    Dim savePath   As String
    Dim saveFormat As Long

    savePath = ThisWorkbook.Path & "\output.csv"

    ' バージョンによって保存形式を切り替える
    If IsExcel2016OrLater() Then
        saveFormat = 62   ' xlCSVUTF8(Excel 2016以降)
    Else
        saveFormat = 6    ' xlCSV(Shift-JIS・旧バージョン対応)
        MsgBox "Excel 2013以前のバージョンのため、CSV はShift-JIS形式で保存されます。", vbInformation
    End If

    Application.DisplayAlerts = False
    ActiveWorkbook.SaveAs Filename:=savePath, FileFormat:=saveFormat
    Application.DisplayAlerts = True

    MsgBox "CSVを保存しました: " & savePath, vbInformation

End Sub

' ----------------------------------------
' スパークラインのバージョン分岐例
' ----------------------------------------
Sub AddSparklineIfSupported()

    If Not IsExcel2010OrLater() Then
        MsgBox "スパークラインはExcel 2010以降でのみ使用できます。" & vbCrLf & _
               "現在のバージョン: " & Application.Version, vbExclamation
        Exit Sub
    End If

    With ActiveSheet.SparklineGroups.Add( _
             Type:=xlSparkLine, _
             SourceData:="B2:M2")
        .Location = ActiveSheet.Range("N2")
    End With

End Sub
' ========================================
' 現在の実行環境情報をシートに出力する診断マクロ
' 別PCに持っていって実行し、環境差異を確認するのに使う
' ========================================
Sub DiagnoseEnvironment()

    Dim ws  As Worksheet
    Dim row As Long

    Set ws = ThisWorkbook.Sheets.Add
    ws.Name = "環境診断_" & Format(Now(), "mmdd_HHmm")

    ws.Range("A1").Value = "項目"
    ws.Range("B1").Value = "値"
    ws.Range("A1:B1").Font.Bold = True

    row = 2

    Dim items As Variant
    Dim vals  As Variant

    items = Array( _
        "Excelバージョン", _
        "バージョン名", _
        "OSバージョン", _
        "ユーザー名", _
        "コンピュータ名", _
        "デフォルトフォント", _
        "デフォルトフォントサイズ", _
        "国/地域コード", _
        "日付区切り", _
        "小数点記号", _
        "ActivePrinter", _
        "64ビット版か", _
        "XLStartパス", _
        "UserLibraryPath")

    vals = Array( _
        Application.Version, _
        Application.Name, _
        Environ("OS"), _
        Environ("USERNAME"), _
        Environ("COMPUTERNAME"), _
        Application.StandardFont, _
        Application.StandardFontSize, _
        Application.International(xlCountryCode), _
        Application.International(xlDateSeparator), _
        Application.International(xlDecimalSeparator), _
        Application.ActivePrinter, _
        Application.IsA64BitExcel, _
        Application.StartupPath, _
        Application.UserLibraryPath)

    Dim i As Long
    For i = 0 To UBound(items)
        ws.Cells(row, 1).Value = items(i)
        On Error Resume Next
        ws.Cells(row, 2).Value = vals(i)
        If Err.Number <> 0 Then
            ws.Cells(row, 2).Value = "取得エラー: " & Err.Description
            Err.Clear
        End If
        On Error GoTo 0
        row = row + 1
    Next i

    ws.Columns("A:B").AutoFit
    MsgBox "環境診断が完了しました。", vbInformation
    Set ws = Nothing

End Sub

原因4:セキュリティ設定によるマクロ無効化

別PCでマクロファイルを開いても「マクロが実行できない」という場合、セキュリティ設定によってマクロが無効化されていることがほとんどです。特に企業のPCではグループポリシーでマクロが全面禁止になっているケースがあり、この場合は個人では設定を変更できません。

セキュリティによる無効化のパターンと対処

  • 黄色いバーで「コンテンツの有効化」が表示される→ バーの「コンテンツの有効化」ボタンをクリックする。次回からは表示されなくなる(信頼済みとしてマークされる)
  • 「マクロは無効にされました」のバーは出るが「コンテンツの有効化」ボタンがない→ グループポリシーまたはトラストセンター設定で全マクロが禁止されている。IT管理者に確認が必要
  • ファイルを開いても何も表示されない・マクロが動かない→ Protectedビュー(保護ビュー)で開かれている可能性がある。「編集を有効にする」を押してからマクロを有効化する

「インターネットからダウンロードしたファイル」の保護ビュー解除

メールの添付ファイルやウェブからダウンロードしたExcelファイルは、Windowsが「危険なファイル」としてZone情報を付与し、Excelが保護ビューで開きます。この場合、マクロを有効化する前に「編集を有効にする」のクリックが必要です。VBAから自動的に解除することはできないため、ユーザーの手動操作が必要です。

' ========================================
' ファイルを開くときにセキュリティ警告が出ないよう
' 信頼できる場所から開く処理(ローカルにコピーしてから開く)
' ========================================
Sub OpenFileFromTrustedLocation()

    Dim sourcePath  As String
    Dim trustedPath As String
    Dim fileName    As String

    ' 信頼できる場所(トラステッドロケーション)として登録済みのフォルダ
    trustedPath = "C:\TrustedMacros\"

    ' ファイル選択
    sourcePath = Application.GetOpenFilename( _
                     FileFilter:="Excelファイル (*.xlsm;*.xlsb),*.xlsm;*.xlsb", _
                     Title:="開くファイルを選択してください")

    If sourcePath = "False" Then Exit Sub

    fileName = Mid(sourcePath, InStrRev(sourcePath, "\") + 1)

    ' 信頼できる場所にファイルをコピーしてから開く
    If Dir(trustedPath, vbDirectory) = "" Then
        MkDir trustedPath
    End If

    Dim fso As Object
    Set fso = CreateObject("Scripting.FileSystemObject")
    fso.CopyFile sourcePath, trustedPath & fileName, True
    Set fso = Nothing

    Workbooks.Open trustedPath & fileName

End Sub
' ========================================
' Workbook_Openイベントで実行環境のセキュリティ状態を確認する
' ThisWorkbookモジュールに記述する
' ========================================
Private Sub Workbook_Open()

    ' マクロが実行されていること自体がマクロ有効の証明だが
    ' 追加のセキュリティ状態確認が必要な場合
    Dim msg As String

    ' 保護ビューチェック(Protected Viewで開かれているか)
    ' 保護ビューではWorkbook_Openイベント自体が実行されないため
    ' ここに到達した時点で保護ビューではないことが確認できる

    ' 信頼できる場所からのファイル確認
    If Not ThisWorkbook.Trusted Then
        msg = "このファイルは信頼できる場所から開かれていません。" & vbCrLf & _
              "一部のマクロ機能が制限される場合があります。" & vbCrLf & vbCrLf & _
              "継続しますか?"

        If MsgBox(msg, vbYesNo + vbExclamation, "セキュリティ確認") = vbNo Then
            ThisWorkbook.Close SaveChanges:=False
            Exit Sub
        End If
    End If

    ' 正常起動時のメッセージ(任意)
    Application.StatusBar = ThisWorkbook.Name & " が正常に起動しました。"

End Sub

原因5:フォント・プリンター依存の記述

マクロの中で特定のフォント名や、ActivePrinter による印刷設定をハードコードしている場合、別PCにそのフォントやプリンターが存在しないとエラーになります。

エラーが起きるコード例

' NG:特定のフォントをハードコード
' 別PCにそのフォントがインストールされていないとエラーまたは代替フォントに変わる
ActiveSheet.Range("A1").Font.Name = "HGP創英角ポップ体"

' NG:プリンター名をハードコード
' 別PCにそのプリンターが存在しない場合はエラー
Application.ActivePrinter = "Canon MF820C Series on Ne01:"
ActiveSheet.PrintOut

修正後のコード(フォント・プリンターを動的に処理する)

' ========================================
' フォントの存在確認をしてから設定するパターン
' ========================================
Function FontExists(fontName As String) As Boolean

    Dim i As Long
    For i = 0 To Application.CommandBars("Formatting").Controls(1) _
                              .CommandBar.Controls.Count - 1
        ' フォント名リストを直接確認する(間接的な方法)
    Next i

    ' より確実な方法:実際に設定してみてエラーが出なければ存在する
    On Error Resume Next
    Dim testCell As Range
    Set testCell = ActiveSheet.Cells(1, 1)
    Dim originalFont As String
    originalFont = testCell.Font.Name
    testCell.Font.Name = fontName
    FontExists = (Err.Number = 0)
    testCell.Font.Name = originalFont   ' 元に戻す
    Err.Clear
    On Error GoTo 0

End Function

Sub SetFontSafely()

    Dim preferredFonts As Variant
    Dim i              As Long
    Dim targetFont     As String

    ' 優先順位付きフォントリスト(上から順に試す)
    preferredFonts = Array("游ゴシック", "メイリオ", "MS ゴシック", "Arial")

    targetFont = preferredFonts(UBound(preferredFonts))   ' デフォルト

    For i = 0 To UBound(preferredFonts)
        If FontExists(CStr(preferredFonts(i))) Then
            targetFont = CStr(preferredFonts(i))
            Exit For
        End If
    Next i

    ActiveSheet.Range("A1:Z100").Font.Name = targetFont
    Debug.Print "設定されたフォント: " & targetFont

End Sub
' ========================================
' プリンターを動的に選択するパターン
' ========================================
Sub PrintWithPrinterSelection()

    ' 方法1:印刷ダイアログを表示してユーザーに選ばせる
    Application.Dialogs(xlDialogPrint).Show

End Sub

Sub PrintToDefaultPrinter()

    ' 方法2:デフォルトプリンターを使って印刷(ハードコードなし)
    ' ActivePrinterを変更せずに印刷すると現在の設定で印刷される
    On Error GoTo PrintError

    With ActiveSheet.PageSetup
        .Orientation   = xlPortrait
        .FitToPagesWide = 1
        .FitToPagesTall = False
    End With

    ActiveSheet.PrintOut Copies:=1, Preview:=False
    Exit Sub

PrintError:
    MsgBox "印刷に失敗しました。" & vbCrLf & _
           "プリンターの設定を確認してください。" & vbCrLf & vbCrLf & _
           "エラー: " & Err.Description, vbCritical

End Sub

Sub ListAvailablePrinters()

    ' 利用可能なプリンター一覧をイミディエイトウィンドウに出力
    Dim wshNetwork As Object
    Set wshNetwork = CreateObject("WScript.Network")

    Dim printers   As Object
    Set printers   = wshNetwork.EnumPrinterConnections

    Dim i As Long
    For i = 0 To printers.Count - 1 Step 2
        Debug.Print "ポート: " & printers.Item(i) & "  プリンター: " & printers.Item(i + 1)
    Next i

    Set printers   = Nothing
    Set wshNetwork = Nothing

End Sub

原因6:外部アプリケーション連携(Outlook・Access・IEなど)

OutlookでメールをVBAから送信したり、AccessのDBに接続したり、Internet Explorerを操作したりするマクロは、別PCに対象アプリケーションがインストールされていない場合にエラーになります。また、IEはWindows 11・Microsoft 365環境では廃止されているため動作しません。

外部アプリケーションの存在確認パターン

' ========================================
' 外部アプリケーションの存在確認ユーティリティ
' ========================================

' Outlookがインストールされているか確認
Function OutlookIsAvailable() As Boolean
    Dim obj As Object
    On Error Resume Next
    Set obj = CreateObject("Outlook.Application")
    OutlookIsAvailable = (Err.Number = 0)
    If Not obj Is Nothing Then Set obj = Nothing
    Err.Clear
    On Error GoTo 0
End Function

' Accessがインストールされているか確認
Function AccessIsAvailable() As Boolean
    Dim obj As Object
    On Error Resume Next
    Set obj = CreateObject("Access.Application")
    AccessIsAvailable = (Err.Number = 0)
    If Not obj Is Nothing Then
        obj.Quit
        Set obj = Nothing
    End If
    Err.Clear
    On Error GoTo 0
End Function

' Wordがインストールされているか確認
Function WordIsAvailable() As Boolean
    Dim obj As Object
    On Error Resume Next
    Set obj = CreateObject("Word.Application")
    WordIsAvailable = (Err.Number = 0)
    If Not obj Is Nothing Then
        obj.Quit
        Set obj = Nothing
    End If
    Err.Clear
    On Error GoTo 0
End Function

' 実行環境チェックをまとめて行う
Sub CheckExternalApps()

    Dim msg As String
    msg = "=== 外部アプリケーション確認 ===" & vbCrLf

    msg = msg & "Outlook : " & IIf(OutlookIsAvailable(), "インストール済み", "未インストール") & vbCrLf
    msg = msg & "Access  : " & IIf(AccessIsAvailable(),  "インストール済み", "未インストール") & vbCrLf
    msg = msg & "Word    : " & IIf(WordIsAvailable(),    "インストール済み", "未インストール") & vbCrLf

    MsgBox msg, vbInformation, "外部アプリケーション確認"

End Sub
' ========================================
' Outlook未インストール時の代替メール送信(CDO使用)
' CDO(Collaboration Data Objects)はWindowsに標準搭載
' ========================================
Sub SendMailWithCDO()

    Dim cdo     As Object
    Dim config  As Object

    Set cdo    = CreateObject("CDO.Message")
    Set config = CreateObject("CDO.Configuration")

    ' SMTPサーバーの設定(社内SMTPサーバーに合わせて変更)
    With config.Fields
        .Item("http://schemas.microsoft.com/cdo/configuration/sendusing")       = 2
        .Item("http://schemas.microsoft.com/cdo/configuration/smtpserver")      = "smtp.example.com"
        .Item("http://schemas.microsoft.com/cdo/configuration/smtpserverport")  = 25
        .Update
    End With

    With cdo
        Set .Configuration = config
        .From    = "[email protected]"
        .To      = "[email protected]"
        .Subject = "VBAからのテストメール"
        .TextBody = "このメールはVBAのCDOから送信されました。"
        .Send
    End With

    Set cdo    = Nothing
    Set config = Nothing

    MsgBox "メールを送信しました。", vbInformation

End Sub
' ========================================
' IE廃止後のWebデータ取得(XMLHTTPRequest使用)
' Outlook・IE不要でWindowsに標準搭載
' ========================================
Sub FetchWebData()

    Dim http    As Object
    Dim url     As String

    url  = "https://api.example.com/data"

    Set http = CreateObject("MSXML2.XMLHTTP")
    http.Open "GET", url, False
    http.Send

    If http.Status = 200 Then
        Debug.Print "取得成功:"
        Debug.Print Left(http.responseText, 500)
    Else
        MsgBox "HTTPエラー: " & http.Status & " " & http.statusText, vbCritical
    End If

    Set http = Nothing

End Sub

原因7:OS・環境変数・ユーザー名依存の記述

ユーザー名・コンピュータ名・ドライブレター・タイムゾーン・地域設定などOS環境に依存したコードは、別PCでは異なる値になるためエラーや意図しない動作を引き起こします。

エラーが起きるコード例と修正パターン

' NG:ユーザー名をハードコード
If Environ("USERNAME") = "yamada" Then
    ' 特定ユーザーのみ処理
End If

' OK:ユーザー名を動的に取得して使う
Dim currentUser As String
currentUser = Environ("USERNAME")
Debug.Print "実行ユーザー: " & currentUser

' ログに実行者名を記録する
Dim logMsg As String
logMsg = Format(Now(), "yyyy/mm/dd HH:mm:ss") & " [" & currentUser & "] 処理実行"
' NG:ドライブレターをハードコード(別PCではZドライブが存在しない可能性)
Workbooks.Open "Z:\共有フォルダ\data.xlsx"

' OK:UNCパス(\\サーバー名\共有名)を使う
' ドライブレターに依存しないネットワークパス
Workbooks.Open "\\fileserver\shared\data.xlsx"

' またはユーザーにパスを入力させる
Dim networkPath As String
networkPath = InputBox("共有フォルダのパスを入力してください(例:\\server\share)", _
                       "パス入力", "\\fileserver\shared\")
' ========================================
' 地域設定の違いによる日付・数値の誤動作対策
' ========================================
Sub SafeDateHandling()

    ' NG:地域設定に依存した日付文字列
    ' アメリカ環境では Month/Day/Year の順になるため誤動作する
    ' Dim d As Date
    ' d = CDate("2024/06/15")   ' 日本ではOKだがUSロケールでは解釈が変わる

    ' OK:年月日を明示的に数値で指定する(地域に依存しない)
    Dim d As Date
    d = DateSerial(2024, 6, 15)   ' 年, 月, 日 を明示的に指定
    Debug.Print Format(d, "yyyy/mm/dd")   ' → 2024/06/15

    ' 日付を文字列に変換する場合もFormatで形式を明示する
    Dim dateStr As String
    dateStr = Format(Date, "yyyy-mm-dd")   ' ISO形式で出力(地域に依存しない)

    ' OK:数値の小数点記号も地域によって異なる対策
    ' VBAのCDbl()はロケールに依存しないが、文字列→数値変換は依存する場合がある
    Dim numStr As String
    numStr = "1234.56"   ' 小数点はピリオド固定で扱う(ロケール変換を避ける)
    Dim numVal As Double
    numVal = CDbl(numStr)   ' CDblはロケールに依存しない
    Debug.Print numVal

End Sub

早期バインディングと遅延バインディングの使い分け

「別PCでも動くマクロ」を作るための最重要テクニックが、遅延バインディング(Late Binding)の活用です。参照設定に依存せず、外部ライブラリのオブジェクトを CreateObject() で実行時に生成するため、ライブラリのバージョン差異の影響を受けません。

早期バインディングと遅延バインディングの比較

  • 早期バインディング(Early Binding):Dim conn As ADODB.Connection のように型を明示。参照設定が必要。IntelliSenseが効く。コンパイル時に型チェックされる。開発・デバッグには便利だが別PC配布時に参照切れリスクあり
  • 遅延バインディング(Late Binding):Dim conn As Object + CreateObject("ADODB.Connection")。参照設定不要。IntelliSenseは効かない。別PC配布時も参照切れが起きない。配布ファイルには必ずこちらを使う
' ========================================
' 早期バインディング→遅延バインディングへの書き換え対応表
' ========================================

' ----------------------------------------
' FileSystemObject
' ----------------------------------------
' 早期:Dim fso As New FileSystemObject
' 遅延:
Dim fso As Object
Set fso = CreateObject("Scripting.FileSystemObject")

' ----------------------------------------
' ADODB Connection / Recordset
' ----------------------------------------
' 早期:Dim conn As New ADODB.Connection
'       Dim rs   As New ADODB.Recordset
' 遅延:
Dim conn As Object
Dim rs   As Object
Set conn = CreateObject("ADODB.Connection")
Set rs   = CreateObject("ADODB.Recordset")

' ----------------------------------------
' Outlook
' ----------------------------------------
' 早期:Dim olApp As New Outlook.Application
' 遅延:
Dim olApp As Object
Set olApp = CreateObject("Outlook.Application")

' ----------------------------------------
' Word
' ----------------------------------------
' 早期:Dim wdApp As New Word.Application
' 遅延:
Dim wdApp As Object
Set wdApp = CreateObject("Word.Application")
wdApp.Visible = True

' ----------------------------------------
' PowerPoint
' ----------------------------------------
' 早期:Dim ppApp As New PowerPoint.Application
' 遅延:
Dim ppApp As Object
Set ppApp = CreateObject("PowerPoint.Application")

' ----------------------------------------
' Dictionary(Scripting.Dictionary)
' ----------------------------------------
' 早期:Dim dict As New Scripting.Dictionary
' 遅延:
Dim dict As Object
Set dict = CreateObject("Scripting.Dictionary")
dict.Add "key1", "value1"
dict.Add "key2", "value2"
Debug.Print dict("key1")

' ----------------------------------------
' WScript.Shell
' ----------------------------------------
Dim wsh As Object
Set wsh = CreateObject("WScript.Shell")
wsh.Run "notepad.exe"
Set wsh = Nothing

開発中は早期バインディング、配布時は遅延バインディングに切り替えるパターン

' ========================================
' 条件コンパイルを使って開発用と配布用を切り替える
' ========================================

' モジュール先頭に定義(1=開発モード、0=配布モード)
#Const DEVELOPMENT_MODE = 0

Sub ConnectToDatabase()

#If DEVELOPMENT_MODE Then
    ' 開発時:早期バインディング(IntelliSenseが効く)
    Dim conn As ADODB.Connection
    Dim rs   As ADODB.Recordset
    Set conn = New ADODB.Connection
    Set rs   = New ADODB.Recordset
#Else
    ' 配布時:遅延バインディング(参照設定不要)
    Dim conn As Object
    Dim rs   As Object
    Set conn = CreateObject("ADODB.Connection")
    Set rs   = CreateObject("ADODB.Recordset")
#End If

    ' 以降は共通の処理
    conn.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;" & _
                            "Data Source=" & ThisWorkbook.Path & "\data.accdb;"
    conn.Open

    rs.Open "SELECT * FROM 売上", conn, 3, 1

    Do While Not rs.EOF
        Debug.Print rs.Fields(0).Value
        rs.MoveNext
    Loop

    If rs.State   = 1 Then rs.Close
    If conn.State = 1 Then conn.Close
    Set rs   = Nothing
    Set conn = Nothing

End Sub

別PCでも動くポータブルなコードを書く原則

以下の原則を守ることで、別PCへの移行時のトラブルを大幅に減らすことができます。

原則1:外部ライブラリは遅延バインディングで使う

配布するマクロファイルには CreateObject() を使った遅延バインディングを徹底します。参照設定に依存しないコードにすることが、PC間互換性の第一条件です。

原則2:ファイルパスは ThisWorkbook.Path を基準にする

マクロファイルからの相対的な位置でファイルを参照することで、フォルダごと移動しても動作するポータブルな構成を実現します。

原則3:バージョン分岐を入れる

Application.Version でExcelバージョンを確認し、新機能を使うコードには必ずバージョン分岐を入れます。

原則4:環境依存の値を設定シートで管理する

フォルダパス・サーバー名・ユーザー設定などの環境依存の値はコードにハードコードせず、設定シートのセルから取得するように設計します。

原則5:移行前に環境診断マクロを実行する

' ========================================
' 移行前チェック:マクロが別PCで動くかどうかを事前に確認する
' ========================================
Sub PreMigrationCheck()

    Dim issues  As String
    Dim ok      As Boolean
    ok = True

    ' --- 参照設定のMISSINGチェック ---
    Dim vbProj As Object
    Dim refs   As Object
    Set vbProj = ThisWorkbook.VBProject
    Set refs   = vbProj.References

    Dim i As Integer
    For i = 1 To refs.Count
        If refs.Item(i).IsBroken Then
            issues = issues & "MISSING参照: " & refs.Item(i).Name & vbCrLf
            ok = False
        End If
    Next i

    ' --- ハードコードパスのチェック(簡易) ---
    ' ※ 実際の検査はコードレビューで行う必要がある

    ' --- Excelバージョン確認 ---
    issues = issues & "Excelバージョン: " & Application.Version & vbCrLf

    ' --- 外部アプリ確認 ---
    issues = issues & "Outlook: " & IIf(OutlookIsAvailable(), "OK", "未インストール") & vbCrLf

    ' --- フォント確認 ---
    issues = issues & "デフォルトフォント: " & Application.StandardFont & vbCrLf

    ' --- 結果表示 ---
    Dim resultMsg As String
    If ok Then
        resultMsg = "移行前チェック完了。参照設定に問題はありません。" & vbCrLf & vbCrLf
    Else
        resultMsg = "注意:以下の問題が見つかりました。" & vbCrLf & vbCrLf
    End If

    MsgBox resultMsg & issues, _
           IIf(ok, vbInformation, vbExclamation), _
           "移行前チェック結果"

    Set refs   = Nothing
    Set vbProj = Nothing

End Sub

別PCでのデバッグ手順

ステップ1:エラーメッセージと番号を記録する

別PCで発生したエラーのメッセージ・番号・発生箇所のスクリーンショットを撮って記録します。エラー番号から原因を絞り込む手がかりになります。

ステップ2:参照設定ダイアログを確認する

VBAエディタ(Alt+F11)→「ツール」→「参照設定」を開き、「MISSING:」で始まる項目がないか確認します。

ステップ3:環境診断マクロを実行する

前述の「DiagnoseEnvironment」マクロと「DiagnoseReferences」マクロを別PCで実行して結果をシートに出力し、作成PCの環境と比較します。

ステップ4:エラー発生行を特定してOn Error Resume Nextで切り分ける

' ========================================
' 別PCでエラーが出る行を特定するデバッグコード
' ========================================
Sub DebugOnAnotherPC()

    Dim errLog As String
    errLog = "=== デバッグログ ===" & vbCrLf

    ' ステップごとにOn Error Resume Nextで囲んでどこでエラーが出るかを記録
    On Error Resume Next

    ' ステップ1:参照設定が必要なオブジェクト作成
    Dim obj1 As Object
    Set obj1 = CreateObject("Scripting.FileSystemObject")
    If Err.Number <> 0 Then
        errLog = errLog & "ステップ1エラー(FSO): " & Err.Description & vbCrLf
        Err.Clear
    Else
        errLog = errLog & "ステップ1 OK: FSOの作成成功" & vbCrLf
    End If

    ' ステップ2:ファイルパスの確認
    Dim testPath As String
    testPath = ThisWorkbook.Path & "\data.xlsx"
    Dim fileExists As Boolean
    fileExists = (Dir(testPath) <> "")
    errLog = errLog & "ステップ2 ファイル存在: " & fileExists & " (" & testPath & ")" & vbCrLf

    ' ステップ3:Excelバージョン確認
    errLog = errLog & "ステップ3 Excelバージョン: " & Application.Version & vbCrLf

    ' ステップ4:フォント設定
    Dim testCell As Range
    Set testCell = ActiveSheet.Range("A1")
    testCell.Font.Name = "游ゴシック"
    If Err.Number <> 0 Then
        errLog = errLog & "ステップ4エラー(フォント): " & Err.Description & vbCrLf
        Err.Clear
    Else
        errLog = errLog & "ステップ4 OK: フォント設定成功" & vbCrLf
    End If

    On Error GoTo 0

    ' ログをシートに出力
    Dim ws As Worksheet
    Set ws = ThisWorkbook.Sheets.Add
    ws.Range("A1").Value = errLog
    ws.Columns("A").ColumnWidth = 100

    MsgBox "デバッグログを新しいシートに出力しました。", vbInformation
    Set ws = Nothing

End Sub

別PCで動かない原因チェックリスト

マクロを別のPCに移したとき、以下のリストを順番に確認してください。

  • VBAエディタの「ツール」→「参照設定」を開いて 「MISSING:」と表示されているライブラリがないか確認したか
  • 外部ライブラリへのアクセスを 遅延バインディング(CreateObject) に書き換えているか
  • コード内に 「C:\Users\ユーザー名」などの絶対パスがハードコードされていないか
  • ファイルパスは ThisWorkbook.Path を基準とした相対的な参照になっているか
  • 別PCの Excelバージョンが作成PCと同じかを確認したか(Application.Version で確認)
  • 新機能(xlCSVUTF8・スパークライン・LET関数など)を使っている場合、バージョン分岐を入れているか
  • 別PCで マクロが有効化されているか(黄色いバーの「コンテンツの有効化」を押したか)
  • ファイルが 保護ビュー(Protected View)で開かれていないか(「編集を有効にする」が必要)
  • 企業のPCで グループポリシーによってマクロが全面禁止されていないか(IT管理者に確認)
  • 特定の フォント名をハードコードしていないか(別PCにないフォントは代替フォントになるかエラー)
  • プリンター名をハードコードしていないか(別PCには同名プリンターが存在しない場合がある)
  • Outlook・Access・IEなどの 外部アプリが別PCにインストールされているか確認したか
  • IEオブジェクトを使ったコードがある場合、XMLHTTPRequest等の代替手段に書き換えているか
  • ネットワークドライブのパスをドライブレター(Z:\ など)で書いていないか(UNCパスを使う)
  • 日付・数値の文字列変換で 地域設定(ロケール)に依存した書き方をしていないか(DateSerial・Formatを使う)
  • マクロファイル自体が .xlsm形式で保存されているか(.xlsxでは動かない)

まとめ

Excelマクロが別のPCで動かない原因は、ほぼすべて「作成したPC固有の環境に依存したコードが含まれている」という一点に集約されます。本記事の要点をまとめます。

  • 参照設定の切れ(MISSING):外部ライブラリへのアクセスは CreateObject() を使った遅延バインディングに書き換える。参照設定の状態は「DiagnoseReferences」マクロで診断できる
  • ハードコードされたパス:ファイルパスは ThisWorkbook.Path を起点に組み立てる。環境依存の値は設定シートで管理してコードから分離する
  • Excelバージョン差異Application.Version でバージョンを確認し、新機能を使うコードには分岐処理を入れる。「DiagnoseEnvironment」マクロで両PC間の差異を比較する
  • セキュリティ設定:別PCでマクロが実行できない場合は「コンテンツの有効化」「編集を有効にする」の操作が必要。企業PCではグループポリシーによる制限の場合はIT管理者に相談する
  • フォント・プリンター:フォント名は優先順位付きリストで存在確認してから設定する。プリンターはハードコードせずダイアログや既定プリンターを使う
  • 外部アプリ連携:Outlook・Access・IEの存在確認をしてから使う。IEは廃止環境ではXMLHTTPRequestに切り替える
  • 事前検証:移行前に「PreMigrationCheck」マクロを実行して問題を洗い出し、移行後に「DebugOnAnotherPC」マクロで発生箇所を特定する

「自分のPCでは動く」マクロを「どのPCでも動く」マクロにするためのキーワードは、遅延バインディング・動的パス解決・バージョン分岐・設定の外部化の4つです。本記事で紹介したコードをそのまま活用し、移行時のトラブルゼロを目指してください。