こんにちは! VBScriptの世界へようこそ。
マクロの記録ボタンを押すだけの世界から一歩踏み出し、黒い画面(コマンドプロンプト)を自在に操る自動化のプロフェッショナルを目指すあなたへ。
今回は、VBScriptを使った実用的なコンソールUIのテクニック、「StdOut.Writeとキャリッジリターン(`Chr(13)`)を駆使した、同一行でのリアルタイム・プログレスバー表示」について徹底解説します。
「処理が動いているのか止まっているのか分からない…」
そんなイライラを解消し、黒い画面に美しく進捗率を表示するテクニックをマスターしましょう。ここをクリアすれば、あなたの書くスクリプトは一気に「プロのツール」の風格を帯びますよ!
—
1. なぜ「同一行のリアルタイム更新」が必要なのか?
VBScriptで大量のファイルを処理したり、重いループ処理を回したりするとき、よくやるのがこれですよね。
WScript.Echo “処理中…”
‘ 重い処理
WScript.Echo “完了しました。”
これだと、処理が「今どのへんなのか」が全く分かりません。ではといって、ループのたびに `WScript.Echo i` なんてやるとどうなるでしょう? コンソール画面には、改行を伴って数字が延々と滝のように流れていきます。ログとしては残るかもしれませんが、画面がすごい勢いで流れてしまい、目が回りますよね。
私たちが求めているのはこれではありません。
「同じ行の上で、`10%… 20%… 30%…` と数字やバーがリアルタイムに書き換わっていくスマートなUI」です。
これをVBScriptの標準機能だけで実現するのが、`WScript.StdOut.Write` と キャリッジリターン(`Chr(13)`)のコンビネーション技なのです。
—
2. 核心技術:キャリッジリターン(`Chr(13)`)の魔術
普段私たちが何気なく使っている「改行」は、実は歴史的な背景から2つの動作の組み合わせで出来ています。
1. 改行(LF: Line Feed / `Chr(10)`):カーソルを「下の行」に移動させる
2. 復帰(CR: Carriage Return / `Chr(13)`):カーソルをその行の「一番左(先頭)」に戻す
通常、`WScript.Echo` は自動的に末尾に改行(CR+LF)を付加します。だから次の行にいってしまうのです。
しかし、`WScript.StdOut.Write` を使うと、勝手に改行を行わない(今の位置にとどまる)出力を制御できます。
ここで出力の最後に `Chr(13)`(キャリッジリターン)だけを送り込むと、カーソルは「その行の先頭」に戻ります。その上から次の文字を出力すると……なんと、前の文字が上書きされるのです!
これが、画面をちらつかせずに同一行をリアルタイム更新するメカニズムの正体です。
—
3. 実装コード:動かして体感するプログレスバー
それでは、実際の現場でそのままコピペして使える完全版のコードを見てみましょう。
メモ帳に貼り付けて、拡張子を `.vbs` (例: `progress.vbs`)で保存してください。
> ⚠️ 超重要ポイント(WSHの実行お作法)
> このスクリプトは、Windows標準の `WScript.exe` ではなく、コマンドプロンプト上で動く `CScript.exe` で実行する必要があります。
> コマンドプロンプトを開き、以下のように実行してください。
> `cscript progress.vbs`
‘ ==============================================================================
‘ ファイル名: progress.vbs
‘ 概要: CScript環境でStdOut.WriteとChr(13)を使い、同一行にプログレスバーを描画する
‘ ==============================================================================
Option Explicit
Sub ShowProgressBar()
Dim totalSteps, i, percent, barLength, filled, empty, bar, message
Dim startTime, elapsed, j
totalSteps = 50 ‘ 仮想的な処理の総ステップ数
barLength = 30 ‘ プログレスバーの全体の文字数
WScript.StdOut.WriteLine “=== 処理を開始します ===”
startTime = Timer
For i = 1 To totalSteps
‘ — 1. 進捗率とバーの計算 —
percent = Int((i / totalSteps) 100)
filled = Int((i / totalSteps) barLength)
empty = barLength – filled
‘ バーの見た目を生成(例: [██████———-])
bar = String(filled, “█”) & String(empty, “-“)
‘ — 2. 出力文字列の組み立て —
‘ 右側にスペースパディングを入れることで、文字数が減ったときの残像を防ぐ
message = “[” & bar & “] ” & Right(” ” & percent, 3) & “% (” & i & “/” & totalSteps & “)”
‘ — 3. 同一行への上書き出力の魔法 —
‘ Chr(13) で行頭に戻し、WScript.StdOut.Write で改行せずに書き込む
WScript.StdOut.Write message & Chr(13)
‘ — 4. 処理を疑似的に再現するためのウェイト —
‘ 実際の業務ではここフックに重いファイル処理やAPI通信などを挟みます
For j = 1 to 500000: Next
Next
‘ — 5. 終了処理 —
‘ ループが終わると最後の行で止まるため、最後に明示的に改行(WriteLine)を入れる
WScript.StdOut.WriteLine “”
WScript.StdOut.WriteLine “=== すべての処理が完了しました! 経過時間: ” & FormatNumber(Timer – startTime, 2) & “秒 ===”
End Sub
‘ 実行
ShowProgressBar()
—
4. コードの深掘り・知見の共有
ここで、エンジニアとして知っておくべき「現場のツボ」をいくつか解説しておきます。
① なぜ `WScript.Echo` ではなく `WScript.StdOut.Write` なのか?
`WScript.Echo` はダイアログボックス(ポップアップ)を出力する能力も持っているため、コンソール出力の制御においては少しお節介です。一方、`WScript.StdOut` は純粋な標準出力ストリームを直接操作するため、改行の有無や出力バッファの制御を完全にプログラマの意図通りに行えます。
② 残像を防ぐパディングの技術
コンソール上で文字を上書きするとき、「前回の文字列より今回の文字列の方が短い」と、行の末尾に前回の文字の残骸が残ることがあります。
今回のコードでは `Right(” ” & percent, 3)` や、バーの長さを常に固定(`barLength = 30`)にすることで文字数が常に一定になるよう設計しています。こういう細かい配慮が、ツール自体の「品質」を高めるんです。
③ 実行時のトラップ:「WScriptで実行しちゃった!」
初心者が一番ハマるのが、エクスプローラーからダブルクリックして `.vbs` を実行してしまうケースです。これだとデフォルトの `WScript.exe` が動くため、`StdOut` が使えずエラー(または何も起きない)になります。
必ずコマンドプロンプトから `cscript.exe` 経由で叩くか、スクリプトの先頭で強制的に `CScript` で再起動させるお馴染みの防御コードを仕込んでおくと完璧ですね。
—
まとめ
いかがでしょうか?
今回は、VBScriptの標準出力とキャリッジリターンを駆使して、コンソール画面をリッチに彩るプログレスバーの実装方法を解説しました。
「たかが進捗率」と思うかもしれませんが、こうした視覚的なフィードバックがあるだけで、ツールを使うユーザー(あるいは未来の自分)のストレスは劇的に軽減されます。「動いてるのかフリーズしてるのか分からない不安」をコードで解消できるエンジニアは、まぎれもなく優秀な自動化スペシャリストです。
ここをクリアしたあなたなら、もっと高度なログ出力やエラーハンドリングも難なくマスターできるはず。
ぜひ、日々の業務自動化スクリプトにこのテクニックを組み込んで、まわりを驚かせてみてくださいね! それでは、良きVBScriptライフを!
