【VBA】Excelファイルを自動で開いて処理して閉じる方法(コピペOK)

VBA
スポンサーリンク

記事ID: 073
タイトル: 【VBA】Excelファイルを自動で開いて処理して閉じる方法(コピペOK)
カテゴリ: ファイル操作
一次キーワード: VBA ファイルを開く 閉じる 自動
想定読者: 複数のExcelファイルを手作業で開いてデータを転記・集計している事務・管理職
検索意図: VBAでExcelファイルを自動で開いて処理して閉じる方法を知りたい
読者の悩み(1文): 毎月20個以上のExcelファイルを1つずつ開いてデータをコピーして閉じる作業が面倒すぎる
読了後にできること(1文): VBAでExcelファイルを自動で開いて必要なデータを取得し閉じるところまで自動化できる
前提条件:
  - Excel版: Excel 2016以降 / Microsoft 365
  - OS: Windows 10/11
  - 保存形式: .xlsm(マクロ有効ブック)
  - 貼り付け場所: 標準モジュール
  - 実行方法: マクロ実行(F5)またはボタン割り当て
更新日: 2026-03-11
スポンサーリンク

この記事でわかること

VBAでExcelファイルを自動で開いて処理して閉じる方法を、コピペで動くコード付きで解説します。

  • 対象:複数のExcelファイルを手作業で開いてデータを転記・集計している人
  • 所要時間:コピペ → 実行まで3分

完成イメージ

実行前(フォルダに各支店の売上報告ファイルがある状態):


C:\Data\売上報告\
  ├── 東京支店.xlsx  (B2セル: 1,500,000)
  ├── 大阪支店.xlsx  (B2セル: 1,200,000)
  └── 名古屋支店.xlsx(B2セル:   800,000)

実行後(集計シートにデータが揃った状態):

A B
東京支店.xlsx 1500000
大阪支店.xlsx 1200000
名古屋支店.xlsx 800000
合計 3500000

マクロを実行すると、フォルダ内のExcelファイルを1つずつ自動で開き、B2セルの値を集計シートに転記して閉じます。全ファイルの処理が完了したら合計値も表示されます。


自分も毎月の売上報告で、各支店から届く20個以上のExcelファイルを1つずつ開いて金額をコピーして閉じる作業を繰り返していました。1時間以上かかるうえに、コピーミスも怖かったです。

VBAでファイルを自動で開いて集計するようにしてからは、ボタンひとつで全支店のデータが集計シートに揃うようになりました。1時間が30秒になったのは衝撃でした。

同じように大量のExcelファイルを手作業で開いている人が、この記事で自動化の一歩を踏み出せたらうれしいです。複数ファイルの統合処理については複数Excelファイルを1つに統合する方法でも詳しく解説しています。


最小版:Excelファイルを開いて値を取得して閉じる

まずは最もシンプルな形です。1つのExcelファイルを開いて、特定セルの値を取得して、閉じるだけのコードです。


Sub ファイルを開いて値を取得()
    Dim filePath As String
    Dim wb As Workbook
    Dim val As Variant

    ' --- 開くファイルのパスを指定 ---
    filePath = "C:\Data\売上報告\東京支店.xlsx"

    ' --- ファイルの存在チェック ---
    If Dir(filePath) = "" Then
        MsgBox "ファイルが見つかりません: " & filePath, vbExclamation
        Exit Sub
    End If

    ' --- ファイルを開く ---
    Set wb = Workbooks.Open(filePath)

    ' --- B2セルの値を取得 ---
    val = wb.Sheets(1).Range("B2").Value

    ' --- ファイルを閉じる(保存しない) ---
    wb.Close SaveChanges:=False

    ' --- 取得した値を表示 ---
    MsgBox "B2の値: " & val, vbInformation
End Sub

ポイント

  • Workbooks.Open(filePath) でファイルを開き、戻り値をWorkbook変数に格納します
  • wb.Sheets(1).Range("B2").Value で開いたブックの1枚目のシートのB2セルの値を取得します
  • wb.Close SaveChanges:=False で変更を保存せずに閉じます。データを読むだけならFalseが安全です
  • Dir(filePath) でファイルの存在を事前に確認しています。パスが間違っているとWorkbooks.Openでエラーになるためです

読み取り専用で開く・パスワード付きファイルを開く

実務では「読み取り専用で開きたい」「パスワード付きファイルを開きたい」というケースがよくあります。

読み取り専用で開く


Set wb = Workbooks.Open(filePath, ReadOnly:=True)
  • ReadOnly:=True を付けると読み取り専用で開きます
  • 元ファイルを変更してしまうリスクがなくなるため、データを読むだけなら常にReadOnly:=Trueを推奨します

パスワード付きファイルを開く


Set wb = Workbooks.Open(filePath, Password:="abc123")
  • Password:= にパスワードを指定します
  • パスワードが違うとエラーになるため、エラー処理と組み合わせて使うのが安全です

更新リンクの確認ダイアログを抑制して開く


Set wb = Workbooks.Open(filePath, UpdateLinks:=0)
  • UpdateLinks:=0 でリンクの更新確認ダイアログを抑制します
  • 他のブックへのリンクを含むファイルを開くとき、ダイアログで処理が止まるのを防ぎます

組み合わせ例


Set wb = Workbooks.Open( _
    Filename:=filePath, _
    ReadOnly:=True, _
    UpdateLinks:=0, _
    Password:="abc123")

実務版:フォルダ内の全Excelファイルを開いて特定セルを集計し閉じる

※ 実行前にブックを上書き保存しておくと安心です。

毎月の集計作業がボタンひとつで完了するようになってからは、集計ミスもゼロになりました。正直もっと早く自動化すればよかったと思います。


Sub フォルダ内ファイル一括集計()
    Dim folderPath As String
    Dim fileName As String
    Dim filePath As String
    Dim wb As Workbook
    Dim wsResult As Worksheet
    Dim r As Long
    Dim total As Double
    Dim fileCount As Long

    ' --- 対象フォルダのパスを指定(末尾に \ を付ける) ---
    folderPath = "C:\Data\売上報告\"

    ' --- フォルダの存在チェック ---
    If Dir(folderPath, vbDirectory) = "" Then
        MsgBox "フォルダが見つかりません: " & folderPath, vbExclamation
        Exit Sub
    End If

    ' --- 集計結果を書き出すシートを準備 ---
    Set wsResult = ThisWorkbook.Sheets("Sheet1")
    wsResult.Cells.Clear
    wsResult.Range("A1").Value = "ファイル名"
    wsResult.Range("B1").Value = "B2の値"

    r = 2          ' データ書き込み開始行
    total = 0
    fileCount = 0

    ' --- 画面更新を停止して高速化 ---
    Application.ScreenUpdating = False

    ' --- エラー発生時もScreenUpdatingを復帰させるための処理 ---
    On Error GoTo ErrHandler

    ' --- フォルダ内のExcelファイルを順に処理 ---
    fileName = Dir(folderPath & "*.xlsx")
    Do While fileName <> ""
        filePath = folderPath & fileName
        fileCount = fileCount + 1

        ' --- ファイルを読み取り専用で開く ---
        On Error Resume Next
        Set wb = Workbooks.Open(filePath, ReadOnly:=True, UpdateLinks:=0)
        On Error GoTo ErrHandler

        If wb Is Nothing Then
            ' ファイルが開けなかった場合はスキップ
            wsResult.Cells(r, 1).Value = fileName
            wsResult.Cells(r, 2).Value = "(開けませんでした)"
            r = r + 1
        Else
            ' --- B2セルの値を集計シートに転記 ---
            ' ※ シートが存在しない場合はエラーになるため注意
            wsResult.Cells(r, 1).Value = fileName
            wsResult.Cells(r, 2).Value = wb.Sheets(1).Range("B2").Value

            ' --- 合計に加算(数値の場合のみ) ---
            If IsNumeric(wb.Sheets(1).Range("B2").Value) Then
                total = total + wb.Sheets(1).Range("B2").Value
            End If

            ' --- ファイルを閉じる(保存しない) ---
            wb.Close SaveChanges:=False
            Set wb = Nothing

            r = r + 1
        End If

        ' --- 進捗をステータスバーに表示 ---
        Application.StatusBar = "処理中... " & fileCount & "件目: " & fileName

        ' --- 次のファイルへ ---
        fileName = Dir()
    Loop

    ' --- 合計行を追加 ---
    wsResult.Cells(r, 1).Value = "合計"
    wsResult.Cells(r, 2).Value = total

    ' --- 後処理 ---
    Application.ScreenUpdating = True
    Application.StatusBar = False
    Set wsResult = Nothing

    If fileCount = 0 Then
        MsgBox "Excelファイルが見つかりませんでした", vbExclamation
    Else
        MsgBox fileCount & "ファイルを処理しました。合計: " & Format(total, "#,##0"), vbInformation
    End If
    Exit Sub

ErrHandler:
    ' --- エラー発生時も画面更新を必ず復帰 ---
    Application.ScreenUpdating = True
    Application.StatusBar = False
    If Not wb Is Nothing Then
        wb.Close SaveChanges:=False
        Set wb = Nothing
    End If
    Set wsResult = Nothing
    MsgBox "エラーが発生しました: " & Err.Description, vbCritical
End Sub

ポイント

  • Dir(folderPath & "*.xlsx") でフォルダ内のExcelファイルを列挙します。フォルダ内ファイル一覧を自動取得する方法も参考になります
  • ReadOnly:=True で読み取り専用で開くため、元ファイルを壊す心配がありません
  • On Error Resume Next でファイルが開けない場合のエラーを捕捉し、スキップして次のファイルに進みます。エラー処理の詳しい方法も参考にしてください
  • Application.ScreenUpdating = False で画面のちらつきを防ぎ、処理速度を大幅に向上させます
  • On Error GoTo ErrHandler でエラー発生時もScreenUpdating = Trueへの復帰と開いたファイルのCloseを確実に行います
  • Application.StatusBar で進捗状況を表示します。進捗表示の方法も参考になります
  • 転記先の行を動的に管理しています。最終行を正確に取得する方法を使えば、既存データの下に追記することも可能です

落とし穴

落とし穴1:ファイルパスが間違っていて「実行時エラー1004」になる

Workbooks.Open に存在しないパスを渡すと「実行時エラー1004」が発生します。

対策: Dir(filePath) でファイルの存在を事前に確認してからWorkbooks.Openを呼んでください。

落とし穴2:ファイルを閉じ忘れてメモリ不足になる

自分もループ内でCloseを入れ忘れて、開いたファイルが20個以上残り続け、最終的にExcelが固まったことがあります。エラーが発生した場合にCloseがスキップされるケースも危険です。

対策: ループ内で必ずwb.Close SaveChanges:=Falseを入れてください。さらにエラーハンドラ(On Error GoTo)内でもCloseを実行するようにしておくと安全です。実務版コードではこの対策を入れています。

落とし穴3:画面がちらついて処理が遅い

ファイルを開くたびに画面が切り替わるため、処理が遅くなり、見た目もちらつきます。

対策: 処理の最初にApplication.ScreenUpdating = Falseを入れ、最後にTrueに戻してください。処理速度が数倍〜数十倍になります。

落とし穴4:保存確認ダイアログが表示されて処理が止まる

wb.Closeの引数にSaveChangesを指定しないと、変更がある場合に「保存しますか?」のダイアログが表示され、処理が止まります。

対策: wb.Close SaveChanges:=False(保存しない)またはwb.Close SaveChanges:=True(保存する)を明示してください。

落とし穴5:リンクの更新確認ダイアログで処理が止まる

開くファイルに他のブックへのリンク(外部参照)が含まれている場合、「リンクを更新しますか?」のダイアログが表示されて処理が止まります。

対策: Workbooks.Open(filePath, UpdateLinks:=0)UpdateLinks:=0を指定してダイアログを抑制してください。

FAQ

Q1: 開いたファイルの特定のシートからデータを取得するには?

wb.Sheets("シート名").Range("A1").Value のように、Workbookオブジェクト経由でシート名を指定します。シート番号で指定する場合は wb.Sheets(1) のように数字を使います。

Q2: .xlsだけでなく.xlsxや.xlsmも対象にできる?

Dir関数のパターンを Dir(folderPath & "*.xls*") にすれば、.xls/.xlsx/.xlsm すべてが対象になります。ただし、.xlsmファイルを開くとマクロが含まれているため、セキュリティの警告が出る場合があります。

Q3: ファイルを開かずにデータを取得する方法はある?

あります。ExecuteExcel4Macroやパワークエリを使えば、ファイルを開かずにセルの値を取得できます。ただし制約があり、速度面や柔軟性ではWorkbooks.Openで開く方法の方が優れています。確実に動かしたいなら本記事の方法が安全です。閉じたままのデータ取得については閉じたブックからデータを取得する方法で解説しています。

Q4: 対象ファイルをダイアログで選びたい場合は?

Application.GetOpenFilename でファイル選択ダイアログを表示できます。戻り値はVariant型で、キャンセル時はFalseが返ります。


Dim filePath As Variant
filePath = Application.GetOpenFilename("Excelファイル,*.xlsx")
If filePath = False Then Exit Sub  ' キャンセルされた場合

Q5: 処理対象のフォルダをダイアログで選びたい場合は?

Application.FileDialog(msoFileDialogFolderPicker) でフォルダ選択ダイアログを表示できます。


Dim fd As FileDialog
Set fd = Application.FileDialog(msoFileDialogFolderPicker)
If fd.Show = -1 Then
    folderPath = fd.SelectedItems(1) & "\"
End If

まとめ

VBAでExcelファイルを自動で開いて処理して閉じる方法を解説しました。

操作 コード 備考
ファイルを開く Workbooks.Open(filePath) 戻り値をWorkbook変数に格納して操作
読み取り専用で開く Workbooks.Open(filePath, ReadOnly:=True) データ読み取りのみなら常に推奨
パスワード付きで開く Workbooks.Open(filePath, Password:="xxx") エラー処理と併用が安全
保存せず閉じる wb.Close SaveChanges:=False 読み取り専用で開いた場合に使用
保存して閉じる wb.Close SaveChanges:=True 変更を反映したい場合に使用
高速化 Application.ScreenUpdating = False 処理後に必ずTrueに戻すこと
  • 読むだけならReadOnly:=Trueで開くのが安全
  • ループ内では必ずCloseを入れてファイルを閉じる
  • ScreenUpdating = Falseで画面のちらつきを防ぎ高速化
  • エラーハンドラでScreenUpdatingの復帰とファイルのCloseを確実に行う

ファイルを開かずにデータを取得したい場合は閉じたブックからデータを取得する方法、複数ファイルのデータを1つにまとめたい場合は複数Excelファイルを1つに統合する方法も参考にしてください。

次にやりたくなること

関連記事

コメント

タイトルとURLをコピーしました