【VBA】正規表現(RegExp)を繰り返すときの注意事項
VBAで正規表現(RegExp)を使う際、見落としがちなのが「オブジェクト生成コスト」です。
特に繰り返し処理の中で使う場合、書き方によってはかなり動作が遅くなるかもしれません。
今回は、よくないNGパターンと改善方法を解説します。
よくあるNGパターン(サブプロシージャ化)
Function HasNumber(text As String) As Boolean
' NGパターン
Dim reg As Object
Set reg = CreateObject("VBScript.RegExp")
reg.Pattern = "\d+"
reg.Global = True
HasNumber = reg.Test(text)
End Function
Sub SampleNG()
' 呼び出す側
Dim i As Long
For i = 1 To 10000
If HasNumber("abc123") Then
' 何か処理
End If
Next i
End Subこの書き方の問題はシンプルで、
「HasNumberプロシージャが呼ばれるたびに RegExp を生成している」
という点です。
例えば、1万回ループすると1万回 CreateObjectされます。
そして、毎回COMオブジェクト生成はかなり重たい処理です。
結果として、
- 処理速度が大幅に低下
- 無駄なメモリ使用
につながります。
改善方法:モジュールレベルで使い回す
正規表現オブジェクトは「1回作って使い回す」が基本です。
' モジュールレベル
Private reg As Object
Function HasNumber(text As String) As Boolean
' OKパターン
' このプロシージャ内ではCreateObjectしない
reg.Pattern = "\d+"
reg.Global = True
HasNumber = reg.Test(text)
End Function
Sub SampleOK()
' 呼び出す側
' 最初に1回だけCreateObjectする
Set reg = CreateObject("VBScript.RegExp")
Dim i As Long
For i = 1 To 10000
If HasNumber("abc123") Then
' 何か処理
End If
Next i
End Subこのプログラムでは、呼び出す側で1回だけCreateObjectをしています。
regはモジュールレベルの変数にしているので、HasNumberプロシージャから参照することができます。
これならば何度もCreateObjectをすることなく、1度だけCreateObjectするので、処理速度の低下やメモリ使用を避けることができます。
正規表現(RegExp)で処理が遅いと感じたら、このポイントを確認してみてください。
