単語が表示される行番号のリストが関連付けられた単語の辞書を取得するための逆インデックスを作成しています (行番号とその行内の特定のセルに表示される単語のリストを開始します)。
私はこれのためにいくつかのコードを動作させることができましたが、配列(辞書の値)への追加を扱うのは少し面倒であることがわかりました.
辞書の値に行番号のリストを格納するために、配列、コレクション、または簡単に検索できるその他のデータ型を使用することにオープンです。以下のコアの問題を示すために、コードの縮小バージョンを貼り付けました。質問は実際にはBuildInvertedIndex
手順に関するものですが、シナリオを簡単に再現できるようにするために残りの部分が含まれています。
Sub Test()
' minimum included here to demonstrate use of buildInvertedIndex procedure
Dim vRange As Range
Dim vDict As Dictionary
Set vRange = ActiveSheet.Range("F2:F20585")
Set vDict = New Dictionary
BuildInvertedIndex vDict, vRange
' test values returned in dictionary (word: [line 1, ..., line n])
Dim k As Variant, vCounter As Long
vCounter = 0
For Each k In vDict.Keys
Debug.Print k & ": " & ArrayToString(vDict.Item(k))
vCounter = vCounter + 1
If vCounter >= 10 Then
Exit For
End If
Next
End Sub
Sub BuildInvertedIndex(pDict As Dictionary, pRange As Range)
Dim cell As Range
Dim words As Variant, word As Variant, val As Variant
Dim tmpArr() As Long
Dim newLen As Long, i As Long
' loop through cells (one col wide so same as looping through lines)
For Each cell In pRange.Cells
' loop through words in line
words = Split(cell.Value)
For Each word In words
If Not pDict.exists(word) Then
' start line array with first row number
pDict.Add word, Array(cell.Row())
Else
i = 0
If Not InArray(cell.Row(), pDict.Item(word)) Then
newLen = UBound(pDict.Item(word)) + 1
ReDim tmpArr(newLen)
For Each val In tmpArr
If i < newLen Then
tmpArr(i) = pDict.Item(word)(i)
Else
tmpArr(i) = cell.Row()
End If
i = i + 1
Next val
pDict.Item(word) = tmpArr
End If
End If
Next word
Next cell
End Sub
Function ArrayToString(vArray As Variant, _
Optional vDelim As String = ",") As String
' only included to support test (be able to see what is in the arrays)
Dim vDelimString As String
Dim i As Long
For i = LBound(vArray) To UBound(vArray)
vDelimString = vDelimString & CStr(vArray(i)) & _
IIf(vCounter < UBound(vArray), vDelim, "")
Next
ArrayToString = vDelimString
End Function
これを実行するには、アクティブ シート (文) の列 F に値が必要です。値がない場合は、VBA 環境で Microsoft Scripting Runtime への参照を追加して、辞書データ型を使用できるようにする必要があります。 (ツール -> 参照 -> Microsoft Scripting Runtime)。
コードからわかるように、既存の配列 (ディクショナリ内に値として格納されている) に新しい行番号を挿入する必要があるため、これは少し面倒です。(既存の値をクリアせずに) この配列を拡張する方法がわからないため、変数 tmpArr を使用して適切なサイズの配列を作成し、辞書内の既存の配列から値を 1 つずつコピーしました。次に、現在の行番号を最後に追加します。次に、一時配列を使用して、そのキー (現在の単語) の既存の値を置き換えます。
これに関するアドバイスは大歓迎です。