「自分のPCでは完璧に動くExcelマクロが、別のPCに持っていったら動かない」――このトラブルは、VBAを業務で使っている現場で非常によく起きる問題です。エラーメッセージも「実行時エラー ‘1004’」「参照が不正または修飾されていません」「オブジェクトはこのプロパティまたはメソッドをサポートしていません」など様々で、一見すると原因が分かりにくいものばかりです。しかし原因は大きく分類すると参照設定の違い・ファイルパスのハードコード・Excelバージョンの差異・セキュリティ設定・環境依存の記述のいずれかに集約されます。本記事では、別のPCでマクロが動かなくなるすべての主要パターンを、その場でコピーして使える修正コードとともに体系的に解説します。
目次
- 別PCで動かない原因の全体像
- 原因1:参照設定が切れている(MISSING)
- 原因2:ファイルパスがハードコードされている
- 原因3:ExcelバージョンによるAPI・関数の違い
- 原因4:セキュリティ設定によるマクロ無効化
- 原因5:フォント・プリンター依存の記述
- 原因6:外部アプリケーション連携(Outlook・Access・IEなど)
- 原因7:OS・環境変数・ユーザー名依存の記述
- 早期バインディングと遅延バインディングの使い分け
- 別PCでも動くポータブルなコードを書く原則
- 別PCでのデバッグ手順
- 別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つです。本記事で紹介したコードをそのまま活用し、移行時のトラブルゼロを目指してください。