【入門編】【属性制御】Attributesプロパティ操作による読み取り専用・隠しファイルの属性変更とロック解除 – VBScript (Visual Basic Scripting Edition)解析バイブル

スポンサーリンク

こんにちは!VBScriptの世界へようこそ。
業務自動化の現場で「マクロの記録」から一歩抜け出し、真の自動化エンジニアを目指すあなたにとって、ファイルシステムを自由自在に操る技術は強力な武器になります。

今回は、ファイルシステムオブジェクト(FSO)の中でも、多くのエンジニアが一度はハマる「ファイルの属性制御(Attributesプロパティ)」について深く掘り下げていきましょう。

「プログラムからファイルを上書き保存しようとしたら、なぜか『書き込みできません』というエラー(Permission denied)が出た……」
そんな絶望的な状況を華麗に解決する、プロの知見をお伝えします。ここをクリアすれば、ファイル操作の引き出しが一気に広がりますよ!

—

1. なぜ「読み取り専用ファイル」の更新でエラーになるのか?

Windowsのファイルには、そのファイルの状態を示す「属性(Attributes)」というメタデータが備わっています。
例えば、以下のようなフラグが存在します。

  • 読み取り専用 (Read-only):うっかり上書きするのを防ぐ
  • 隠しファイル (Hidden):通常のフォルダ一覧に表示させない
  • システムファイル (System):OSの動作に必要な重要ファイル

VBScriptでファイルを自動処理する際、配布された設定ファイルやログファイルが「読み取り専用」になっていると、FSOを使って書き込みを行おうとした瞬間に容赦なくエラーが発生します。

「じゃあ、書き込む前にプログラム側で属性を書き換えればいいじゃないか!」
その直感は大正解です。それを実現するのが、FSOの `Attributes` プロパティなのです。

—

2. 属性制御の核心:ビット演算の仕組み

FSOの `Attributes` プロパティは、単なる数字ではありません。複数の属性フラグが足し合わされた「ビットフラグ」として管理されています。

VBScriptでよく使われる定数は以下の通りです。

| 定数 | 値 (10進数) | 意味 |
| :— | :— | :— |
| `ReadOnly` | 1 | 読み取り専用 |
| `Hidden` | 2 | 隠しファイル |
| `System` | 4 | システムファイル |
| `Archive` | 32 | アーカイブ(変更されたファイル) |
| `Normal` | 0 | 通常のファイル(属性なし) |

ここで重要なのは、「現在の属性を壊さずに、特定の属性だけをON/OFFする」という技術です。単純に `file.Attributes = 1` などと代入してしまうと、元々ついていた「隠しファイル」などの属性が消えてしまいます。

ここに、プログラミングの妙味があります。ビット演算(ANDとOR)を使って、安全に属性をコントロールするのです。

—

3. 実践!安全な属性変更とロック解除スクリプト

それでは、現場でそのまま使える実用的なコードを見ていきましょう。
今回は、「読み取り専用(ReadOnly)」のファイルに対して、一時的にその属性を外し、データを書き込んだ上で、再び「読み取り専用」に戻すという、極めて堅牢なスクリプトを作成します。

‘ =================================================================0
‘ スクリプト名: ChangeAttributeSample.vbs
‘ 概要: 読み取り専用ファイルの属性を一時解除して書き込み、元に戻すサンプル
‘ =================================================================0

Option Explicit

Sub UpdateReadOnlyFile()
Dim fso, filePath, targetFile
Set fso = CreateObject(“Scripting.FileSystemObject”)

‘ テスト用のファイルパス(環境に合わせて書き換えてください)
filePath = “C:\Automation\sample_config.txt”

‘ 1. ファイルの存在確認
If Not fso.FileExists(filePath) Then
WScript.Echo “エラー: 指定されたファイルが存在しません。” & vbCrLf & filePath
Exit Sub
End If

‘ 2. ファイルオブジェクトの取得
Set targetFile = fso.GetFile(filePath)

‘ 3. 現在の属性をデバッグ表示(ビット演算の確認)
WScript.Echo “【処理前】現在の属性値: ” & targetFile.Attributes

‘ 4. 「読み取り専用」属性が設定されているか判定
‘ VBScriptではビットAND演算子 (And) を使ってフラグをチェックします
If (targetFile.Attributes And 1) = 1 Then
WScript.Echo “-> 読み取り専用ファイルです。一時的に解除します。”

‘ 読み取り専用フラグ (1) を「落とす」 (XOR または ビット演算の引き算)
‘ 安全のため、(元の属性 – 1) または NOT演算を使います
‘ ここではシンプルに ReadOnlyビットをクリアします
targetFile.Attributes = targetFile.Attributes – 1
Else
WScript.Echo “-> 通常ファイルのため、解除の必要はありません。”
End If

‘ 5. ファイルに書き込みを行う(テキスト追記の例)
Dim ts
‘ ForWriting (2) または ForAppending (8)
Set ts = targetFile.OpenAsTextStream(8, 0)
ts.WriteLine “【自動更新】 ” & Now & ” にデータを追記しました。”
ts.Close
Set ts = Nothing
WScript.Echo “-> ファイルの更新に成功しました。”

‘ 6. セキュリティと整合性のため、再び「読み取り専用」に戻す
‘ 読み取り専用フラグ (1) を再び「足す」
If (targetFile.Attributes And 1) = 0 Then
targetFile.Attributes = targetFile.Attributes + 1
WScript.Echo “【処理後】セキュリティのため、再度読み取り専用に設定しました。”
End If

‘ 7. クリーンアップ
Set targetFile = Nothing
Set fso = Nothing
WScript.Echo “すべての処理が正常に完了しました。”

End Sub

‘ メイン処理の実行
UpdateReadOnlyFile()

—

4. 初学者が陥りやすい罠とエラー対策

現場でこのコードを実装する際、よくある「つまずきポイント」を先回りして解説しておきます。

罠①:他の属性(隠しファイル等)が吹っ飛ぶ

先ほども触れましたが、単に `targetFile.Attributes = 0` などとやると、そのファイルが持っていた「隠しファイル属性」や「システム属性」がすべてリセットされ、予期せぬトラブルを引き起こします。
必ず 「足し算・引き算」 または 「ビット演算子(`Or`, `And`)」 を使って、ピンポイントでフラグを操作するようにしてください。

罠②:ファイルが別のプロセスに掴まれている (Permission Denied)

Attributesを外してもなおエラーが出る場合、大抵の原因は「他のアプリケーション(Excelやメモ帳など)がそのファイルを開いたままにしている」ことです。
VBScriptを実行する前に、必ず対象のファイルが閉じられていることを確認してください。

罠③:ネットワークドライブでの遅延

社内共有サーバー(NASなど)上のファイルに対してAttributesを変更する場合、ネットワークの応答速度によっては変更が即時反映されないことがあります。ファイル操作の直後は、少しウェイトを入れるか、エラーハンドリング(`On Error Resume Next`)を適切に組み合わせるのがプロの技です。

—

まとめ:ここをクリアすればVBScriptの基本はバッチリ!

今回は、FSOの `Attributes` プロパティを用いた高度なファイル制御について解説しました。

  • ファイルの属性は「ビットフラグ」の集合体であること
  • 単純代入ではなく、足し算・引き算(またはビット演算)で安全にON/OFFを切り替えること
  • 書き込み前後の「解除 ➔ 処理 ➔ 再設定」というライフサイクルを守ること

この概念を理解していれば、VBScriptに限らず、VBAやC#、VB.NETなどの他言語におけるファイルシステム操作にもそのまま応用できます。

「マクロの記録」の向こう側にある、本物のシステム自動化の世界へようこそ。
この調子で、あなたの業務をどんどんスマートに自動化していきましょう!