【VBA】Excelファイルを読み取り専用で開く・解除する方法(コピペOK)

VBA
スポンサーリンク
スポンサーリンク

この記事でできること

VBAでExcelファイルを読み取り専用で開く・解除する操作を自動化できるようになる。

対象:VBA初心者〜初級者。「共有フォルダのファイルを誤って上書きしたくない」「他の人が開いているファイルを安全に処理したい」という方向け。

コピペ → 実行まで5分。

どんな場面で使う?

  • 共有フォルダのマスターデータを参照するとき — 売上マスターや商品マスターなど、参照だけしたいファイルを誤って上書きしないように安全に開きたい
  • 複数人が同時にアクセスするExcelファイルの処理 — 他のユーザーが編集中かどうかを事前チェックし、ロック状態に応じて処理を分岐させたい
  • バッチ処理で大量のファイルからデータを抽出するとき — 読み取り専用で開けば他のユーザーの作業を邪魔せずにデータ取得できる
  • 経理・人事の集計マクロ — 部門ごとのファイルを順番に開いてデータを吸い上げる際、誤保存を防ぐ安全策として読み取り専用を標準にしたい
  • ファイルの編集権限を途中で切り替えるワークフロー — 最初は読み取り専用で内容を確認し、問題なければ編集モードに切り替えて修正・保存する運用

自分も共有フォルダのマスターデータを参照するだけのつもりが、うっかり上書き保存してしまい、慌てて元に戻したことがある。地味にストレスだったし、周りにも迷惑をかけた。VBAで「読み取り専用で開く」を標準にしてからは、そういう事故がゼロになった。この記事で、同じヒヤリを経験した人が安全なファイル操作を身につけられればうれしい。

Before / After

Before(手作業):

  • ファイルを開くときに読み取り専用を選び忘れる → 誤上書きのリスク
  • 他の人が開いているか分からず、保存時にエラー → やり直し

After(VBA自動化):

  • マクロが常に読み取り専用で開く → 誤上書きゼロ
  • 他ユーザーの使用状況を事前チェック → 安全に処理を分岐

手順

  1. Excelを開き、Alt + F11 でVBE(コードを書く画面)を開く
  2. メニューバーの 挿入 → 標準モジュール をクリック
  3. 下のコードをコピーして貼り付ける
  4. F5 キーで実行(またはマクロ実行画面から選択)

前提条件

– Excel 2016以降 / Microsoft 365

– Windows 10/11

– 保存形式:.xlsm(マクロ有効ブック)

– 貼り付け場所:標準モジュール

– 実行方法:マクロ実行(F5 または Alt + F8)

基本コード(読み取り専用で開く)

まずはファイルを読み取り専用で開く最小限のコード。


Sub OpenReadOnly()
    Dim filePath As String
    Dim wb       As Workbook

    ' ★ここにファイルパスを指定
    filePath = "C:\Users\Public\Documents\sample.xlsx"

    ' ファイルの存在確認
    If Dir(filePath) = "" Then
        MsgBox "ファイルが見つかりません。" & vbCrLf & filePath, vbExclamation
        Exit Sub
    End If

    ' 読み取り専用で開く
    Set wb = Workbooks.Open(Filename:=filePath, ReadOnly:=True)

    MsgBox wb.Name & " を読み取り専用で開きました。", vbInformation
End Sub

ポイント:

  • ReadOnly:=True を指定するだけで、読み取り専用で開ける。この1つの引数を追加するだけで、誤上書きのリスクがなくなる
  • 開いたブックを wb 変数に入れておくと、後の処理(データ取得・閉じるなど)で使いやすい。変数に入れずに ActiveWorkbook で参照すると、別のブックがアクティブになったときに誤操作の原因になる
  • Dir(filePath) でファイルの存在を事前に確認しているのは、存在しないパスを Workbooks.Open に渡すとランタイムエラーで止まるためだ。実務では共有フォルダのパスが変わることもあるので、この存在チェックは省略しない方がよい
  • ファイルの存在確認はファイルやフォルダの存在を確認してから処理する方法も参考にしてほしい

実務版コード(読み取り専用の判定・解除・ChangeFileAccess)

実務では「読み取り専用かどうかを判定して処理を分岐する」「読み取り専用を途中で解除する」といった操作が必要になる。自分はこの方法を覚えてからは、共有ファイルの参照マクロと編集マクロを安全に使い分けられるようになった。


Sub ReadOnlyControl()
    Dim filePath As String
    Dim wb       As Workbook

    ' ★ここにファイルパスを指定
    filePath = "C:\Users\Public\Documents\sample.xlsx"

    ' ファイルの存在確認
    If Dir(filePath) = "" Then
        MsgBox "ファイルが見つかりません。" & vbCrLf & filePath, vbExclamation
        Exit Sub
    End If

    ' === 読み取り専用で開く ===
    Set wb = Workbooks.Open(Filename:=filePath, ReadOnly:=True)

    ' === 読み取り専用かどうかを判定 ===
    If wb.ReadOnly Then
        MsgBox wb.Name & " は読み取り専用で開かれています。", vbInformation
    Else
        MsgBox wb.Name & " は編集可能な状態で開かれています。", vbInformation
    End If

    ' === 読み取り専用を解除する(編集可能に変更) ===
    ' 他のユーザーがファイルをロックしていない場合のみ有効
    On Error Resume Next
    wb.ChangeFileAccess Mode:=xlReadWrite
    If Err.Number <> 0 Then
        MsgBox "読み取り専用を解除できませんでした。" & vbCrLf & _
               "他のユーザーが編集中の可能性があります。", vbExclamation
        Err.Clear
        On Error GoTo 0
        wb.Close SaveChanges:=False
        Exit Sub
    End If
    On Error GoTo 0

    MsgBox wb.Name & " の読み取り専用を解除しました。" & vbCrLf & _
           "編集可能な状態です。", vbInformation

    ' ★ ここで必要な編集処理を行う

    ' === 保存して閉じる ===
    wb.Save
    wb.Close
End Sub

コード解説:

このコードは「読み取り専用で開く → 状態を判定 → 編集モードに切り替え → 編集 → 保存して閉じる」という一連のフローを1つのSubにまとめている。wb.ReadOnly プロパティで現在の状態を確認できるため、開いた直後に読み取り専用かどうかをユーザーに通知している。ChangeFileAccess Mode:=xlReadWrite が読み取り専用を解除するコア部分で、他のユーザーがファイルをロックしていなければ編集可能な状態に変わる。なぜ On Error Resume Next で囲んでいるかというと、ロック中のファイルに対して ChangeFileAccess を呼ぶとエラー1004が発生するためだ。このエラーを捕捉して、ロック中なら読み取り専用のまま閉じるという安全な分岐を実現している。

注意: ChangeFileAccessで編集モードに切り替えた後は、ファイルを上書き保存できる状態になる。実行前に対象ファイルのバックアップを取っておくことを推奨。

実務版コード2(他ユーザーが開いているか確認)

共有フォルダのファイルを処理するとき、「他の人が開いているかどうか」を事前にチェックできると安心。複数ブックを開かずにデータ取得する方法と組み合わせると、開けないときの代替処理も組める。


Sub CheckFileInUse()
    Dim filePath As String
    Dim fileNum  As Integer
    Dim inUse    As Boolean

    ' ★ここにファイルパスを指定
    filePath = "C:\Users\Public\Documents\sample.xlsx"

    ' ファイルの存在確認
    If Dir(filePath) = "" Then
        MsgBox "ファイルが見つかりません。" & vbCrLf & filePath, vbExclamation
        Exit Sub
    End If

    ' 他ユーザーが開いているかチェック
    inUse = IsFileInUse(filePath)

    If inUse Then
        MsgBox "他のユーザーが開いています。" & vbCrLf & _
               "読み取り専用で開きます。", vbExclamation

        ' 読み取り専用で開く
        Dim wb As Workbook
        Set wb = Workbooks.Open(Filename:=filePath, ReadOnly:=True)

        ' ★ 読み取り専用での処理(参照のみ)をここに書く

        wb.Close SaveChanges:=False
    Else
        MsgBox "ファイルは使用されていません。" & vbCrLf & _
               "編集モードで開きます。", vbInformation

        ' 編集モードで開く
        Dim wbEdit As Workbook
        Set wbEdit = Workbooks.Open(Filename:=filePath, ReadOnly:=False)

        ' ★ 編集処理をここに書く

        wbEdit.Save
        wbEdit.Close
    End If
End Sub

Function IsFileInUse(filePath As String) As Boolean
    Dim fileNum As Integer

    On Error Resume Next
    fileNum = FreeFile
    Open filePath For Binary Access Read Write Lock Read Write As #fileNum
    Close #fileNum

    If Err.Number <> 0 Then
        IsFileInUse = True
        Err.Clear
    Else
        IsFileInUse = False
    End If
    On Error GoTo 0
End Function

ポイント:

  • IsFileInUse関数は、ファイルを排他ロックで開こうとしてエラーが出るかどうかで判定する。VBAの Open 文で Lock Read Write を指定して開けるかどうかを試し、エラーが出れば「誰かが使っている」と判断する仕組みだ
  • 他ユーザーが開いている → 読み取り専用で開く、いなければ編集モードで開く、という分岐ができる。この分岐パターンは共有フォルダのファイルを扱うマクロの定番だ
  • なぜこの2段階チェックが必要かというと、Workbooks.OpenReadOnly:=False を指定しても他ユーザーがロック中なら結局読み取り専用で開かれてしまい、保存時にエラーになる。事前にチェックして処理を分けておけば、ユーザーに状況を明確に伝えられる
  • Excelファイルを自動で開いて処理して閉じる方法と組み合わせると、バッチ処理の安全性が上がる

落とし穴

# 症状 原因 対策
1 ReadOnly:=Trueで開いたのに上書き保存できてしまう SaveAsで別名保存するとそのブックは編集可能になる。ChangeFileAccessで途中で解除されている可能性もある 読み取り専用で開いた後に編集しない運用を徹底する。またはwb.Saved = Trueで変更なし扱いにして閉じる
2 ChangeFileAccessで「実行時エラー 1004」が出る 他のユーザーがファイルを排他ロック中。または共有フォルダのアクセス権限が不足 On Error Resume Nextでエラーを捕捉し、ロック中の場合は読み取り専用のまま処理する
3 「’sample.xlsx’は編集のためロックされています」ダイアログが出る Workbooks.Openで読み取り専用を指定していないとき、他ユーザーがファイルを開いているとこのダイアログが表示される ReadOnly:=Trueを明示的に指定すれば、ダイアログなしで読み取り専用で開ける
4 IsFileInUse関数がExcelファイルで正しく判定できない Excelは独自のロック機構(~$ロックファイル)を使うため、Open文での判定が期待通りにならないケースがある ロックファイル(~$で始まるファイル)の存在をDirで確認する方法を併用する
5 読み取り専用で開いたブックを閉じるときに「保存しますか?」が出る 読み取り専用でもセルの計算結果が変わると「変更あり」と判定される wb.Close SaveChanges:=Falseで保存せずに閉じる。ブックの保存・閉じる操作を自動化する方法も参照
6 ファイル属性の「読み取り専用」とExcelの「読み取り専用」の違いが分からない ファイル属性の読み取り専用(GetAttrでvbReadOnly)はOS側の設定。Excelの読み取り専用(wb.ReadOnly)はExcelが開く際のモード。両者は別物 OS側の読み取り専用属性を変更するにはSetAttrを使う。Excelの読み取り専用モードはChangeFileAccessで変更する

自分も最初、ファイル属性の「読み取り専用」とExcelの「読み取り専用で開く」が同じだと思い込んでいて、SetAttrで属性を外してもExcelで編集できず混乱した。この2つは別物だと知るまでに無駄な時間を使った。

VBAで読み取り専用が解除できないときの対処法

「ChangeFileAccessで読み取り専用を解除しようとしたが実行時エラー1004が出る」という場合、原因は他のユーザーがファイルを排他ロックで開いているか、共有フォルダのアクセス権限が書き込みを許可していないことだ。まずエクスプローラーでファイルと同じフォルダに ~$ファイル名.xlsx というロックファイルが存在するか確認する。ロックファイルがあれば誰かが編集中なので、その人がファイルを閉じるまで待つ必要がある。アクセス権限の問題なら、フォルダのプロパティ→セキュリティタブで書き込み権限を確認する。

VBAでファイルがロックされていて開けないときの対処法

「Workbooks.Openを実行すると『編集のためロックされています』ダイアログが出て処理が止まる」という場合、原因は ReadOnly:=True を指定していないことだ。引数なしで Workbooks.Open を呼ぶと、Excelはデフォルトで編集モードで開こうとし、ロック中のファイルに対してダイアログを表示する。対策として、参照目的で開く場合は必ず ReadOnly:=True を指定する。バッチ処理で大量のファイルを順番に開く場合は、事前に IsFileInUse 関数でロック状態をチェックし、ロック中なら読み取り専用、空いていれば編集モードで開く分岐を入れるのが安全だ。

FAQ

Q1. パスワード付きファイルを読み取り専用で開くには?

Password引数を追加する。ブックにパスワードを自動で設定・解除する方法も参考にしてほしい。


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

Q2. 読み取り専用で開いたブックからデータだけ取得して閉じたい

値を変数やシートにコピーしてから閉じる。


Set wb = Workbooks.Open(Filename:=filePath, ReadOnly:=True)
ThisWorkbook.Sheets("Sheet1").Range("A1").Value = wb.Sheets(1).Range("A1").Value
wb.Close SaveChanges:=False

Q3. ファイル属性の読み取り専用を解除するには?

SetAttr関数を使う。


' 読み取り専用属性を外す
SetAttr filePath, GetAttr(filePath) And Not vbReadOnly

Excelの「読み取り専用で開く」とは別の操作なので注意。

Q4. 複数ファイルをまとめて読み取り専用で開くには?

Dir関数でループする。


Dim f As String
f = Dir("C:\Users\Public\Documents\*.xlsx")
Do While f <> ""
    Workbooks.Open Filename:="C:\Users\Public\Documents\" & f, ReadOnly:=True
    f = Dir()
Loop

Q5. 読み取り専用を推奨するダイアログを表示させるには?

ファイルの「読み取り推奨」プロパティを設定する。


' 保存時に読み取り推奨を設定
ActiveWorkbook.SaveAs Filename:=filePath, ReadOnlyRecommended:=True

次回開くときに「読み取り専用で開きますか?」ダイアログが表示される。

まとめ

この記事では、VBAでExcelファイルを読み取り専用で開く・解除する方法を解説した。

  • 基本コードReadOnly:=Trueで安全にファイルを開く
  • 実務版:読み取り専用の判定・ChangeFileAccessでの解除・エラーハンドリング
  • 他ユーザーチェックIsFileInUse関数でロック状態を事前確認

共有フォルダのファイルを扱うマクロでは、読み取り専用の制御は必須スキルだ。自分の経験上、「読み取り専用で開く」を標準にしてからファイル事故がゼロになった。まずは基本コードの ReadOnly:=True を覚えるだけでも十分効果がある。その上で、他ユーザーのロック状態チェックや ChangeFileAccess による切り替えを組み合わせれば、チーム全員が同じファイルを安全に扱えるマクロが作れる。Excelファイルを自動で開いて処理して閉じる方法ブックの保存・閉じる操作を自動化する方法と組み合わせると、安全で堅牢なファイル処理マクロが作れる。

次にやりたくなること

コメント

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