編集:すべての回答はうまく機能しますが、大きなデータセットの場合、マクロアプローチの方がうまく機能しました。それらすべてを試して、自分に最適なものを確認してください。
私はパフォーマンスのためにExcelでこの問題を解決しようとしています(私はRでそれを行いましたが、遅いです)。基本的に、各キーワード(キーワードのリストから)を列のテキスト(基本的には段落)と照合する必要があります。これがイラストです:
上記のデータは、この質問のソースにテキスト形式であり、コピーアンドペーストに適しています。
私はいくつかのテキスト関数(FINDやSEARCHなどですが、位置を返すだけです)を探していたので、これがExcelで実行できるかどうかはわかりません。
この短いマクロを試してください:
Sub KeyWord()
Dim Na As Long, Nc As Long, ary, s As String
Dim r As Range, a, i As Long, outpt As String
Na = Cells(Rows.Count, "A").End(xlUp).Row
Nc = Cells(Rows.Count, "C").End(xlUp).Row
ReDim ary(1 To Nc)
i = 1
For Each r In Range("C1:C" & Nc)
ary(i) = r.Text
i = i + 1
Next r
For i = 1 To Na
s = Cells(i, "A").Value
outpt = ""
For Each a In ary
If InStr(1, s, a) > 0 Then
outpt = outpt & "," & a
End If
Next a
If outpt = "" Then
Else
Cells(i, "E").Value = Mid(outpt, 2)
End If
Next i
End Sub
例えば:
EDIT#1:
完全な単語のみをキャプチャするための小さなトリックは、各キーワードをスペースで囲み、各文をスペースで囲むことです。
これは、[スペース][スペース]が劇場と一致しないことを意味します!:
Sub KeyWord_II_TheSequel()
Dim Na As Long, Nc As Long, ary, s As String
Dim r As Range, a, i As Long, outpt As String
Na = Cells(Rows.Count, "A").End(xlUp).Row
Nc = Cells(Rows.Count, "C").End(xlUp).Row
ReDim ary(1 To Nc)
i = 1
For Each r In Range("C1:C" & Nc)
ary(i) = r.Text
ary(i) = " " & ary(i) & " "
i = i + 1
Next r
For i = 1 To Na
s = Cells(i, "A").Value
s = " " & s & " "
outpt = ""
For Each a In ary
If InStr(1, s, a) > 0 Then
outpt = outpt & "," & a
End If
Next a
If outpt = "" Then
Else
Cells(i, "E").Value = Mid(outpt, 2)
End If
Next i
End Sub
免責事項:
膨大な数のキーワードに対して、次の「配列数式」のパフォーマンスを見積もることは困難です。妥当なデータセットで機能し、「正しい」結果を生成します。
配列数式 for E2
(次に自動入力列E)は次のとおりです。
E2:
=TEXTJOIN(", ",TRUE,REPT(C$2:C$99999,ISNUMBER(SEARCH(C$2:C$99999,A2))))
CTRLSHIFTENTER
私が言ったように、それは「適度に大きい」セット、たとえば数千でテストされたので、同様の状況の一般的な解決策として投稿しましたが、700k(!)の膨大なセットには疑問があります。
また、数式を保持せず、計算にのみ使用し、値を修正して、最後に空のセルを削除することをお勧めします。 HTH
A6
のE5
の出力を表示するディスプレイ(A5
の出力は「none」であるため)はエラーであり、A6
のE6
の出力が本当に必要であると想定します。
列にキーワードがあるのは不自然だと思います。 Ai
の出力はEi
にあり、Ci
の値は、Rowi
の他のものとは実際には何の関係もありません。それはm×nの状況であり、mのセルがあります検索するテキストの(段落)、および検索するnキーワード。まあ、それを処理する方法があります。
私のソリューションでは、n+ 1ヘルパー列を使用しています。ここでのnは5なので、これは6つのヘルパー列を意味します。これはColumnsF
からK
になります。 (ヘルパー列の場合と同様に、好きな場所に配置できます。必要に応じて、ColumnsAA
throughAF
に配置できます。また、非表示にすることもできます。)
最初のもの(F
)は空白のままです。入る
=OFFSET($C$1, COLUMN()-COLUMN($F:$F), 0)
セルG1
に移動し、右にドラッグ/塗りつぶしてK1
に移動します。これは、現在の列番号(ヘルパー列のブロックの先頭を基準とする)をキーワードであるColumnC
へのインデックスとして使用し、それによってRow1(cellsG1
throughK1
)のキーワードを複製します。
次に、
=F2 & IF(ISNUMBER(SEARCH(G$1, $A2)), ", " & G$1, "")
セルG2
に。右にドラッグ/塗りつぶし、cellK2
に移動し、次に下にドラッグして、ColumnA
にデータがあるm行をカバーします。これにより、現在の行のColumnA
の段落で、現在の列のRow1にあるi番目のキーワードが検索されます。見つかった場合(つまり、SEARCH(…)
が数値を返した場合、つまりISNUMBER(SEARCH(…))
がtrueの場合)、コンマとスペースが前に付いたキーワードを生成します。キーワードが見つからない場合、IF(…)
関数はnull文字列と評価されます。 (大文字と小文字を区別して比較する場合は、SEARCH
をFIND
に置き換えます。)次に、どちらの方法でも、結果は左側のセルの値に連結されます。これにより、ColumnK
に、現在の行のColumnA
の段落に存在するキーワードのコンマ区切りのリストが生成されます。
次に入力します
=IF(K2="", "", RIGHT(K2, LEN(K2)-2))
E2
に移動し、下にドラッグ/塗りつぶして、ColumnA
にデータがある行をカバーします。つまり、ColumnK
の値がnullの場合は、nullと評価されます。それ以外の場合は、ColumnK
の値の先頭から,
を削除します。
入力データに対して取得した結果の画像は次のとおりです。
CellE6
(A6
の出力)で、私のソリューションでは一致するキーワードがColumnC
に表示される順序でリストされているのに対し、図ではcellA6
に表示される順序でリストされていることに注意してください。それが問題である場合は、質問を編集してそのように言ってください。修正できるかどうかを確認します。