web-dev-qa-db-ja.com

VBAで正規表現の一致を返す(Excel)

非構造化テキストのセルを取得し、sdi値と呼ばれるものを探し、見つかった場合はその数値を返す関数を、Excel 2010用に作成しようとしています。 sdi値はsdi ####として表示されます。私が欲しいのは、sdiとそれに続く特定の数字を返すことです。したがって、セルに「some text sdi 1234 some some text」が含まれている場合、関数はsdi 1234を返します。

これは私の機能です:

Function SdiTest(LookIn As String) As String
  Dim temp As String
  Dim STA As Object
  temp = ""

  Set SDI = CreateObject("VBScript.RegExp")
  SDI.IgnoreCase = True
  SDI.Pattern = "sdi [1-9]*"
  SDI.Global = True

  If SDI.Test(LookIn) Then
    temp = SDI.Execute(LookIn)
  End If

  SdiTest = temp
End Function

Sdi番号がない場合は、ifステートメントを入力せず、空の文字列を忠実に返します。 sdi番号がある場合、#VALUE!

私は何が欠けていますか?

はい、VBScriptは有効です。さらに、VBAで正規表現を使用するのはイライラするだけでなく、有用な情報をオンラインで見つけるのも困難です。優れたオンラインリソースへのリンクをいただければ幸いです。

ありがとうございました

44
TheoRose

SDI番号を取得するには、一致にアクセスする必要があります。これを行う関数を次に示します(セルごとに1つのSDI番号しかないと仮定)。

正規表現では、「sdiの後にスペースと1つ以上の数字が続く」を使用しました。 「sdiの後にスペースと0個以上の数字が続きます」。私のパターンの+を*に変更するだけで、元の状態に戻ることができます。

Function ExtractSDI(ByVal text As String) As String

Dim result As String
Dim allMatches As Object
Dim RE As Object
Set RE = CreateObject("vbscript.regexp")

RE.pattern = "(sdi \d+)"
RE.Global = True
RE.IgnoreCase = True
Set allMatches = RE.Execute(text)

If allMatches.count <> 0 Then
    result = allMatches.Item(0).submatches.Item(0)
End If

ExtractSDI = result

End Function

セルに抽出したい複数のSDI番号がある場合、RegexExtract関数を次に示します。 3番目のパラメーターを渡して各一致を分離できます(コンマ区切りのように)。実際の関数呼び出しでパターンを手動で入力します。

Ex) =RegexExtract(A1, "(sdi \d+)", ", ")

ここは:

Function RegexExtract(ByVal text As String, _
                      ByVal extract_what As String, _
                      Optional seperator As String = "") As String

Dim i As Long, j As Long
Dim result As String
Dim allMatches As Object
Dim RE As Object
Set RE = CreateObject("vbscript.regexp")

RE.pattern = extract_what
RE.Global = True
Set allMatches = RE.Execute(text)

For i = 0 To allMatches.count - 1
    For j = 0 To allMatches.Item(i).submatches.count - 1
        result = result & seperator & allMatches.Item(i).submatches.Item(j)
    Next
Next

If Len(result) <> 0 Then
    result = Right(result, Len(result) - Len(seperator))
End If

RegexExtract = result

End Function

* RegexExtractから "RE.IgnoreCase = True"を削除しましたが、再度追加するか、必要に応じてオプションの4番目のパラメーターとして追加することもできます。

71
aevanko