2016-09-13 89 views
2

我試圖計算可變長度字符串集合中的術語頻率。上下文是Access數據庫中的描述。寧願將解決方案保留在VBA中。分隔符是「」(空格)字符。特殊字符將被提前刪除。VBA:字頻陣列

我的第一次感覺有點蠻力;我懷疑更有效的方法是可能的。

以下是我目前正在做的一個字符串,它提供了我所期望的結果:

Private Sub Command0_Click() 

    Dim myCol As Collection 
    Dim myArray() As String 
    Dim strArray As Variant 
    Dim strDescr, strTerm, strMsg As String 
    Dim i, j As Integer 

    Set myCol = New Collection 

    strDescr = "This is just a test only a test test test" 

    myArray = Split(strDescr, " ") 

    For Each strArray In myArray 
     On Error Resume Next 
     myCol.Add strArray, CStr(strArray) 
    Next strArray 

    For i = 1 To myCol.Count 
     strTerm = myCol(i) 
     j = 0 
     For Each strArray In myArray 
      If strArray = strTerm Then j = j + 1 
     Next strArray 
     'placeholder   
     strMsg = strMsg & strTerm & " | " & j & Chr(10) & Chr(13) 
    Next i 

    'placeholder 
    'save results into a table 
    MsgBox strMsg 

End Sub 

示例結果:

sample result

接下來,我需要擴大這個方法來逐步通過記錄集,以不斷追加單詞到數組和集合。記錄集可以很大,30K記錄,descr是30-60個字符。

問題:

  1. 如何追加到在一個記錄每行一個數組?
  2. 當我縮放記錄數時,這種方法會失敗嗎?
  3. 更好的方法?

謝謝!

回答

2

你的直覺是正確的 - 這是非常強大的力量,所以它不會很好地擴展。是的,有一個更好的方法 - 我會使用Scripting.Dictionary而不是Collection。它允許一個Collection不允許的兩件事:首先,你可以檢查一個密鑰的存在而不依賴於錯誤處理程序(並且簡單地將計數存儲在Dictionary本身中)。其次,您可以檢索Keys數組以輕鬆提取結果。

您的代碼將轉化爲更多的東西是這樣的:

'Requires a reference to Microsoft Scripting Runtime. 
Private Sub Command0_Click() 
    Dim counts As New Scripting.Dictionary 
    Dim word As Variant 
    Dim desc As String 

    desc = "This is just a test only a test test test" 

    For Each word In Split(LCase$(desc), " ") 
     If Not counts.Exists(word) Then 
      counts.Add word, 1 
     Else 
      counts.Item(word) = counts.Item(word) + 1 
     End If 
    Next 

    For Each word In counts.Keys 
     Debug.Print word, counts(word) 
    Next 
End Sub 

至於你的最後一個問題,「?我怎麼追加到在一個記錄每一行陣」 - 你需要做的就是循環訪問記錄集並將它們添加到同一個Dictionary中。然後,您可以簡單地檢索完成後的總計數。

+0

共產國際,這是非常好的。感謝您的建議方法! –