【テクニカル・上級編】【初心者向け】DateCreatedプロパティを利用した「本日生成された提出ファイル」のみを自動ピックアップするVBS – VBScript (Visual Basic Scripting Edition)解析バイブル

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

境界を超えて:`DateCreated`を制御し、日次ファイル処理を「堅牢」に変える技術的真髄

業務自動化の世界において、「今日作成されたファイルをコピーする」というタスクは、一見すると初歩的な演習に過ぎない。しかし、現場の最前線でシステムを運用するエンジニアにとって、その「初歩」こそが、最も多くのバグとリソースリーク、そして予期せぬシステム停止を招く戦場であることを、君は知っているだろうか。

単に `DateCreated` プロパティを比較するだけのスクリプトは、レガシーな環境や大規模なファイルシステムにおいては、精度不足によるデータ欠損や、COMオブジェクトの解放漏れによるメモリ圧迫を引き起こす。

本稿では、FileSystemObject(FSO)を用いたファイル操作を、単なる「動くコード」から、プロフェッショナルが設計する「堅牢な自動化資産」へと昇華させるための、極限の知見を伝授する。

1. 陥りやすい「時間精度の罠」:Date型比較の真実

初心者が最初に直面する、そして最も致命的なミスは、`DateCreated` と `Date` の比較における「型と精度の不一致」だ。

VBScriptにおける `Date` 関数は、現在の日付を返すが、その内部的な値は「時刻 00:00:00」を保持している。一方で、`File.DateCreated` は、秒単位、あるいはそれ以下の精度を持つタイムスタンプを保持している。

' --- 致命的な間違い ---
If File.DateCreated = Date Then 
    ' この条件が真になるのは、ファイルが「ちょうど午前0時0分0秒」に作成された時のみである。
    ' 実運用では、ほぼ確実に失敗する。
End If

これを回避するためには、日付部分のみを抽出する `Int()` 関数、あるいは `DateValue()` 関数を用いて、比較の粒度を「日」に揃える必要がある。これが、エンジニアとしての「正確性」への第一歩だ。

2. オブジェクトのライフサイクルとメモリの最適化

VBScriptはCOM(Component Object Model)上で動作している。FSOのような強力なオブジェクトを扱う際、我々が意識すべきは、そのライフサイクル(生存期間)である。

ループ処理の中でオブジェクトを生成し、適切に破棄(`Set obj = Nothing`)しない行為は、メモリリークの温床となる。特に、数万個のファイルをスキャンするようなバッチ処理において、この微細な管理不足が、長期間稼働するサーバーのメモリをじわじわと食いつぶし、最終的なシステムダウンを招く。

「使い終わったら、即座に、確実に、明示的に解放する」。これは、レガシー環境の保守において、黄金律として刻まれておくべき作法だ。

3. 実装:プロフェッショナル・グレードの自動ピックアップ・スクリプト

以下に、実務でそのまま投入可能な、堅牢性を重視したスクリプトを提示する。このコードには、エラーハンドリング、リソース管理、そして正確な日付比較が組み込まれている。

' ==============================================================================
' Script Name: DailyFilePicker.vbs
' Description: 本日作成されたファイルを抽出し、指定ディレクトリへコピーする
' Author: Legendary Chief Architect
' ==============================================================================
Option Explicit

' --- 設定領域 ---
Const SRC_DIR     = "C:\Data\Incoming\"      ' 監視対象フォルダ
Const DEST_DIR    = "C:\Data\DailyBackup\"   ' コピー先フォルダ
Const LOG_FILE    = "C:\Data\Logs\process.log" ' 実行ログ

' --- メインルーチン ---
Call Main()

Sub Main()
    Dim fso, srcFolder, destFolder, file, targetDate
    Dim copyCount : copyCount = 0
    
    ' 1. インスタンス生成
    Set fso = CreateObject("Scripting.FileSystemObject")
    
    ' 2. 存在チェック(防御的プログラミング)
    If Not fso.FolderExists(SRC_DIR) Then
        Err.Raise 1, "Main", "Source directory not found: " & SRC_DIR
    End If
    
    If Not fso.FolderExists(DEST_DIR) Then
        ' コピー先がなければ作成する(必要に応じて)
        fso.CreateFolder(DEST_DIR)
    End If

    ' 比較対象となる「本日」の日付(時刻を切り捨てた純粋な日付値)
    targetDate = Date 

    On Error Resume Next ' エラーハンドリング開始

    Set srcFolder = fso.GetFolder(SRC_DIR)
    
    ' 3. ファイル走査
    For Each file In srcFolder.Files
        ' DateCreatedの時刻部分をInt関数で切り捨て、日付のみで比較
        If Int(file.DateCreated) = targetDate Then
            
            ' コピー実行(上書き許可: True)
            ' ファイルがロックされている場合などのエラーを考慮
            file.Copy DEST_DIR & file.Name, True
            
            If Err.Number = 0 Then
                copyCount = copyCount + 1
            Else
                ' エラーログ出力(本来は詳細なエラー内容を記録すべき)
                WriteLog "ERROR: Failed to copy " & file.Name & " - " & Err.Description
                Err.Clear
            End If
            
        End If
    Next

    ' 4. 後処理とリソース解放(重要!)
    WriteLog "SUCCESS: Process completed. Copied " & copyCount & " files."

    ' オブジェクトの明示的解放
    Set srcFolder = Nothing
    Set fso = Nothing
    
    On Error GoTo 0
End Sub

' --- ユーティリティ:ログ出力 ---
Sub WriteLog(msg)
    Dim fso, logFile
    Set fso = CreateObject("Scripting.FileSystemObject")
    ' 追記モード (8) でオープン
    Set logFile = fso.OpenTextFile(LOG_FILE, 8, True)
    logFile.WriteLine "[" & Now & "] " & msg
    logFile.Close
    Set logFile = Nothing
    Set fso = Nothing
End Sub

4. システム間連携とレガシー環境への洞察

このスクリプトを運用する際、シニアエンジニアとして考慮すべきは「実行環境のコンテキスト」だ。

Windows APIへの昇華

もし、スキャンするファイル数が数百万件を超え、FSOのパフォーマンスがボトルネックとなる場合、我々はVBScriptの限界を認めるべきだ。その時こそ、`GetFileTime` などの Windows API を直接叩く C++ プログラムや、より高速な I/O 操作が可能な PowerShell / .NET への移行を検討するタイミングである。VBScriptは「手軽な自動化」には最適だが、「極限のパフォーマンス」を求める領域では、設計の判断ミスが致命傷となる。

権限とロックの管理

ファイルコピーにおいて、対象ファイルが他のプロセス(Excelやシステムプロセス)によって開かれている場合、`file.Copy` はエラーを吐く。本スクリプトでは `On Error Resume Next` を用いて、一つのエラーがバッチ全体の停止を招かないよう設計しているが、これは「エラーを無視している」のではなく、「エラーを制御下に置いている」ことを意味する。

結論

「今日作成されたファイルをコピーする」という単純なロジックの背後には、日付精度の管理、メモリのライフサイクル、そして例外処理という、エンジニアリングの真髄が詰まっている。

コードを書くとき、常に自問せよ。
「このスクリプトは、1年後の、あるいは100万個のファイルが投入された環境でも、正しく、静かに、リソースを浪費せずに動き続けるか?」

その問いに対する答えこそが、君を単なるプログラマーから、伝説的なアーキテクトへと変えるのだ。

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