最初に一致する単語が見つかったListObject(テーブル)の行を返します。
Public Function MatchFruit(ByVal sInfo As String, ByRef rFruit As Range) As Long
Dim vaSplit As Variant
Dim i As Long, j As Long
Dim rFound As Range
Dim sWhat As String
vaSplit = Split(sInfo, Space(1))
For i = LBound(vaSplit) To UBound(vaSplit)
'strip out non-alpha characters
sWhat = vbNullString
For j = 1 To Len(vaSplit(i))
If Asc(Mid(LCase(vaSplit(i)), j, 1)) >= 97 And Asc(Mid(LCase(vaSplit(i)), j, 1)) <= 122 Then
sWhat = sWhat & Mid(vaSplit(i), j, 1)
End If
Next j
'find the word in the range
Set rFound = Nothing
Set rFound = rFruit.Find(sWhat, , xlValues, xlWhole, , , False)
If Not rFound Is Nothing Then 'if it's found
'return the row in the ListObject
MatchFruit = rFound.Row - rFruit.ListObject.HeaderRowRange.Row
'stop looking
Exit For
End If
Next i
End Function
あなたの最初のテーブルがtblDataとあなたの第2のテーブルtblFruitと呼ばれていると仮定すると、あなたは
=INDEX(tblFruit[Color],MatchFruit([@Info],tblFruit[Fruit]))
を使用して、色と価格になるだろう同様
=INDEX(tblFruit[Price],MatchFruit([@Info],tblFruit[Fruit]))
ロング説明
vaSplit
の代入線は、文字列を区切り文字に基づいて配列に変換するために関数Split
を使用します。あなたのサンプルデータは文章だったので、通常の区切り記号は単語に分割するスペースです。
This is some line about apples.
のような文字列が配列
vaSplit(1) This
vaSplit(2) is
vaSplit(3) some
vaSplit(4) line
vaSplit(5) about
vaSplit(6) apples.
次へと変換され、For
ループは、それが他のリストでそれを見つけることができるかどうかを確認するために、アレイ内のすべての要素を通過します。 LBound
とUbound
(下限と上限)の関数が使用されます。なぜなら、配列の要素数がわからないからです。
ループ内の最初の操作は、無関係な文字を取り除くことです。そのために、変数sWhat
を作成し、何も設定しません。要素内のすべての文字をループして、a...z
の範囲外にあるかどうかを確認します。基本的には、手紙であるものはsWhat
に追加され、数字でないもの(数字、スペース、ピリオド)はありません。最後にsWhat
は、すべての非アルファ文字を取り除いた現在の要素と同じです。この例では、ピリオドのためにapples.
と一致することはないため、削除されています。
良い数字が得られたら、Find
メソッドを使用して、その単語がrFruit
の範囲に存在するかどうかを確認します。そうであれば、rFound
はNothing
にはなりません。
範囲内の単語が見つからない場合、rFound
はNothing
になり、関数はゼロを返します。
単語が見つかった場合、関数は、ListObject
が開始する行より少ない行で見つかった行を返します。そうすれば、関数はワークシート上にないListObject
のデータを含む行を返します。これは、式を組み込む場合に有用である。数式が何かを返すようにするには、その数式を数式の名前に割り当てます。
最後に、Exit For
行は、一度一致が見つかると、配列を見ているだけで停止します。データに複数の一致がある場合、最初の一致のみが返されます。
のトラブルシューティングあなたが見つける最も可能性の高いエラーは、それが行番号を返すことを期待するときに関数がゼロを返すということです。それはおそらく、リスト内に単語が見つからなかったことを意味します。
両方のリストに一致する単語が含まれていることが確かな場合は、トラブルシューティングの方法を以下に示します。Set rFound =
行の後にDebug.Print
文を挿入します。 (イミディエイトウィンドウを表示することがVBEでCtrl + G)イミディエイトウィンドウにsWhat
を印刷する
Set rFound = rFruit.Find(sWhat, , xlValues, xlWhole, , , False)
Debug.Print "." & sWhat & "."
If Not rFound Is Nothing Then 'if it's found
。単語の周りのピリオドは、印刷可能でない文字(スペースなど)を見ることができるようになっています。 .pears .
とpears
を一致させようとすると、最初のスペースに最後にスペースがあるため、一致しません。前後の間隔があるために表示されます。
空白が問題になる場合は、sWhat
でTrim$()
関数を使用して最初に取り除くことができます。そのDebug.Print
Withステートメント
、あなたがタイプミスを持っていることを認識するであろう。その場合には
.paers.
のような結果が表示される場合があります。
小さなヒント - >少しシンプルにしてからもっと複雑にするのはなぜですか?例えば。 「これはリンゴについてのいくつかの線です」の代わりに「リンゴ」のためのものです。そこではいくつかのインデックス(マッチ;マッチ)を簡単に使うことができます。 – Vityata
ご意見ありがとうございます。私はあなたの意見に同意します。しかし、この例は、より複雑なシートの単純化されたバージョンです。元のシートにはさらに多くの行が含まれており、「情報」列の値はずっと複雑です。したがって、これらの値を代用することは実際の選択肢ではありません。 編集:ところで、これらの値をVBAで置き換えるには、同様のスクリプトが必要です。 ;) –