1

我写了一个子程序,它从一张纸上查找搜索词,并从包含其中一个词的大字符串数组中捕获每一行(将其打印到另一张纸上)。

最初我是这样写的:

  • 对于每个搜索词,查看文件中的每一行并打印每个匹配项。

它有效,但这意味着如果一行包含多个搜索词,它将被打印多次。我想消除这一点,如果它包含至少一个搜索词,只需打印一次。所以,我重新安排了代码,使其像这样工作:

  • 对于文件中的每一行,查看每个搜索词并在匹配时打印该行。
  • (如果您确实找到了匹配项,请跳过该行的剩余搜索词)

如果有的话,我想这种方式应该比原来的方式稍微高效一些……然而,在我重新排列代码之后,执行起来需要更长的时间

我想这意味着,虽然我觉得我好像在以不同的顺序做同样的事情,甚至节省了一些不必要的检查,但我必须以某种方式将耗时最长的部分复合起来。任何人都可以阐明并帮助我了解我是如何使代码变得如此糟糕的吗?

以下是相关代码段的两个版本的样子:

原始方式:

searchTermRow = firstSearchTermRow
While ActiveWorkbook.Sheets("SearchTerms").Cells(searchTermRow, 1) <> ""
    term = ActiveWorkbook.Sheets("SearchTerms").Cells(searchTermRow, 1)
    For j = 1 To UBound(bigStringArray) - 1
        counter = counter + 1
        If (InStr(bigStringArray(j), term) <> 0) Then
            Cells(resultsRow, 1).Value = bigStringArray(j)
            resultsRow = resultsRow + 1
        End If
    Next j
    searchTermRow = searchTermRow + 1
Wend

重新排列:

For j = 1 To UBound(bigStringArray) - 1
    searchTermRow = firstSearchTermRow
    Do While ActiveWorkbook.Sheets("SearchTerms").Cells(searchTermRow, 1) <> ""
        term = ActiveWorkbook.Sheets("SearchTerms").Cells(searchTermRow, 1)
        counter = counter + 1
        If (InStr(bigStringArray(j), term) <> 0) Then
            Cells(resultsRow, 1).Value = bigStringArray(j)
            resultsRow = resultsRow + 1
            Exit Do
        End If
        searchTermRow = searchTermRow + 1
    Loop
Next j

bigStringArray 是一个大型字符串数组,由文件中的每一行组成。计数器就在那里,这样我就可以计算完成了多少检查。

4

1 回答 1

1

您可以bigStringArray通过使用带有诸如term1|term2|term3 etc.

Option Explicit

Sub RegexMatch()

    Const firstSearchTermRow = 2

    Dim ws As Worksheet
    Dim lastRow As Long, resultsRow As Long, j As Long
    Dim rngTerms As Range, t0 As Single: t0 = Timer

    Set ws = ActiveWorkbook.Sheets("SearchTerms")
    lastRow = ws.Cells(Rows.count, 1).End(xlUp).Row
 
    ' build regex pattern
    Dim sPattern As String
    Set rngTerms = ws.Range("A" & firstSearchTermRow & ":A" & lastRow)
    sPattern = Join(WorksheetFunction.Transpose(rngTerms), "|")
    'Debug.Print sPattern

    Dim regex As Object, m As Object
    Set regex = CreateObject("vbscript.regexp")
    With regex
       .Global = False
       .MultiLine = False
       .IgnoreCase = True
       .Pattern = "(" & sPattern & ")"
    End With

    ' test data
    Dim bigStringArray
    bigStringArray = Array("", "ABCDE", "BCDEF", "CDEFGH", "DEFHIJKL")

    resultsRow = 1
    For j = 1 To UBound(bigStringArray)
        If regex.test(bigStringArray(j)) Then
            Set m = regex.Execute(bigStringArray(j)) ' match
            Cells(resultsRow, 1).Value = bigStringArray(j)
            Cells(resultsRow, 2).Value = m(0) ' matched term
            resultsRow = resultsRow + 1
        End If
    Next

    MsgBox j - 1 & " strings checked", vbInformation, Format(Timer - t0, "0.00 secs")
End Sub
于 2021-09-19T17:01:46.267 回答