【问题标题】:Counting the matching substrings in range计算范围内的匹配子串
【发布时间】:2021-07-13 02:40:37
【问题描述】:

我正在编写一个工作簿,我需要在其中计算“St/”子字符串在范围(Q 列)中出现的次数。注意:我对所有出现感兴趣,而不仅仅是存在子字符串的单元格的数量。
这是我正在尝试使用的代码(基于 Santhosh Divakar - https://stackoverflow.com/a/23357807/12536295 的评论),但在运行时我收到了运行时错误 (13)。我错过了什么/做错了什么?

Dim lastrow, q as Integer
lastrow = Range("A1").End(xlToRight).End(xlDown).Row
With Application
q = .SumProduct((Len(Range("Q1:Q" & lastrow)) - Len(.Substitute(Range("Q1:Q" & lastrow), "St/", ""))) / Len("St/"))
End With

【问题讨论】:

    标签: excel vba


    【解决方案1】:

    看看下面的代码对你有没有帮助:

    Public Sub TestCount()
        lastrow = Range("Q" & Rows.Count).End(xlUp).Row
        strformula = "=SUMPRODUCT(LEN(Q1:Q" & lastrow & ")-LEN(SUBSTITUTE(UPPER(Q1:Q" & lastrow & "),""/ST"","""")))/LEN(""/St"")"
        MsgBox Evaluate(strformula)
    End Sub
    

    【讨论】:

    • 对 OP 的有效回答;认为搜索字符串的最后一个字符是“ST/”,而不是“/ST”。 在我的帖子中也使用了评估。
    • 这正是我想要的。 Evaluate 方法实现了它。谢谢 shrivallabha.redij!
    【解决方案2】:

    我认为您可以计算字符数,将“St/”替换为空,然后再次计算字符并除以 len("St/")。这是一个例子。

    '''your existing code
    Dim lCount As Long
    Dim lCount_After As Long
    '''set a Range to column Q
    Set oRng = Range("Q1:Q" & lRow_last)
    '''turn that range into a string
    sValues = CStr(Join(Application.Transpose(oRng.Value2)))
    lCount = Len(sValues)
    lCount_After = lCount - Len(Replace(sValues, "St/", ""))
    lCount_After = lCount_After / 3
    
    Debug.Print lCount_After
    

    【讨论】:

      【解决方案3】:

      使用ArrayToText()函数

      a) 如果您弃用 Excel 版本 MS365,您可以通过 评估 表格 ARRAYTOTEXT() 缩短先前的字符串构建 一次获取所有行的连接字符串的公式(补充@Foxfire 的有效解决方案)

      注意,必须将范围地址作为字符串插入; 为了完全限定范围引用我使用了一个额外的External:=True 参数。

      b) VBA 的Split() 函数最终允许通过以下方式返回找到的分隔符的数量(例如“St/”) UBound() 函数。它为此返回上边界(即最大的可用下标) 从零开始的一维拆分数组。

      示例:如果存在八个St/ 分隔符,则拆分数组由 九个元素;因为它是从零开始的,所以第一个元素的索引为 0 最后一个元素被8 识别,这已经是想要的函数结果。

      Function CountOccurrencies(rng As Range, Optional delim as String = "St/")
      'a) get a final string (avoiding to join cells per row) 
          Dim txt As String
          txt = Evaluate("ArrayToText(" & rng.Address(False, False, External:=True) & ")")
      'b) get number of delimiters 
          CountOccurrencies = UBound(Split(txt, delim))
      End Function
      
      

      【讨论】:

        【解决方案4】:

        不是最干净的,但您可以将所有内容放入数组并按St/ 拆分。该数组的大小将是您获得了多少巧合:

        Sub test()
        Dim LR As Long
        Dim MyText() As String
        Dim i As Long
        Dim q As Long
        
        LR = Range("Q" & Rows.Count).End(xlUp).Row
        ReDim Preserve MyText(1 To LR) As String
        
        For i = 1 To LR Step 1
            MyText(i) = Range("Q" & i).Value
        Next i
        
        q = UBound(Split(Join(MyText, ""), "St/"))
        
        Debug.Print q
        Erase MyText
        End Sub
        

        我得到的输出是 8

        请注意此代码区分大小写

        【讨论】:

        • 很好的解决方案 +:) Fyi 可能对我通过ArrayToText 发布的补充帖子感兴趣,但基于相同的有条不紊的方法。 - (旁注:完全限定范围参考)
        【解决方案5】:

        使用 Excel 2019+ 中的 TextJoin() 函数:

        Sub CalcSt()
            Const WHAT = "St/": Dim joined As String
            joined = WorksheetFunction.TextJoin("|", True, Columns("Q"))
            Debug.Print (Len(joined) - Len(Replace(joined, WHAT, ""))) / Len(WHAT)
        End Sub
        

        【讨论】:

          猜你喜欢
          • 2013-10-05
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多