【入門編】【初心者向け】TextStreamのCloseメソッドを安全に呼ぶためのExit Sub/Function時のリソース解放の基本パターン – VBScript (Visual Basic Scripting Edition)解析バイブル

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

「ファイルが開けない!」を防ぐ。VBScriptにおけるTextStream解放の極意

「プログラムは動いたけれど、次に実行しようとしたら『ファイルが他のプロセスで使用されているため…』と怒られてしまった」

もしあなたがそんな経験をしたことがあるなら、おめでとうございます。あなたは今、プログラミングにおけるもっとも重要な概念の一つである「リソースの管理」という壁に直面しています。

マクロの記録や、ネットで見つけたコードをコピーして動かす段階から一歩踏み出し、現場で「本当に信頼されるエンジニア」になるために。今日は、VBScriptのファイル操作における最大の落とし穴、TextStreamのClose(クローズ)とリソース解放について、その本質を深く、かつ分かりやすく紐解いていきましょう。

ここをクリアすれば、VBScriptの基本はバッチリですよ。

1. なぜ「Close」を忘れると致命的なのか?

VBScriptでファイルの中身を読み書きするとき、私たちは `FileSystemObject` (FSO) を使い、その中の `TextStream` というオブジェクトを通じてファイルにアクセスします。

ここで重要なイメージを持ってください。ファイル操作とは、OS(Windows)という巨大な図書館から「本(ファイル)」を借りてくる行為です。

1. Open: 図書館の受付で本を借りる。
2. Read/Write: 借りた本を読み、書き込む。
3. Close: 本を返却する。

もし、あなたが本を借りたまま、途中で「あ、別の用事を思い出した!」と言って(`Exit Sub` などで)立ち去ってしまったらどうなるでしょうか?

図書館のルールでは、「返却されていない本は、他の誰も手に取ることができない」ことになっています。これが、VBScriptで発生する「ファイルロック」の正体です。

陥りやすい「失敗パターン」

以下のコードを見てください。一見、正しく動いているように見えますが、非常に危険です。

' ❌ 危険なコードの例
Sub BadProcess()
    Dim fso, ts
    Set fso = CreateObject("Scripting.FileSystemObject")
    Set ts = fso.OpenTextFile("C:\temp\data.txt", 1) ' ファイルを開く

    ' 何らかの条件判定
    If Not FileExists(ts) Then 
        ' ここで処理を抜けてしまうと...
        Exit Sub ' ⚠️ 致命的!ts.Close が呼ばれず、ファイルがロックされたままになる!
    End If

    ' 本来の処理
    MsgBox ts.ReadLine
    
    ts.Close ' ここまで到達すればOKだが、途中で抜けると実行されない
    Set ts = Nothing
    Set fso = Nothing
End Sub

このコードでは、条件によって `Exit Sub` が実行されると、`ts.Close` を通り過ぎてしまいます。すると、そのプログラムが終了しても、Windowsは「まだ誰かがこのファイルを使っている」と誤認し続け、ファイルがロックされてしまいます。

2. プロが実践する「安全な解放」の黄金パターン

では、どうすればよいのでしょうか?
答えはシンプルです。「どんな理由で処理を抜けるときでも、必ず必ずCloseを通るように設計する」。これだけです。

これを実現するための、もっとも堅牢なパターンを紹介します。

✅ 黄金のテンプレート:エラーハンドリングとクリーンアップ

VBScriptには、現代的な言語にある `try…finally`(エラーが起きても必ず最後に実行する仕組み)がありません。そのため、「エラーが発生しても、最後の一箇所に集まってから去る」という設計思想が必要になります。

' ✨ プロフェッショナルな実装例
Sub SafeFileProcess()
    Dim fso, ts
    Dim filePath : filePath = "C:\temp\data.txt"

    ' 1. オブジェクトの初期化
    On Error Resume Next ' エラーが起きても止まらず、次の行へ進む(エラー制御の開始)
    Set fso = CreateObject("Scripting.FileSystemObject")
    
    ' ファイルが存在するかチェック
    If Not fso.FileExists(filePath) Then
        MsgBox "ファイルが見つかりません。"
        GoTo Cleanup ' ❌ Exit Sub ではなく、後述の「Cleanup」へジャンプさせる
    End If

    ' 2. ファイルを開く
    Set ts = fso.OpenTextFile(filePath, 1) ' 1 = ForReading
    If Err.Number <> 0 Then
        MsgBox "ファイルを開けませんでした: " & Err.Description
        GoTo Cleanup
    End If

    ' --- ここからメインの処理 ---
    MsgBox "ファイルの内容: " & ts.ReadLine
    ' --------------------------

    ' 3. 正常終了のための準備
    ' (特に追加の処理がなければ、そのままCleanupへ流れる)

' =========================================================
' 4. 【最重要】クリーンアップ・セクション
' ここは「Exit Sub」の代わりに、必ずここを通るように設計する
' =========================================================
Cleanup:
    ' エラー情報のクリア
    Err.Clear

    ' TextStreamの解放
    If Not ts Is Nothing Then
        ts.Close        ' ファイルを閉じる
        Set ts = Nothing ' メモリからオブジェクトを削除
    End If

    ' FSOの解放
    If Not fso Is Nothing Then
        Set fso = Nothing
    End If

    ' エラーが発生していた場合に通知したいならここで判定
    If Err.Number <> 0 Then
        MsgBox "予期せぬエラーが発生しました。"
    End If
End Sub

' ※注: VBScriptでは本来 GoTo は推奨されませんが、
' 構造化されていないVBScriptにおいて、リソース解放を確実に実行するためには
' この「一箇所に集約する」手法が極めて実用的です。

3. コードの深層:なぜ `Set obj = Nothing` まで必要なのか?

「`ts.Close` をすれば十分じゃないのか?」と思ったあなた。鋭いですね。
しかし、真のプロフェッショナルは `Set ts = Nothing` までセットで行います。これには明確な理由があります。

オブジェクトのライフサイクル

`ts.Close` は、「ファイル(本)を閉じる」行為です。
`Set ts = Nothing` は、「その本を手に持っている自分(オブジェクト)を消す」行為です。

VBScriptは「参照カウンタ」という仕組みでメモリを管理しています。オブジェクトが「まだ使われている」と判断されている限り、そのメモリは解放されません。
`Close` だけでは、オブジェクト自体はメモリ上に残り続けます。大量のファイルを扱うループ処理の中でこれを怠ると、メモリ使用量がじわじわと増えていく「メモリリーク」を引き起こし、最終的にシステムが不安定になる原因となります。

「Closeで窓を閉め、Nothingで部屋の電気を消す」。
このイメージを持っておけば、リソース管理で迷うことはありません。

まとめ:今日から使えるチェックリスト

新しいスクリプトを書くときは、心の中でこのチェックリストを唱えてください。

1. [ ] `Exit Sub` を安易に使っていないか?(使うなら、その前に必ず `Close` を呼んでいるか?)
2. [ ] `On Error Resume Next` を使ったら、適切にエラーをハンドリングしているか?
3. [ ] 処理の最後に、必ず `Close` と `Set … = Nothing` を書く「出口」を作っているか?

これらを意識するだけで、あなたの書くコードの品質は、初心者レベルから「プロのエンジニア」の領域へと劇的に進化します。

一歩ずつ、着実に。
リソースを制御できる者こそが、自動化の世界を支配するのです。応援していますよ!

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