VBScriptを掌握せよ:全半角混在文字列を「バイト単位」で安全に切り詰める極意
業務自動化の現場において、VBScriptは「古い」と揶揄されることがある。だが、Windows環境においてランタイム不要で即座に動作するその軽量さは、今なお最強の武器だ。
特に、データベースや固定長ファイル、あるいはGUIのラベル表示といった「物理的な制約」がある場所で、全角・半角が混在する文字列を扱う際、安易な `Left` 関数で済ませていないだろうか? もしそうなら、あなたのシステムは遅かれ早かれ「文字化け」という地雷を踏むことになる。
今日は、プロフェッショナルとして守るべき「バイト単位の厳密な文字列操作」の極致を伝授する。
—
なぜ `Len` や `Left` ではいけないのか
VBScriptの `Len` や `Left` は「文字数(グリフ)」を基準に計算を行う。しかし、Windowsの表示領域やDBのカラム長は「バイト数」で制限されていることが多い。
- 半角:1バイト
- 全角:2バイト
この混在環境で `Left` を使うと、全角文字の半分だけを切り取ってしまい、表示不可のバイナリが生成される。これが「文字化け」の正体だ。我々は、メモリ上のバイト表現を正しく制御しなければならない。
—
プロダクション品質の「TruncateByByte」関数
以下は、私が長年の開発現場で「標準ライブラリ」として使い続けてきた、堅牢な切り詰め関数だ。これをモジュールに組み込むだけで、文字列操作の安全性は劇的に向上する。
‘——————————————————————————-
‘ 関数名: TruncateByByte
‘ 概要: 指定バイト数を超えた場合、末尾を「…」で置換して切り詰める
‘ 引数: strTarget – 対象文字列
‘ iMaxByte – 最大バイト数(3バイト以上の余裕が必要)
‘ 戻り値: 整形済み文字列
‘——————————————————————————-
Function TruncateByByte(strTarget, iMaxByte)
Dim iLen, iTotalByte, i, strChar, iCharByte
‘ 異常系ガード: 指定バイト数が小さすぎる場合はそのまま返す
If iMaxByte < 3 Then
TruncateByByte = strTarget
Exit Function
End If
' LenBとMidBを使い、バイト数で判定する
iTotalByte = LenB(StrConv(strTarget, vbFromUnicode))
' 指定バイト数以下ならそのまま返す
If iTotalByte <= iMaxByte Then
TruncateByByte = strTarget
Exit Function
End If
' 必要なバイト数までループし、文字列を構築
' 「…」を付与するため、実質的な最大長は iMaxByte - 2 となる
Dim iLimit: iLimit = iMaxByte - 2
Dim strResult: strResult = ""
Dim iCurrentByte: iCurrentByte = 0
For i = 1 To Len(strTarget)
strChar = Mid(strTarget, i, 1)
' 文字単位のバイト数を取得(半角=1, 全角=2)
iCharByte = LenB(StrConv(strChar, vbFromUnicode))
If (iCurrentByte + iCharByte) > iLimit Then
‘ 残り枠に収まらない場合は三点リーダーを付けて終了
TruncateByByte = strResult & “…”
Exit Function
End If
strResult = strResult & strChar
iCurrentByte = iCurrentByte + iCharByte
Next
TruncateByByte = strResult
End Function
—
コードの設計思想:ここが「プロ」のこだわりだ
このコードには、単なる実装以上の意図が込められている。
1. `StrConv(strTarget, vbFromUnicode)` の活用:
VBScriptの内部文字列はUnicode(2バイト固定)だが、外部(ファイルやDB)に出力する際はANSIやShift-JISに変換される。`LenB` でバイト数を測る前に `vbFromUnicode` を通すことで、実際にファイル書き出し時に消費されるバイト数を正確に見積もっている。
2. ガード節の徹底:
`iMaxByte < 3` のような異常系を先頭で弾くことで、後続の複雑なロジックを無駄に走らせない。これはパフォーマンスの鉄則だ。
3. 状態管理の最小化:
フラグ変数を乱用せず、ループ内で完結させることで、メモリリークや意図しない副作用を排除している。
—
実務での活用アドバイス
- DB連携時: SQLの `INSERT` や `UPDATE` 文を作成する際、この関数を必ず通すこと。入力値チェックをフロントエンド(画面)だけに任せるのは脆弱性の温床だ。
- ファイル出力: CSV出力時に、各フィールドの長さをこの関数で制限すれば、Excelで開いたときに列が崩れる事故を100%防げる。
- 保守性の担保: この関数を `Common.vbs` のような共通ライブラリファイルに切り出し、`ExecuteGlobal` または `Include` 相当のテクニックで読み込むことで、修正箇所を一箇所に限定できる。
最後に
VBScriptを「古い」と切り捨てるのは簡単だ。しかし、この枯れた技術を「いかに正確に制御するか」という視点こそが、真のエンジニアを分かつ境界線となる。
自動化エンジニアよ、細かい処理にこそ魂を込めよ。その細部へのこだわりが、あなたの構築する業務システムを「誰が触っても壊れない」堅牢な城へと変えるのだ。
