こんにちは!VBScriptの世界へようこそ。
業務自動化の現場で、ExcelマクロやWSH(Windows Script Host)を使ったシステム組立てに奮闘していませんか?
「何万件ものログデータやCSVデータをVBScriptで読み込んだはいいが、特定のデータを検索する処理を入れた途端、画面が固まったようにフリーズしてしまう……」
そんな絶望を味わったことはありませんか?
今回は、そんなパフォーマンスの壁を軽々と超える「二分探索(バイナリサーチ)」の極意を伝授します。ここをクリアすれば、あなたの書くVBScriptは見違えるほど高速になり、周囲をあっと言わせるプロの仕上がりになりますよ。
さあ、基礎から本質まで、一緒にしっかりとマスターしていきましょう!
—
1. なぜ「線形検索」では数万件のデータに太刀打ちできないのか?
まず、私たちが普段やりがちな「前から順番に探していく方法」――これを線形検索(リニアサーチ)と呼びます。
[ 探したい値: 85 ]
[ 10 ] -> [ 25 ] -> [ 40 ] -> [ 60 ] -> [ 85 ] (5番目でやっと発見!)
データが100件程度ならこれでも一瞬です。しかし、これが5万件あったらどうでしょう?運悪くお目当てのデータが一番最後尾にあった場合、コンピュータは5万回もしらみつぶしに確認作業を行います。VBScriptのようなインタプリタ言語(一行ずつ解釈しながら実行する言語)にとって、このループ処理の乱用は致命傷になり得ます。
救世主「二分探索(バイナリサーチ)」の仕組み
ここで登場するのが二分探索です。
ただし、これには「あらかじめデータが昇順(小さい順)に並び替えられていること」という絶対条件があります。
辞書で「プログラミング」という単語を引くとき、1ページ目から順にめくる人はいませんよね?大体真ん中あたりを開いて、「あ行だからもっと前だな」「た行だから後ろだな」と、範囲を半分に絞り込んでいくはずです。あれがまさに二分探索の本質です。
[ 10件の整列済みデータ ]
1. まん中(5番目)を見る → 探したい値より「大きい」
2. 後半の半分を捨てる! 残りの前半(1〜4番目)だけで再度まん中を見る
3. これを繰り返すと、最大でも 4〜5回 の比較だけでデータが見つかる!
データが 50,000件 あっても、二分探索を使えば、たったの 17回前後 の比較で目的のデータにたどり着きます。すごくないですか?
—
2. 実装の全体像:VBScriptによる超高速バイナリサーチ
それでは実際のコードを見てみましょう。
今回は、あらかじめ整列された数万件のデータ(を模擬した配列)の中から、指定した値を一瞬で探し出すスクリプトを作成しました。
メモ帳を開いて、以下のコードを `binary_search.vbs` という名前で保存し、ダブルクリックして実行してみてください。
‘ =================================================================0
‘ 脚本名: BinarySearchSample.vbs
‘ 概要: 大規模整列済み配列に対する二分探索(バイナリサーチ)の実装例
‘ =================================================================Option Explicit
Sub Main()
Dim targetValue, resultIndex
Dim maxCount, i
maxCount = 50000 ‘ 5万件のデータを想定
WScript.Echo “【準備】” & maxCount & “件の整列済み配列を生成中…”
‘ 1. テスト用の整列済み配列を作成 ( 2, 4, 6, 8, … という偶数の配列)
Dim arrData()
ReDim arrData(maxCount – 1)
For i = 0 To maxCount – 1
arrData(i) = (i + 1) 2
Next
‘ 2. 検索テスト
‘ 存在しない値 (例: 77777) や、存在する値 (例: 8888) を指定
targetValue = 8888
WScript.Echo “【検索開始】 ” & targetValue & ” を探しています…”
‘ 計測開始
Dim startTime
startTime = Timer
‘ ★ここに二分探索の神髄がある
resultIndex = BinarySearch(arrData, targetValue)
‘ 計測終了
Dim endTime
endTime = Timer
‘ 3. 結果の表示
If resultIndex <> -1 Then
WScript.Echo ” -> 発見成功! インデックス番号 [” & resultIndex & “], 値: ” & arrData(resultIndex)
Else
WScript.Echo ” -> 指定されたデータは見つかりませんでした。”
End If
WScript.Echo “処理時間: ” & FormatNumber(endTime – startTime, 4) & ” 秒”
End Sub
‘ —————————————————————–
‘ 関数名: BinarySearch
‘ 引数1: arr (整列済み配列)
‘ 引数2: val (探したい値)
‘ 戻り値: 見つかったインデックス (見つからない場合は -1)
‘ —————————————————————–
Function BinarySearch(arr, val)
Dim low, high, mid
low = LBound(arr) K ‘ 配列の最小インデックス(通常は0)
high = UBound(arr) ‘ 配列の最大インデックス
Do While low <= high ' VBScriptでは整数除算 \ を使うことで、安全に中央インデックスを算出する mid = low + (high - low) \ 2 If arr(mid) = val Then ' 的中! BinarySearch = mid Exit Function ElseIf arr(mid) < val Then ' 探している値の方が大きいので、探索範囲を「右半分」に絞る low = mid + 1 Else ' 探している値の方が小さいので、探索範囲を「左半分」に絞る high = mid - 1 End If Loop ' ループを抜けたら見つからなかった証拠 BinarySearch = -1 End Function ' メイン処理の実行 Main() ---
3. コードのキモを解説!ここがエンジニアの腕の見せ所
① 整数除算オペレータ `\` の重要性
コード内で `mid = low + (high – low) \ 2` という計算をしています。
ここで通常の割り算記号 `/` ではなく、あえて `\`(バックスラッシュ:整数除算) を使っているのがポイントです。
VBScriptで `/` を使うと、結果が自動的に浮動小数点数(Double型)になってしまい、配列のインデックスとして指定したときにエラーや予期せぬ挙動を引き起こす原因になります。配列のインデックスを扱うときは常に整数であるべきです。ここ、実務で非常によくあるハマりどころなので覚えておいて損はありません!
② 変数のスコープとメモリ管理 (`Option Explicit`)
先頭に書かれている `Option Explicit` は、すべての変数の宣言を強制するお呪いです。
VBScriptはデフォルトでは変数宣言なしでも動いてしまいますが、タイポ(スペルミス)によるバグの温床になります。プロフェッショナルへの第一歩として、必ずファイルの一番上に書きましょう。
—
4. 現場でよくある「落とし穴」とエラー対策
二分探索を実務に導入する際、以下の罠に引っかかる人が後を絶ちません。あらかじめ回避策を押さえておきましょう。
- 罠1:データがソート(昇順並び替え)されていない
- 対策: 二分探索は「並びがバラバラのデータ」に対して使うと100%誤った結果を返します(見つかるはずのデータが見つからない等)。もしデータが未整理なら、事前にソート処理を挟むか、素直に別の方法を検討してください。
- 罠2:配列が空(要素数0)の場合のエラー
- 対策: `UBound` や `LBound` を使うため、配列が初期化されていない状態で関数に放り込むと「プロシージャの呼び出しまたは引数が不正です」というエラーが発生します。必要に応じて `If IsArray(arr) Then …` などのガード節を入れましょう。
—
まとめ
いかがでしたでしょうか?
今回は大容量配列に対する超高速検索アルゴリズム「二分探索」について、VBScriptの作法を交えて解説しました。
「マクロの記録」から一歩進み、こうしたアルゴリズムの引き出しを持つことで、あなたの自動化スクリプトは「動くだけのスクリプト」から「堅牢で高速なシステム」へと生まれ変わります。
ここをクリアできれば、VBScriptの基礎はもうバッチリです!
ぜひ、日々の業務効率化にこの知見を取り入れて、周囲を驚かせてみてくださいね。それでは、次のステップでお会いしましょう!
