4

我的 sub 比较两个字符串列表并返回最接近的匹配项。我发现潜艇被一些常用词绊倒了,比如“the”和“facility”。我想编写一个函数,该函数将提供一组单词以排除并检查这些单词的每个字符串,如果找到则排除它们。

这是一个示例输入:

|aNames        |  bNames        | words to exclude
|thehillcrest  |oceanview health| the
|oceanview, the|hillCrest       | health

预期输出:

|aResults     |bResuts
|hillcrest    |hillcrest
|oceanview    |oceanview

到目前为止,我有:

Dim ub as Integer
Dim excludeWords() As String

'First grab the words to be excluded
If sheet.Cells(2, 7).Value <> "" Then
  For y = 2 To sheet.Range("G:G").End(xlDown).Row
    ub = UBound(excludeWords) + 1             'I'm getting a subscript out of range error here..?
    ReDim Preserve excludeWords(0 To ub)
    excludeWords(ub) = sheet.Cells(y, 7).Value
  Next y
End If

然后我的比较函数使用双循环将 A 列中的每个字符串与 B 列进行比较。在比较之前,a 列和 b 列中的值将通过我们的函数,该函数将检查这些单词是否要排除。可能没有要排除的词,所以参数应该是可选的:

Public Function normalizeString(s As String, ParamArray a() As Variant)
  if a(0) then           'How can I check?
    for i = 0 to UBound(a)
      s = Replace(s, a(i))
    next i
  end if
  normalizeString = Trim(LCase(s))
End Function

这段代码中可能有几个部分不起作用。你能指出我正确的方向吗?

谢谢!

4

2 回答 2

6

要将列表存储在数组中,您可以这样做

Sub Sample()
    Dim excludeWords As Variant
    Dim lRow As Long

    With Sheet1 '<~~ Change this to the relevant sheet
        '~~> Get last row in Col G
        lRow = .Range("G" & .Rows.Count).End(xlUp).Row

        excludeWords = .Range("G2:G" & lRow).Value

        'Debug.Print UBound(excludeWords)

        'For i = LBound(excludeWords) To UBound(excludeWords)
            'Debug.Print excludeWords(i, 1)
        'Next i
    End With
End Sub

然后将数组传递给您的函数。上面的数组是一个二维数组,因此需要相应地处理(参见上面代码中的注释部分

就像我在上面的评论中提到的

怎么oceanview, the变成Oceanview?您可以替换the,但这会给您oceanview,(注意逗号)而不是Oceanview.

您可能必须将这些特殊字符传递给工作表中的 Col G,或者您可以使用循环在函数中处理它们。为此,您必须使用 ASCII 字符。请看这个

评论的跟进

这是我写得很快的东西,所以它没有经过广泛的测试。这是你想要的?

Sub Sample()
    Dim excludeWords As Variant
    Dim lRow As Long

    With Sheet1
        lRow = .Range("G" & .Rows.Count).End(xlUp).Row

        excludeWords = .Range("G2:G" & lRow).Value

        '~~> My column G has the word "habilitation" and "this"
        Debug.Print normalizeString("This is rehabilitation", excludeWords)

        '~~> Output is "is rehabilitation"
    End With
End Sub

Public Function normalizeString(s As String, a As Variant) As String
    Dim i As Long, j As Long
    Dim tmpAr As Variant

    If InStr(1, s, " ") Then
        tmpAr = Split(s, " ")

        For i = LBound(a) To UBound(a)
            For j = LBound(tmpAr) To UBound(tmpAr)
                If LCase(Trim(tmpAr(j))) = LCase(Trim(a(i, 1))) Then tmpAr(j) = ""
            Next j
        Next i
        s = Join(tmpAr, " ")
    Else
        For i = LBound(a) To UBound(a)
            If LCase(Trim(s)) = LCase(Trim(a(i, 1))) Then
                s = ""
                Exit For
            End If
        Next i
    End If

    normalizeString = Trim(LCase(s))
End Function
于 2014-11-06T21:28:37.870 回答
5

首先,您不能为还没有大小的数组调用UBound函数:

Dim excludeWords() As String

ub = UBound(excludeWords) + 1  'there is no size yet

要删除一些不需要的单词,请使用替换功能

String1 = Replace(String1, "the", "")

要进行您描述的比较,我将使用Like函数。这是文档。 http://msdn.microsoft.com/pl-pl/library/swf8kaxw.aspx

于 2014-11-06T21:27:34.123 回答