今日は、ACCESSで RegExp を使ってみることにします。RegExp を使えると検索抽出の範囲が拡大します。特に、事件等を記録する備考のフィールドを持っている場合で、備考の検索が緻密に行えますので埋もれたデータを検索するとき絶大な効果を発揮します。
テーブル
ACCESSのデータの備考の中に埋もれたデータ(<住所と>で囲まれた部分)を取り出すことになりましたので、RegExpの利用を考えてみました。自分の必要な結果が得られましたので記録することにしました。
帳票フォーム
SQLでSELECTするフィール名は、テーブルの「備考」と「備考」の内容からキー「<住所」とキー「>」に囲まれたを文章を抽出してトップの「<」とテールの「>」を削除して「備考住所」とします。その2フィールドを表示する帳票フォームです。
フォームのオープン
目的とする結果がこのようなものです。1カ所だけならInstr関数で、<>のそれぞれの場所を計算すればいいのですが、4行目のように2カ所となるとそれもできそうもありません。
Accessの場合、SQLの中でユーザー関数が使えるので作成することにします。
関数myRegExpの作成
標準モジュールの中に Public で記述します。
Target はフィールドです。Patt にパターンを記述します。
Public Function myRegExp(ByVal Target As Variant, _ ByVal Patt As String) As String Dim RE As New RegExp Dim MC As MatchCollection Dim M As Match Dim Res As String Dim P As String Dim BUF() As String Dim iCount As Long P = Nz(Target, "") If P = "" Then myRegExp = "" Exit Function End If With RE .Global = True .IgnoreCase = False .Pattern = Patt Set MC = .Execute(P) End With Res = "" If MC.Count > 0 Then ReDim BUF(MC.Count - 1) For Each M In MC P = Replace(M.Value, "<", "") P = Replace(P, ">", "") BUF(iCount) = P iCount = iCount + 1 Next M Res = Join(BUF, ",") End If Set RE = Nothing Set MC = Nothing myRegExp = Res End Function
フォームに記述するモジュール
REに RegEp のパターンを記述します。
ドット(.)だけの「.*?」ですと、「<住所」と「>」の間に改行があるとマッチしませんので抽出されません。
改行を含んでほしいので「(\r\n\f|.)*?」としています。
Private Sub Form_Load() Dim mySQL As String Dim RE As String RE = "'(<住所)(\r\n\f|.)*?>'" mySQL = "SELECT A.備考 AS 備考" mySQL = mySQL & ", myRegExp(A.備考, " & RE & ") AS 備考住所" mySQL = mySQL & " FROM T_備考 AS A" mySQL = mySQL & " WHERE INSTR(A.備考, '<住所') > 0 AND INSTR(A.備考, '>') > 0" Me.RecordSource = mySQL & ";" End Sub
「'(<住所)(\r\n\f|.)*?>'”」「’<住所’) > 0 AND INSTR(A.備考, ‘>’) > 0″」が緑色表示になっていますが、これはわたしの JavaScript が不完全でコメントアウトの判定ができないためです。それを考慮してください。
追伸
JavaScript を改善してコメントアウトの誤表示が出ないようにしました。