1日30分。1ヶ月で10時間。これは、私が以前担当していた経理部で、各部署から送られてくる予算報告ファイルを手作業で「開き」、データをコピーし、名前を付けて「保存」していた時間だ。
ファイルが10個ならまだいい。しかし、拠点が50、100と増えるにつれ、この単純な動作が業務を圧迫し、本来行うべき分析業務の時間を奪っていく。
VBAを習得する最大のメリットは、こうした「ファイルを開く」「閉じる」「保存する」というOSレベルの操作をExcelに代行させられる点にある。
実務でVBAを組む際、最も頻繁に、そして最も慎重に扱うべきなのがファイル操作だ。
正しく制御できれば劇的な効率化が期待できる一方で、パスの指定を一つ間違えれば、重要なデータを上書きしてしまうリスクも孕んでいる。
筆者の経験では、VBAを始めたばかりの人が最初にぶつかる壁は「ファイルを開いた後の制御」だ。
「開くこと」はできても、開いた後にそのファイルをどう指定し、どう安全に閉じるか。
本稿では、15年の実務経験から導き出した、安全かつ高速なファイル操作の鉄則を共有したい。

- VBA ファイル操作 開く 保存の基本をマスターして転記作業を自動化する
- 絶対パスと相対パスの使い分けでメンテナンス性を高める
- FileDialogを使用してユーザーにファイルを選択させる方法
- 経理部の月次決算で役立つ複数ブックの一括集計シナリオ
- 営業部での日報作成:日付を付けて自動保存する仕組み
- 在庫管理システムとの連携:CSV形式での保存と文字化け対策
- FileSystemObject(FSO)を使ったより高度なファイル制御
- 読み取り専用やパスワード付きファイルをスマートに扱う
- VBAとGoogleスプレッドシートのファイル操作の挙動差
- 大規模データを扱う際の高速化とメモリ解放のテクニック
- VBAファイル操作に関するよくある質問(FAQ)
- 明日からの実務に取り入れる3ステップ
VBA ファイル操作 開く 保存の基本をマスターして転記作業を自動化する
VBAでファイル操作を行う際、中心となるのは「Workbooks」コレクションだ。
最も基本的なコードは、Workbooks.Open メソッドを使用して既存のブックを開くことだろう。
しかし、単に開くだけでは不十分だ。実務では「開いたブックを変数に格納する」というステップが欠かせない。
Sub BasicFileOpen()
Dim wb As Workbook
' ファイルを開いて変数wbにセットする
Set wb = Workbooks.Open("C:\Users\Tanaka\Desktop\2026年度_営業報告.xlsx")
' 開いたブックに対して操作を行う
Debug.Print wb.Sheets(1).Name
' 保存して閉じる
wb.Close SaveChanges:=True
End Sub
このコードで注目してほしいのは Set wb = Workbooks.Open(...) の部分だ。
筆者が社内研修で教えていると、初心者の多くは Workbooks.Open とだけ書き、その後の操作を ActiveWorkbook で行おうとする。
しかし、これは非常に危険だ。開く途中でユーザーが別のExcelをクリックしたり、アドインが勝手に別のブックをアクティブにしたりすると、操作対象が入れ替わってしまうからだ。
必ず変数に格納し、その変数を通じて操作する癖をつけてほしい。
ポイント: ファイルを開くときは必ずWorkbook型の変数にセットすること。これにより、どのブックを操作しているかが明確になり、予期せぬエラーを防ぐことができます。

次に「保存」だ。保存には Save と SaveAs の2種類がある。
上書き保存なら wb.Save、名前を付けて保存なら wb.SaveAs を使う。
実務でよく見かけるのは、保存時の確認ダイアログでマクロが止まってしまうケースだ。
これを防ぐには Application.DisplayAlerts = False を活用する。
ただし、処理が終わったら必ず True に戻すことを忘れてはいけない。
絶対パスと相対パスの使い分けでメンテナンス性を高める
コード内に 「C:\Users\Tanaka\…」 といったフルパスを直接書き込む(ハードコーディングする)のは、実務では「負債」になりかねない。
作成した本人のPCでは動いても、他の共有サーバーに移動させたり、同僚のPCで実行したりした瞬間に「ファイルが見つかりません」というエラー(実行時エラー 1004)を吐いて止まるからだ。
こうした事態を避けるために、ThisWorkbook.Path を活用すべきだ。
マクロが含まれているブックと同じフォルダにあるファイルを開く場合、以下のように記述する。
Sub OpenRelativePath()
Dim targetPath As String
' マクロブックと同じフォルダ内の「data」フォルダにあるファイルを指定
targetPath = ThisWorkbook.Path & "\data\売上マスタ.xlsx"
If Dir(targetPath) <> "" Then
Workbooks.Open targetPath
Else
MsgBox "ファイルが見つかりません:" & targetPath
End If
End Sub
ここで登場した Dir 関数は、ファイルが存在するかどうかを事前にチェックするためのものだ。
実務でよく見かけるのは、ネットワークの不調やファイル名の微差でエラーになるケース。
いきなり Open するのではなく、Dir で存在を確認してから処理に入るのが、プロの書く堅牢なコードと言える。
ある製造業の営業部でツールを配布した際、この ThisWorkbook.Path を使っていなかったために、100名以上のユーザーから一斉に「動かない」と連絡が来た苦い経験がある。
環境に依存しないパス指定は、配布用ツール作成の鉄則だ。

FileDialogを使用してユーザーにファイルを選択させる方法
常に同じ名前のファイルを開くわけではない場合、ユーザーにファイルを選んでもらうインターフェースが必要になる。
そこで使うのが Application.FileDialog だ。
これを使えば、Excel標準の「ファイルを開く」ダイアログをVBAから呼び出せる。
Sub SelectAndOpenFile()
Dim fd As FileDialog
Set fd = Application.FileDialog(msoFileDialogFilePicker)
With fd
.Title = "集計対象のファイルを選択してください"
.Filters.Clear
.Filters.Add "Excelファイル", ".xlsx; .xlsm"
.AllowMultiSelect = False ' 複数選択を禁止
If .Show = True Then
' 選択されたファイルを開く
Workbooks.Open .SelectedItems(1)
Else
MsgBox "キャンセルされました"
End If
End With
End Sub
この FileDialog の利点は、ユーザーがエクスプローラー形式で直感的にファイルを選べる点にある。
特に、月ごとにファイル名が変わる(例:「2026年06月度決算.xlsx」)ような業務では、コードを書き換える手間が省けるため重宝する。
経理部の月次締めなどで、過去のデータを参照したいときなどにも有効だ。
ポイント: .Filters.Add を使うことで、ユーザーが間違って画像ファイルやPDFファイルを選択できないように制限をかけるのが親切な設計です。

経理部の月次決算で役立つ複数ブックの一括集計シナリオ
ここからは具体的な業務シナリオを見ていこう。
まずは、経理部で各拠点から送られてきた12個の「経費報告書.xlsx」を一つのマスターファイルに集計する場面だ。
筆者の経験では、こうした作業はループ処理とファイル操作の組み合わせで真価を発揮する。
Sub ConsolidateReports()
Dim targetDir As String
Dim fileName As String
Dim mainWb As Workbook
Dim subWb As Workbook
Set mainWb = ThisWorkbook
targetDir = ThisWorkbook.Path & "\Reports\"
fileName = Dir(targetDir & "*.xlsx") ' 最初のファイル名を取得
Application.ScreenUpdating = False ' 画面更新を停止(高速化)
Do While fileName <> ""
' ファイルを開く
Set subWb = Workbooks.Open(targetDir & fileName)
' データのコピー(例:A2から最終行まで)
subWb.Sheets(1).Range("A2:E100").Copy _
Destination:=mainWb.Sheets("集計").Cells(Rows.Count, 1).End(xlUp).Offset(1)
' 保存せずに閉じる
subWb.Close SaveChanges:=False
' 次のファイル名を取得
fileName = Dir()
Loop
Application.ScreenUpdating = True
MsgBox "集計が完了しました"
End Sub
このコードは、指定したフォルダ内のExcelファイルを次々と開き、データを集計シートに貼り付けては閉じる、という動作を繰り返す。
12拠点分なら数秒で終わるだろう。
手作業で行えば、ファイルを開く、シートを探す、コピーする、閉じる、という一連の動作を12回繰り返さなければならない。
さらに、コピーし忘れや重複コピーといったヒューマンエラーのリスクも常につきまとう。
こうした定型業務こそ、VBAによるファイル操作の独壇場だ。

営業部での日報作成:日付を付けて自動保存する仕組み
次に、営業部などで毎日作成する日報を、特定のフォーマットで保存するケースを考える。
「20260608_営業日報_田中.xlsx」のように、日付と名前を自動的に付与して保存する仕組みだ。
保存を忘れたり、誤って上書きしたりするミスを防ぐことができる。
Sub SaveDailyReport()
Dim saveName As String
Dim saveDir As String
' 保存先のパス(マクロブックと同じフォルダの「日報」フォルダ)
saveDir = ThisWorkbook.Path & "\日報\"
' ファイル名を作成:YYYYMMDD_営業日報_名前.xlsx
saveName = Format(Date, "yyyymmdd") & "_営業日報_田中.xlsx"
' 既に同じファイルがあるかチェック
If Dir(saveDir & saveName) <> "" Then
If MsgBox("既に同名のファイルが存在します。上書きしますか?", vbYesNo) = vbNo Then
Exit Sub
End If
End If
' 名前を付けて保存
On Error Resume Next
ThisWorkbook.SaveAs Filename:=saveDir & saveName
If Err.Number <> 0 Then
MsgBox "保存に失敗しました。パスが正しいか、ファイルが別の人に開かれていないか確認してください。"
Else
MsgBox "保存完了:" & saveName
End If
On Error GoTo 0
End Sub
実務でよくあるトラブルとして、「同名のファイルを誰かが開いているために保存できない」というものがある。
これを考慮して、On Error Resume Next でエラーをトラップし、適切なメッセージを出すようにしている。
また、Format(Date, "yyyymmdd") を使うことで、常に最新の日付がファイル名に反映されるように工夫している。

在庫管理システムとの連携:CSV形式での保存と文字化け対策
3つ目の事例は、物流・在庫管理の現場だ。
Excelで管理している在庫データを、基幹システムにインポートするためにCSV形式で保存する。
この際、注意すべきは「形式」の指定だ。
Excelの通常の保存(xlOpenXMLWorkbook)ではなく、CSV形式(xlCSV)を指定する必要がある。
Sub ExportToCSV()
Dim wb As Workbook
Dim exportPath As String
Set wb = ThisWorkbook
exportPath = ThisWorkbook.Path & "\Export\Inventory_" & Format(Now, "hhnnss") & ".csv"
' CSV形式で保存
' FileFormat:=xlCSV (6) を指定
Application.DisplayAlerts = False
wb.Sheets("在庫データ").Copy ' 新しいブックにシートをコピー
With ActiveWorkbook
.SaveAs Filename:=exportPath, FileFormat:=xlCSV, CreateBackup:=False
.Close SaveChanges:=False
End With
Application.DisplayAlerts = True
MsgBox "CSV出力が完了しました:" & exportPath
End Sub
このコードでは、現在のブック全体ではなく、特定のシートだけを新しいブックとして切り出し、それをCSVとして保存している。
筆者が以前サポートしたある中小企業の物流センターでは、毎日手作業で「名前を付けて保存」からCSVを選んでいた。
しかし、たまに間違えて「Excelブック」のまま保存してしまい、基幹システムへの取り込みエラーを頻発させていた。
この作業をボタン一つで行えるようにしただけで、システム担当者の呼び出し回数は激減した。
注意点: CSVとして保存する際、セル内に「,(カンマ)」が含まれていると、データがずれる原因になります。事前に置換するか、ダブルクォーテーションで囲む処理を検討してください。
FileSystemObject(FSO)を使ったより高度なファイル制御
ここまで紹介した Dir 関数や Workbooks.Open は便利だが、フォルダの作成やファイルの移動、詳細な属性取得などを行うには限界がある。
そこで登場するのが FileSystemObject(以下FSO)だ。
FSOは、Windowsのファイルシステムを直接操作するための強力なライブラリである。
FSOを使うには、VBEの「ツール」→「参照設定」から「Microsoft Scripting Runtime」にチェックを入れるのが一般的だが、ここでは誰でもそのまま動かせる「実行時バインディング」のコードを紹介する。
Sub FSO_FolderCheck()
Dim fso As Object
Set fso = CreateObject("Scripting.FileSystemObject")
Dim targetFolder As String
targetFolder = ThisWorkbook.Path & "\Backup"
' フォルダが存在しなければ作成する
If Not fso.FolderExists(targetFolder) Then
fso.CreateFolder (targetFolder)
MsgBox "バックアップ用フォルダを作成しました。"
End If
' ファイルのコピー
fso.CopyFile ThisWorkbook.FullName, targetFolder & "\Backup_" & Format(Now, "yyyymmdd_hhnnss") & ".xlsm"
End Sub
FSOのメリットは、コードの読みやすさと機能の豊富さだ。
「フォルダがあるか?」「なければ作る」といった操作が直感的に書ける。
筆者の経験では、大規模な自動化ツールを作る際は、Dir よりも FSO を好んで使う。
特に、サブフォルダの中まで再帰的にファイルを探すような処理では、FSOなしでは実現が難しい。
読み取り専用やパスワード付きファイルをスマートに扱う
実務の現場では、自分以外の誰かがファイルを開いていることが多々ある。
また、機密保持のためにパスワードがかかっていることもあるだろう。
これらを考慮せずに Workbooks.Open を実行すると、マクロは途中で止まってしまう。
読み取り専用で開く場合は、引数 ReadOnly:=True を指定する。
もし書き込みが必要なのに誰かが開いている場合は、ReadOnly プロパティを確認して処理を分岐させるのがスマートだ。
Sub OpenWithCare()
Dim wb As Workbook
Dim path As String
path = "C:\Data\共有名簿.xlsx"
' パスワード付きファイルを、読み取り専用で開く
' 読み取り推奨メッセージも無視する
Set wb = Workbooks.Open(Filename:=path, _
ReadOnly:=True, _
Password:="P@ssw0rd123", _
IgnoreReadOnlyRecommended:=True)
If wb.ReadOnly Then
MsgBox "このブックは読み取り専用で開かれました。編集はできません。"
End If
End Sub
パスワードをコード内に直接書くことの是非はあるが、完全に自動化したい場合はこのように引数で渡すことができる。
ただし、セキュリティの観点からは、パスワードは別の暗号化されたファイルから読み込むか、実行時にユーザーに入力させるなどの工夫が望ましい。
VBAとGoogleスプレッドシートのファイル操作の挙動差
最近ではExcelだけでなくGoogleスプレッドシートを併用する職場も増えている。
Excel VBAに慣れた人がGoogle Apps Script(GAS)を触ると、ファイル操作の概念の違いに驚くだろう。
Excel VBAは「PC内のパス(住所)」を指定してファイルを探すが、クラウド上のGASは「ファイルID(固有の識別番号)」で指定するからだ。
| 機能 | Excel VBA | Google Apps Script |
|---|---|---|
| 指定方法 | C:\Users\… (パス) | 1a2b3c… (ファイルID) |
| ファイルを開く | Workbooks.Open | SpreadsheetApp.openById |
| 同時編集 | 排他制御(一人のみ書き込み) | 同時編集可能 |
| 保存の概念 | 明示的なSaveが必要 | 常にオートセーブ |
この違いは大きい。VBAでは「保存せずに閉じる」ことで変更を破棄できるが、スプレッドシートにはその概念がない。
また、VBAの Workbooks.Open はローカルファイルを物理的に読み込むため、ファイルサイズが大きいと時間がかかる。
一方で、OSの違い(WindowsかMacか)によってパスの区切り文字(\ か / か)が変わる問題もVBA特有の悩みだ。
マルチプラットフォームで運用する場合は、Application.PathSeparator を使って区切り文字を動的に取得するのが定石である。
大規模データを扱う際の高速化とメモリ解放のテクニック
「マクロを実行したらExcelが固まった」
「処理は終わったはずなのに動作が重い」
研修でよく受ける相談だ。ファイル操作を伴うマクロが遅い原因の多くは、画面の描画更新とブックの閉じ忘れにある。
まず、Application.ScreenUpdating = False は必須だ。
これだけで処理速度は2倍から5倍は変わる。
さらに、大量のファイルを開閉する場合、Excelのメモリ管理が追いつかなくなることがある。
以下の3点を意識してみてほしい。
- 不要なブックは
wb.Close SaveChanges:=Falseですぐに閉じる。 Set wb = Nothingでオブジェクト変数を明示的に解放する。- コピー&ペーストの後は
Application.CutCopyMode = Falseでクリップボードを空にする。
Sub HighSpeedProcess()
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual ' 再計算を停止
' --- ファイル操作のメイン処理 ---
Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = True
End Sub
特に xlCalculationManual は、数式が大量に入ったファイルを開く際に絶大な効果を発揮する。
開くたびに再計算が走るのを防げるからだ。
筆者が以前扱った30MBを超える重厚な集計ファイルでは、この一行を追加しただけで、実行時間が10分から1分に短縮された。
VBAファイル操作に関するよくある質問(FAQ)
Q1: ネットワーク上の共有フォルダのファイルが開けません。
A1: パスが「\\ServerName\Folder\」のようなUNCパスになっているか確認してください。また、ネットワークドライブ(Z:\など)を割り当てている場合、人によってドライブレターが異なるとエラーになります。UNCパスでの指定を推奨します。
Q2: 保存しようとすると「このファイル名は既に使用されています」と出ます。
A2: Application.DisplayAlerts = False を使って警告を非表示にするか、事前に Dir 関数でファイルの存在を確認し、Kill ステートメントで既存ファイルを削除してから保存してください。
Q3: マクロ実行中に「ファイルを選択」ダイアログでキャンセルするとエラーになります。
A3: FileDialog.Show の戻り値を判定してください。キャンセル時は False が返ります。If .Show = False Then Exit Sub のように記述して、処理を中断させるのが正解です。
Q4: 読み取り専用で開いたブックを上書き保存できますか?
A4: いいえ、できません。別の名前で SaveAs するか、一旦閉じて SetAttr 関数などでファイルの属性を変更してから開き直す必要があります。基本的には、開く前に属性を確認すべきです。
Q5: Excel 2016で作成したファイル操作マクロは、Microsoft 365でも動きますか?
A5: 基本的には動きます。ただし、OneDriveやSharePoint上のファイルを操作する場合、ローカルパスではなくURL(https://…)として認識されるケースがあり、従来の Dir 関数などが使えない場合があります。その際は、同期済みのローカルフォルダを指定するなどの工夫が必要です。
明日からの実務に取り入れる3ステップ
VBAによるファイル操作は、単なるプログラミングの知識を超えて、業務フローそのものを再設計する力を持っている。
まずは以下の3ステップから始めてみてほしい。
- 現状のパスを特定する: 毎日手作業で開いているファイルのフルパスをメモし、それを変数に格納することから始める。
- 「開いて閉じる」だけのマクロを作る: データの転記は後回しでいい。まずは複数のファイルをエラーなく順次開いて閉じる、という制御を
Dir関数で実装してみよう。 - 安全装置を組み込む:
DisplayAlertsやDirによる存在チェックを入れ、自分以外の誰かが使っても壊れない「堅牢さ」を意識する。
筆者が15年Excelを使い続けて確信しているのは、ツールは「完璧」である必要はないということだ。
まずは目の前の、たった一つのコピペ作業を自動化する。
そのためにファイルを開くコードを1行書く。
その積み重ねが、いずれ数時間かかる月次業務を、コーヒーを飲んでいる間に終わらせる魔法へと変わるのだ。
重要なのは、一歩踏み出す勇気。
まずは空のシートで、Workbooks.Open と打ち込んでみることからすべては始まる。
あなたが手にするのは、単なる自動化ツールではない。
自分自身と、そして共に働く仲間たちの「時間」という最も貴重なリソースなのだ。
Microsoft公式: Workbooks.Open メソッドによると、このメソッドには15もの引数が存在し、状況に合わせて細かな制御が可能です。
公式ドキュメントを読み解く力も、中級者への大きな一歩となるだろう。


コメント