如何判断一个数组是否包含一个字符串

62

可能是重复问题:
如何在MS Access VBA数组中搜索字符串

我目前正在编写一个Excel宏,但找不到像if array.contains(mystring)这样的方法。

我写了下面的代码,但它给出了“无效限定符”的消息,并在If后面高亮显示了Mainfram

Dim Mainfram(4) As String

Mainfram(0) = "apple"

Mainfram(1) = "pear"

Mainfram(2) = "orange"

Mainfram(3) = "fruit"

    For Each cel In Selection
        If Mainfram.Contains(cel.Text) Then
            Row(cel.Row).Style = "Accent1"
        End If
    Next cel
选择是一列。
有人能帮忙吗?
嗨,JP 我尝试了你的建议,但它说对象必需。并且突出显示了 If IsInArray(cell.Text, Mainfram) Then 这是我的完整代码。
Sub changeRowColor()

Columns("B:B").Select

Dim cel As Excel.Range
Dim Mainfram(4) As String

Mainfram(0) = "apple"
Mainfram(1) = "pear"
Mainfram(2) = "orange"
Mainfram(3) = "Banana"

For Each cel In Selection
    If IsInArray(cell.Value, Mainfram) Then
        Rows(cel.Row).Style = "Accent1"
    End If
Next cel

End Sub

Function IsInArray(stringToBeFound As String, arr As Variant) As Boolean

    IsInArray = (UBound(Filter(arr, stringToBeFound)) > -1)

End Function

算了,我发现那个愚蠢的错误了... 无论如何还是谢谢你。


FYI,这个问题已经在这里得到了回答。 - JimmyPena
1
@JP:好的,那我们把这个问题标记为完全重复吧。 - Jean-François Corbett
@Jean-FrançoisCorbett 标记了。 - JimmyPena
请勿更新您的问题,如果您只是想评论我的答案,请留下评论。运行您的代码时,我遇到的唯一错误(除了不匹配的“cel/cell”引用)是在“Rows(cel.Row).Style =“Accent1””行上出现的错误。 - JimmyPena
被接受的答案可行。还要看一下建议使用Join方法的答案,这是一个更快的解决方案。 - Tom Collins
你应该使用 ApplePenPineapple 等等。 :D - Black
4个回答

141

使用我在类似问题的答案中提供的代码:

Sub DoSomething()
Dim Mainfram(4) As String
Dim cell As Excel.Range

Mainfram(0) = "apple"
Mainfram(1) = "pear"
Mainfram(2) = "orange"
Mainfram(3) = "fruit"

For Each cell In Selection
  If IsInArray(cell.Value, MainFram) Then
    Row(cell.Row).Style = "Accent1"
  End If
Next cell

End Sub

Function IsInArray(stringToBeFound As String, arr As Variant) As Boolean
  IsInArray = (UBound(Filter(arr, stringToBeFound)) > -1)
End Function

1
+1 像往常一样不错 :) - Siddharth Rout
30
这只能找到包含文本字符串stringToBeFound的所有数组元素,而不是完全相等的元素。因此,对于包含键"e"、"absolutely"、"eventually"等的数组,IsInArray("e", arr)将返回true。 - berkus
10
这并不是一个好的解决方案。这种方式会在查找“p”而非整个单词时返回TRUE。 - Payam
3
这种方法也非常慢。请查看我在“Join”答案下的评论以查看测试结果。 - Tom Collins
如何找到匹配值的数组索引? - Si8
显示剩余7条评论

19

使用JOININSTR的另一种简单方法

Sub Sample()
    Dim Mainfram(4) As String, strg As String
    Dim cel As Range
    Dim Delim As String

    Delim = "#"

    Mainfram(0) = "apple"
    Mainfram(1) = "pear"
    Mainfram(2) = "orange"
    Mainfram(3) = "fruit"

    strg = Join(Mainfram, Delim)
    strg = Delim & strg

    For Each cel In Selection
        If InStr(1, strg, Delim & cel.Value & Delim, vbTextCompare) Then _
        Rows(cel.Row).Style = "Accent1"
    Next cel
End Sub

2
是的,但如果要查找的字符串恰好包含您选择的任意定界符(或任何其他字符),则可能会失败。 - Jean-François Corbett
1
"pear#orange" 将会是一个误判。顺便提一下,使用当前代码 "apple" 会返回一个误判...但你可以通过在搜索字符串前加上分隔符来解决这个问题:strg = "#" & strg - Jean-François Corbett
4
再次同意你的说法。这取决于分隔符的选择。顺便说一下,#This is my €*@£!%&* delimiter!# 是一个好的分隔符。那么单元格有这个分隔符的可能性有多大呢?:-D - Siddharth Rout
2
你的代码在搜索 "fruit" 时会失败,因为字符串末尾没有 Delim。在字符串两侧放置一个 Delim。否则,比被接受的答案更好,我将在下一条评论中解释。 - Tom Collins
3
这种方法比使用筛选器的已接受答案快得多。我进行了一项测试,分别对使用随机的10个单词进行了测试,每个测试迭代了1000万次。JOIN方法花费了7秒钟,而FILTER方法花费了38秒。 - Tom Collins
显示剩余6条评论

5

10
好的回答。提供代码示例会让它更好! - Doug Glancy
2
仅包含链接的回答真的算是“好答案”吗?多数意见似乎是“不是”。 - Jean-François Corbett
2
那么如果我从链接中复制/粘贴了示例,我的答案会更好吗?该链接包含一个确切的示例,OP可以直接在他的代码中使用它来实现他的目标。 - EkoostikMartin
13
@EkoostikMartin 实际上,我会说答案是“是”。即使它是 MSDN 文档,最好也是从该页面复制和粘贴“相关”的内容到您的答案中,然后包含链接供参考。即使很少见,MSDN 的 URL 也有可能失效。而且,除非需要更多信息,否则不需要去另一个网站。同样,如果所有答案都在这里,放在同一个网页上,那么比较不同的答案将更容易实现。 - Ellie Kesselman
3
我同意,复制代码会更好。Feral Oink提出了一个不错的观点,而且如果其他人可以直接查看此帖子中的代码而不需要打开另一个链接,这也能节约下游人员的时间。一个人多花几秒钟的时间可以让许多人节省同样的时间。有人想想孩子们吧! - Anthony
你回答中的链接已失效。暂时可以使用这个链接:https://learn.microsoft.com/zh-cn/office/vba/language/reference/user-interface-help/filter-function - ARich

1

恐怕没有捷径可以做到这一点 - 如果有人能为VB6编写一个Linq包装器就好了!

您可以编写一个函数,通过循环遍历数组并检查每个条目来完成它 - 我认为您不会得到比这更简洁的方法。

这里有一篇提供一些详细信息的示例文章:http://www.vb6.us/tutorials/searching-arrays-visual-basic-6


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接