4

假设我在任意列中有第 1 行以下的这些值:

1 A
2 A
3 A
4 A
5 B
6 B
7 B
8 A
9 A
10 A

我希望能够说 start=5 是第一个 B,last=7 是最后一个 B。如果第一个和最后一个都没有 B,则返回 0。

4

4 回答 4

17

不要忘记在 VBA 中您仍然可以访问大量的内置 Excel 函数。示例(假设您的数据在第 1 列中):

找到第一个 B...
Columns(1).Find(What:="B", LookAt:=xlWhole, MatchCase:=False).Row 'Returns 5

找到最后一个 B...
Columns(1).Find(What:="B", LookAt:=xlWhole, SearchDirection:=xlPrevious, MatchCase:=False).Row 'Returns 7

如果未找到 B,则返回错误。如果没有找到 B,我们可以通过使用错误处理返回 0 来利用这一点。把它们放在一起...

Sub DoTest()
  Dim RowFirst As Integer, _
      RowLast As Integer
  On Error GoTo ErrorHandler
  RowFirst = Columns(1).Find(What:="B", LookAt:=xlWhole, SearchDirection:=xlNext, MatchCase:=False).Row
  RowLast = Columns(1).Find(What:="B", LookAt:=xlWhole, SearchDirection:=xlPrevious, MatchCase:=False).Row
  Exit Sub
ErrorHandler:
  RowFirst = 0
  RowLast = 0
End Sub
于 2014-10-01T08:24:56.407 回答
3

像这样的东西对你有用还是你需要两个独立的功能?

Function findValues(place As String, val As String, rng As Range) As Integer
    Dim r As Range
    findValues = 0
    For Each r In rng
        If InStr(r.Value2, val) > 0 Then
            findValues = r.Row
            If LCase(place) = "first" Then
                Exit For
            End If
        End If
    Next
End Function

像这样使用:

Dim rng As Range
Set rng = Range("B1:B10")
Dim i As Integer
i = findValues("first", "B", rng)
i = findValues("last", "B", rng)

根据您需要检查的范围有多大,这可能需要一段时间。

于 2012-12-07T19:25:34.900 回答
1

这是另一种方式。

Sub FindFirstLast()

    Dim vaValues As Variant
    Dim vaFilter As Variant
    Dim lFirst As Long
    Dim lLast As Long

    Const sFIND As String = "B"

    With Application.WorksheetFunction
        'Get a 1-d array from a column
        vaValues = .Transpose(Sheet1.Range("A1:A10").Value)

        'Use match to get the first instance
        lFirst = .Match(sFIND, vaValues, False)

        'Filter on the values
        vaFilter = Filter(vaValues, sFIND)

        'Assumes they're all together
        lLast = lFirst + UBound(vaFilter)
    End With

    Debug.Print lFirst, lLast

End Sub
于 2012-12-07T21:44:32.667 回答
1

我一直在一些应用程序中使用 Kevin Pope 的方法,但发现它有时会包含我不想要的东西。以为我会分享我的经验和解决方案。

最近我意识到,如果我有这样的事情:

Mouser  EPM1270GT144I5
Mouser  EPM1270GT144I5
Mouser  GRM32DR71E106K
Mouser  GRM32DR71E106K
TTI     GRM32DR71E106KA12L
Avnet   GS816273CC-250I
Avnet   GS816273CC-250I

并且正在寻找这个:GRM32DR71E106K

它将返回我正在搜索的两个和以相同字符串开头的第三个。

我需要适应搜索精确匹配项。修复非常简单:

 Public Function findValues(Val As String, Rng As Range, Optional place As Integer) As Integer
        Dim R As Range
        findValues = 0
        For Each R In Rng
            If StrComp(R.Value2, Val) = 0 Then
    '        If InStr(R.Value2, Val) > 0 Then
                findValues = R.Row
                If place = 1 Then
                    Exit For
                End If
            End If
        Next
    End Function

我希望有人觉得这很有用。

于 2013-05-06T17:16:48.177 回答