h-yonesanのblog

VBAやプログラムについて日々勉強したことを書いています。

AccessVBA フォームのFilterプロパティに設定する文字列を生成する関数

初めに

先日、レコードを一覧表示するフォームに検索用のテキストボックスを追加し、その入力内容でフィルタをかける、という機能を作った。
例えばこんな感じ

Me.Filter= "入社年 > 2015 and 部署 = A事業部 and 性別 = 男"
Me.Fiter=True

このFilterプロパティに設定する文字列
"入社年 > 2015 and 部署 = A事業部 and 性別 = 男"
を生成する関数を作った。
(正確に言うと自分の力では作れず、私の先生の力を大いに借りたのだが、、)

サンプルコード

Function Combine(condition1 As String, condition2 As String, condition3 As String) As String
    Combine = Join(Array(condition1, condition2, condition3), " and ")
End Function

これをイミディエイトウィンドウ上で実行すると
?combine("cond1","cond2","cond3")
cond1 and cond2 and cond3
となった。

今は引数の数が固定なので、任意の数の引数に対応するようにしたい。改良したのが次のコード。

Function Combine(ParamArray conditions()) As String
    Dim ret As String
    Dim i As Long
    For i = LBound(conditions) To UBound(conditions)
        ret = ret & " and " & conditions(i)
    Next i
    Combine = ret
End Function

これを実行すると
?combine("cond1","cond2")
and cond1 and cond2

?combine("cond1","cond2","cond3")
and cond1 and cond2 and cond3

と引数の数の変化には対応出来たが、先頭に" and "が入ってしまった。それを削除したのが次のコード

Function Combine(ParamArray conditions()) As String
    Dim ret As String
    Dim i As Long
    For i = LBound(conditions) To UBound(conditions)
        ret = ret & " and " & conditions(i)
    Next i
    Combine = Mid(ret, Len(" and ") + 1)
End Function

実行すると
?combine("cond1","cond2")
cond1 and cond2

?combine("cond1","cond2","cond3")
cond1 and cond2 and cond3

と先頭の" and "が削除された。更に区切り文字 " and "も引数にしたのが次のコード。

Function Combine(delimiter As String, ParamArray conditions()) As String
    Dim ret As String
    Dim i As Long
    For i = LBound(conditions) To UBound(conditions)
        ret = ret & delimiter & conditions(i)
    Next i
    Combine = Mid(ret, Len(delimiter) + 1)
End Function

実行すると
?combine(" and ","cond1","cond2","cond3")
cond1 and cond2 and cond3
となった。

ただし、今の関数だと引数が空文字列の場合
?combine(" and ","cond1","","cond3")
cond1 and and cond3
?combine(" and ","","cond2","cond3")
and cond2 and cond3

のように不要なandが含まれてしまう。引数に空文字列が与えられた場合(つまり検索条件の指定が無かった場合)スキップするように改良したのが次のコード

Function Combine(delimiter As String, ParamArray conditions()) As String
    Dim ret As String
    Dim i As Long
    For i = LBound(conditions) To UBound(conditions)
        If conditions(i) <> "" Then ret = ret & delimiter & conditions(i)
    Next i
    Combine = Mid(ret, Len(delimiter) + 1)
End Function

実行すると
?combine(" and ","cond1","","cond3")
cond1 and cond3
?combine(" and ","","cond2","cond3")
cond2 and cond3
と余計なandが入っていない。これで一応欲しい機能が実現出来たようだ。だが、きちんと動作確認するには単体テストが必要で、それは後日書こうと思う。

最後に

生まれて初めてブログを書いた。ブログを書くのがこんなに難しいとは思わなかった。文章を書く良い訓練になるので、今後も自分が勉強したことを少しずつ書いていこうと思う。
また、シンタックスハイライトが出来なくて困ったが、こちらの記事を見て解決した。ありがとうございます!
k01ken.hatenablog.com