You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何修改Excel VBA代码实现2词、3词字符串的频次统计

问题描述

大家好,我在Excel中做了如下设置:
enter image description here
我的核心需求是自动提取A列的所有字符串粘贴到H列,同时在I列返回对应字符串的出现频次,目前使用的VBA脚本如下:

Sub WordCountTester()
    Dim d As Object, k, i As Long, ws As Worksheet
    
    Set ws = ActiveSheet
    With ws.ListObjects("Table3")
        If Not .DataBodyRange Is Nothing Then
            .DataBodyRange.Delete
        End If
    End With
    Set d = WordCounts(ws.Range("A2:A" & ws.Cells(Rows.Count, "A").End(xlUp).Row), _
                       ws.Range("F2:F" & ws.Cells(Rows.Count, "F").End(xlUp).Row))
    'list words and frequencies
    For Each k In d.keys
        ws.Range("H2").Resize(1, 2).Offset(i, 0).Value = Array(k, d(k))
        i = i + 1
    Next k
End Sub

'rngTexts = range with text to be word-counted, defined in set d= above
'rngExclude = 'range with words to exclude from count, defined in set d= above
Public Function WordCounts(rngTexts As Range, rngExclude As Range) As Object 'dictionary
    Dim words, c As Range, dict As Object, regexp As Object, w, wd As String, m
    Set dict = CreateObject("scripting.dictionary")
    Set regexp = CreateObject("VBScript.RegExp") 'see link below for reference
    With regexp
        .Global = True
        .MultiLine = True
        .ignorecase = True
        .Pattern = "[\dA-Z-]{3,}" 'at least 3 characters
     End With
     'loop over input range
     For Each c In rngTexts.Cells
        If Len(c.Value) > 0 Then
            Set words = regexp.Execute(LCase(c.Value))
            'loop over matches
            For Each w In words
                wd = w.Value 'the text of the match
                If Len(wd) > 1 Then  'EDIT: ignore single characters
                   'increment count if the word is not found in the "excluded" range
                    If IsError(Application.Match(wd, rngExclude, 0)) Then
                        dict(wd) = dict(wd) + 1
                    End If
                End If '>1 char
            Next w
        End If
            Next c
     Set WordCounts = dict
End Function

但当前代码仅支持统计1词字符串的频次,我需要调整为统计2词、3词字符串的频次(其中drive-by按2个词计算),同时保留F列的排除词功能,用于过滤不需要统计的2词、3词字符串。请问需要修改代码的哪一部分才能实现该需求?

解决方案

你只需修改WordCounts函数的逻辑即可,核心修改点包括:

  • 先把匹配到的带横杠的字符串拆分为独立单词,存入临时单词数组
  • 遍历临时单词数组,生成连续的2词、3词组合
  • 对生成的词组做排除校验后再统计频次

修改后的完整WordCounts函数代码如下:

Public Function WordCounts(rngTexts As Range, rngExclude As Range) As Object 'dictionary
    Dim words, c As Range, dict As Object, regexp As Object, w
    Dim tempWords() As String, wordIdx As Long, i As Long, phrase As String
    Set dict = CreateObject("scripting.dictionary")
    dict.CompareMode = vbTextCompare '不区分大小写
    Set regexp = CreateObject("VBScript.RegExp")
    With regexp
        .Global = True
        .MultiLine = True
        .ignorecase = True
        .Pattern = "[\dA-Z-]{3,}" '至少3个字符的匹配规则保留
     End With
     '遍历输入区域
     For Each c In rngTexts.Cells
        If Len(c.Value) > 0 Then
            Set words = regexp.Execute(LCase(c.Value))
            Erase tempWords
            wordIdx = 0
            '第一步:把所有匹配到的内容拆分横杠,存入临时单词数组
            For Each w In words
                Dim splitArr() As String
                splitArr = Split(Replace(w.Value, "-", " "), " ") '把横杠换成空格再拆分
                For i = LBound(splitArr) To UBound(splitArr)
                    If Len(Trim(splitArr(i))) >= 3 Then '过滤掉拆分后长度不足的内容
                        ReDim Preserve tempWords(wordIdx)
                        tempWords(wordIdx) = Trim(splitArr(i))
                        wordIdx = wordIdx + 1
                    End If
                Next
            Next w
            '第二步:生成2词、3词组合并统计
            If wordIdx >= 2 Then '至少有2个词才能生成词组
                '生成2词组合
                For i = 0 To wordIdx - 2
                    phrase = tempWords(i) & " " & tempWords(i + 1)
                    If IsError(Application.Match(phrase, rngExclude, 0)) Then
                        dict(phrase) = dict(phrase) + 1
                    End If
                Next
                '生成3词组合
                If wordIdx >= 3 Then
                    For i = 0 To wordIdx - 3
                        phrase = tempWords(i) & " " & tempWords(i + 1) & " " & tempWords(i + 2)
                        If IsError(Application.Match(phrase, rngExclude, 0)) Then
                            dict(phrase) = dict(phrase) + 1
                        End If
                    Next
                End If
            End If
        End If
     Next c
     Set WordCounts = dict
End Function

如果需要同时保留单字统计,只需在第二步代码后增加单字遍历统计的逻辑即可,WordCountTester主过程无需任何修改,原有F列排除词功能完全保留,只需把需要排除的2词/3词词组按原有格式填入F列即可生效。


内容的提问来源于stack exchange,提问作者Long N

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.03 15:54:05