「ゴミ」を取り除き、純粋なロジックを取り出す。FSOと正規表現で極めるSQLクレンジング術
こんにちは。現場の荒波を乗り越えてきたエンジニアの皆さん、今日もコードを書いていますか?
「マクロの記録」を使って、Excelの操作を自動化することには成功した。けれど、いざ「外部ファイルからデータを読み込んで、複雑な加工をする」というフェーズに入ると、急に手が止まってしまう……。そんな経験はありませんか?
実は、そこが「単なる操作の自動化」から「真の業務自動化エンジニア」へと脱皮する境界線なんです。
今回は、実務で非常によく遭遇する「外部のSQLファイルから、コメント行や不要な改行を排除して、実行可能なクリーンなSQL文を抽出する」というタスクを題材に、VBScriptの核となる「FileSystemObject (FSO)」と、文字列操作の最強兵器「正規表現」を使いこなす方法を伝授します。
ここをクリアすれば、VBScriptの基本はバッチリですよ。一緒に進んでいきましょう。
1. なぜ「クレンジング」が必要なのか?
エンジニアの仕事は、常に「綺麗なデータ」を扱うことではありません。むしろ、「汚いデータ」をいかにして「綺麗な状態」に整えるかに、その価値の大部分が割かれます。
例えば、開発者が書いたSQLファイルには、以下のようなものが含まれていることがよくあります。
- `– この処理は重要` といった、メモ書きのコメント行
- `/* 複数行にわたる`
`詳細な説明 */` といった、ブロックコメント
- コードの可読性を上げるために挿入された、大量の空行や連続したスペース
これらをそのままプログラムに流し込んで動的にSQLを組み立てようとすると、意図しない改行で構文エラーになったり、文字列結合が複雑になりすぎてバグの温床になったりします。
そこで、「FSOでファイルを読み込み、正規表現で不要な部分を削ぎ落とす」という前処理(クレンジング)が必要になるのです。
2. 武器を揃えよう:FileSystemObject と RegExp
今回のミッションで使用する「武器」は2つです。
① FileSystemObject (FSO)
Windowsのファイルシステム(ファイルやフォルダ)を操作するためのオブジェクトです。「ファイルを開く」「中身を読み取る」「書き出す」といった、OSとの対話における門番のような存在です。
② RegExp (Regular Expression)
「正規表現」を扱うためのオブジェクトです。
「特定のパターン(例:`–` で始まる行)」を見つけ出し、それを一括で削除したり置換したりする、文字列操作のプロフェッショナルです。
3. 実装:SQLクレンジング・スクリプト
それでは、実際に動くコードを見てみましょう。このコードは、指定されたSQLファイルを読み込み、コメントと無駄な空白を除去して、メモリ上に「綺麗なSQL」を生成するものです。
' ==========================================================================
' SQL Cleansing Script (FSO & RegExp Edition)
' 概要: SQLファイルからコメント行およびブロックコメントを除去し、
' 不要な空白を整える。
' ==========================================================================
Option Explicit
' メイン処理
Sub Main()
Dim inputFilePath, cleanSQL
' --- 設定領域 ---
inputFilePath = "C:\temp\sample_query.sql" ' 読み込みたいSQLファイルのパス
' ----------------
On Error Resume Next ' エラーハンドリングの準備
' 1. ファイルの読み込み
cleanSQL = ReadAndCleanSQL(inputFilePath)
If Err.Number <> 0 Then
MsgBox "エラーが発生しました: " & Err.Description, vbCritical, "エラー"
Exit Sub
End If
On Error GoTo 0 ' エラーハンドリングを通常に戻す
' 2. 結果の出力 (ここではデバッグ用にMsgBoxで表示)
' ※ 実際の実務では、このcleanSQLをそのままDB接続オブジェクトへ渡します
If cleanSQL <> "" Then
MsgBox "クレンジング完了!" & vbCrLf & vbCrLf & "--- 結果 ---" & vbCrLf & cleanSQL, vbInformation, "成功"
Else
MsgBox "クレンジング後のSQLが空です。", vbExclamation, "警告"
End If
End Sub
' --------------------------------------------------------------------------
' 関数: ReadAndCleanSQL
' 引数: strPath (ファイルパス)
' 戻り値: クレンジング済みの文字列
' --------------------------------------------------------------------------
Function ReadAndCleanSQL(strPath)
Dim fso, ts, rawText
Dim regEx, patternList, i
' オブジェクトの生成
Set fso = CreateObject("Scripting.FileSystemObject")
' ファイルが存在するかチェック(プロの嗜みです)
If Not fso.FileExists(strPath) Then
Err.Raise 1, "ReadAndCleanSQL", "指定されたファイルが見つかりません: " & strPath
End If
' 1. FSOを使ってファイルを開き、中身を丸ごと読み込む
' ForReading = 1
Set ts = fso.OpenTextFile(strPath, 1)
rawText = ts.ReadAll
ts.Close
' 2. 正規表現オブジェクトの準備
Set regEx = CreateObject("VBScript.RegExp")
regEx.Global = True ' 見つかった全てに適用
regEx.IgnoreCase = True ' 大文字小文字を区別しない
regEx.MultiLine = True ' 行をまたぐ処理を許可
' 3. クレンジング・パターンの定義 (ここが心臓部です)
' パターン1: ブロックコメント /* ... */ を除去
' パターン2: シングルラインコメント -- ... を除去
' パターン3: 連続する空白や改行を整理
' ブロックコメント除去パターン (/* と */ の間にある全文字)
rawText = ExecuteRegex(regEx, rawText, "/\*[\s\S]*?\*/")
' シングルラインコメント除去パターン (-- 以降の行末まで)
rawText = ExecuteRegex(regEx, rawText, "--.*$")
' 余計な改行や連続する空白を1つのスペースに集約
rawText = ExecuteRegex(regEx, rawText, "\s+")
' 前後の余分な空白をトリム
ReadAndCleanSQL = Trim(rawText)
' オブジェクトの解放 (メモリ管理の重要ポイント)
Set ts = Nothing
Set fso = Nothing
Set regEx = Nothing
End Function
' --------------------------------------------------------------------------
' 補助関数: ExecuteRegex
' 正規表現の置換を簡潔に記述するためのヘルパー
' --------------------------------------------------------------------------
Function ExecuteRegex(regExObj, targetText, pattern)
regExObj.Pattern = pattern
ExecuteRegex = regExObj.Replace(targetText, " ") ' 置換後の文字列はスペース1つにする
End Function
' スクリプト実行
Main
4. コードの深層解説:何が起きているのか?
エンジニアとして大切なのは、「動いたからOK」ではなく「なぜ動いたか」を理解することです。
FSOのオブジェクト・ライフサイクル
コードの中で `Set fso = CreateObject(…)` としていますが、これはメモリ上に「ファイル操作専用の道具箱」を召喚するイメージです。使い終わったら `Set fso = Nothing` とすることで、その道具箱をメモリから返却します。大規模なバッチ処理では、この「使い終わったら片付ける」という作法が、メモリ不足を防ぐ鍵になります。
正規表現パターンの魔法
今回の肝となる3つのパターンを解剖しましょう。
1. `/\*[\s\S]*?\*/` (ブロックコメント除去)
- `/\*` と `\*/` で囲まれた部分をターゲットにします。
- `[\s\S]*?` の部分は、「空白(`\s`)とそれ以外の文字(`\S`)のいずれか」が「最短一致(`*?`)」で続くことを意味します。これを使わないと、ファイル内の最初から最後までのコメントが全部消えてしまうという悲劇が起こります。
2. `–.*$` (シングルラインコメント除去)
- `–` から始まり、行の終わり(`$`)までの全ての文字にマッチします。
3. `\s+` (空白の集約)
- `\s` はスペース、タブ、改行を指します。これが `+`(1回以上の繰り返し)にマッチすることで、バラバラな改行やスペースを、一括で「1つのスペース」にまとめ上げることができます。
5. 実務で陥りやすい「罠」と回避策
最後に、私が現場で何度も見てきた「失敗パターン」を共有しておきます。
① 文字コードの壁(UTF-8 vs Shift-JIS)
FSOの `OpenTextFile` は、実は UTF-8(BOMなし)の扱いに非常に弱い という弱点があります。もし読み込むSQLファイルがUTF-8で、日本語コメントが含まれている場合、文字化けが発生します。
- 対策: 現代的な開発現場では、SQLファイルは `Shift-JIS` で保存するか、もしUTF-8を扱う必要があるなら `ADODB.Stream` という別のオブジェクトを使用するのがプロの選択です。
② エラーハンドリングの欠如
ファイルが存在しない、あるいはファイルが他のプロセスによってロックされている(開かれっぱなし)場合、スクリプトは即座にクラッシュします。
- 対策: `If Not fso.FileExists(…)` による事前チェックと、`On Error Resume Next` を用いたエラー制御を必ずセットで行いましょう。
まとめ:一歩先のエンジニアへ
いかがでしたか?
単に「ファイルを開いて読み込む」だけでなく、正規表現という強力なロジックを組み合わせることで、「プログラムが扱いやすい形にデータを加工する」という高度な処理が可能になります。
「マクロの記録」は素晴らしい第一歩です。しかし、今回のように「オブジェクトの性質」や「データの構造」を意識してコードを書けるようになれば、あなたの自動化スキルは次元が変わります。
ここをクリアすれば、VBScriptの基本はバッチリですよ。
次は、このクレンジングしたSQLを、実際にデータベースへ接続して実行する工程に挑戦してみましょう。応援しています!
