No Programming, No Life

プログラミング関連の話題や雑記

VBAでメッセージフォーマット

f:id:fumokmm:20200504205857p:plain

VBAの標準関数にメッセージフォーマットしてくれる関数が無いような気がしたので書きました。 エラー処理などは省略していますので、実用の際は適当に拡張してお使い下さい。

概要

メッセージをフォーマッティングしたいとき、テンプレートとなる文字列を用意しておいて、 可変となる部分に埋め込みパラメータを入れておいて置換していく関数です。 VBAなどで標準モジュール内に関数を入れておけば、例えばExcelで使う場合などは ワークシート関数としても利用可能となります。 サンプルは利用例をご覧ください。

仕様

  • 埋め込みパラメータは "{}" とします (Logback風)
  • 第1引数にテンプレートメッセージを指定(必須)
  • 第2引数以降に埋め込むパラメータを指定(可変長, 0個でも可)

ソース

Option Explicit

'''
' MessageFormat関数
' パラメータ埋め込みメッセージフォーマッティング処理
'
' 処理概要:
'   テンプレート文字列に対して、パラメータを埋め込んだメッセージを返却します。
'     ・テンプレート中のパラメータ埋め込み部分(プレースホルダ)は "{}" で記述します
'     ・プレースホルダは登録順に引数の埋め込みパラメータ分、置換されていきます
'
' 引数:
'   x_templateMessage - テンプレートメッセージ
'   x_params          - 埋め込みパラメータ
'
Function MessageFormat(ByVal x_templateMessage As String, ParamArray x_params() As Variant) As String
    Dim p_pos As Long: p_pos = 1
    Dim p_posFound As Long: p_posFound = 0
    Dim p_result As String: p_result = ""
    
    Dim i As Integer
    For i = 0 To UBound(x_params)
        ' プレースホルダ {} を検索
        p_posFound = InStr(p_pos, x_templateMessage, "{}")
        ' プレースホルダ {} が見つからなかった場合
        If p_posFound = 0 Then
            Exit For ' 置換終了
        End If
        
        p_result = p_result & Mid$(x_templateMessage, p_pos, p_posFound - p_pos)
        p_result = p_result & CStr(x_params(i))
        p_pos = p_posFound + 2
    Next i

    ' 残分を追加
    If p_pos <= Len(x_templateMessage) Then
        p_result = p_result & Mid$(x_templateMessage, p_pos, Len(x_templateMessage) - p_pos + 1)
    End If
    
    ' 結果返却
    MessageFormat = p_result
End Function

挙動とは関係ないですが、VBEのエディタが貧弱なので、変数名に以下のコーディングルールを採用しています。

  1. 引数の変数名は "x_" で始める。その後ろは自由
  2. ローカル変数名は "p_" で始める。その後ろは自由

上記コードもこのルールで記述しています。

リポジトリ

github.com

利用例

f:id:fumokmm:20200602231014p:plain

まとめ

  • 今回はVBAの標準関数にメッセージフォーマットしてくれる関数が無いようなので書いてみました
  • 上記利用例の様にワークシート関数として利用できる他、VBAコード内でログ出力や、メッセージボックスの文言を生成する場合などにも利用できるのではないでしょうか

追記

  • コードがバグってたので修正 (2020-10-30)