【问题标题】:Excel VBA search within range from previous columnExcel VBA 在上一列的范围内搜索
【发布时间】:2021-07-07 19:18:28
【问题描述】:

我尝试实现this,但我遇到了编译器错误(“错误的限定”或类似的东西,它不是我拥有的英文版 Excel)。我想这与范围/字符串有关?

Function SearchForTotal(givenLocation As Range, searchText As String) As Range
    Debug.Print givenLocation 'gives $U$83
    Dim startSearchFrom As String
    '-1 because it's from previous column you'll be searching in
    startSearchFrom = givenLocation.Offset(0, -1).Address
    Debug.Print startSearchFrom
    Dim i As Integer: i = startSearchFrom.Row
    Do While i > 0
        If (searchText = ThisWorkbook.Sheets("Sheet1").Range(startSearchFrom.column & i).Value) Then
            Set SearchForTotal= Range(startSearchFrom.column & i)
            Exit Do
        End If
        i = i - 1
    Loop
End Function

错误来自“Dim i As Integer: i = startSearchFrom.Row”行

我还尝试将变量 startSearchFrom 作为 range 而不是 string(然后使用 Set),但是使用此代码我也有编译器错误(“类型不匹配”)。

【问题讨论】:

  • 尝试将“Dim i As Integer: i = startSearchFrom.Row”分成不同的行: Dim i As Integer i = startSearchFrom.Row 会发生什么?
  • startSearchFrom 是一个字符串,所以它不能有.Row.Column 属性。这将始终返回错误。另外,如果i > 32767 你会得到一个溢出错误,并且可以有比工作表上更多的行。
  • 您已经提供了指向您之前 Q 的链接,但没有遵循您接受的 A 中给出的建议。回去重读 A,并在这里应用它的建议
  • @chrisneilsen 我知道这与 Range & 字符串类型有关,但无法单独解决,抱歉

标签: excel vba


【解决方案1】:

startSearchFrom.column 是一个数字,所以使用.Cells(rowno,colno) 而不是.Range()

Option Explicit

Function SearchForTotal(givenLocation As Range, searchText As String) As Range
    
    Dim ws As Worksheet, iCol As Long, iRow As Long
    Set ws = ThisWorkbook.Sheets("Sheet1")

    '-1 because it's from previous column you'll be searching in
    iCol = givenLocation.Offset(0, -1).Column
    iRow = givenLocation.Row

    Do While iRow > 0
        If (searchText = ws.Cells(iRow, iCol).Value) Then
            Set SearchForTotal = ws.Cells(iRow, iCol)
            Exit Do
        End If
        iRow = iRow - 1
    Loop
End Function

Sub test()
    Debug.Print SearchForTotal(Range("U83"), "test").Address
End Sub

【讨论】:

  • 我不想将 SearchForTotal 函数运行到调试打印中,而是将其存储到一个变量中(在我的例子中是“resultAddress as Range”变量),我该如何存储它?只需:resultAddress = SearchForTotal(Range("U83"), "test") 或使用 Set ?
  • @smirnoff 与Set resultAddress = SearchForTotal(Range("U83"), "test")
  • 你的功能试过了吗?我认为 iCol 变量存在问题,在我的示例中,我需要使用的范围是 T81。用你的代码我有这个: $CC$20 ?
  • @smirnoff 你在哪里有$CC$20
  • 我在我的 debug.print 中得到了结果,但这是因为我已经将行与列在一行上进行了切换:$ :p 抱歉,但是您的代码运行良好,谢谢非常。问题解决了!
【解决方案2】:

使用循环查找值

  • 使用Find 方法肯定是更好(更有效)的方法。
Option Explicit

Function SearchForTotalLoop( _
    ByVal GivenLocation As Range, _
    ByVal SearchText As String) _
As Range
    
    If GivenLocation Is Nothing Then Exit Function
    ' There's nothing to left of column `A`:
    If GivenLocation.Column = 1 Then Exit Function

    '-1 because it's from the previous column you'll be searching in
    Dim rgStart As Range: Set rgStart = GivenLocation.Offset(0, -1)
    
    Dim ws As Worksheet: Set ws = GivenLocation.Worksheet
    
    Dim r As Long: r = rgStart.Row
    Dim Col As Long: Col = rgStart.Column
    
    Do While r > 0
        If ws.Cells(r, Col).Value = SearchText Then ' A<>a
        ' To ignore case i.e. 'A = a', rather use the following:
        'If StrComp(ws.Cells(r, Col).Value, SearchText, vbTextCompare) = 0 Then
            Set SearchForTotal = ws.Cells(r, Col)
            Exit Do
        End If
        r = r - 1
    Loop

End Function

Sub SearchForTotalTEST()
    ' s - Start
    ' f - Found
    Dim sCell As Range: Set sCell = Range("B83")
    Dim fCell As Range: Set fCell = SearchForTotal(sCell, "Total")
    If fCell Is Nothing Then Exit Sub
    MsgBox "Starting Cell: " & sCell.Address & vbLf _
        & "Found Cell: " & fCell.Address & vbLf _
        & "Found Value: " & fCell.Value, vbInformation, "Find Total"
End Sub

编辑

  • 使用Find 方法,您可以执行以下操作(未经测试)。
Function SearchForTotal( _
    ByVal GivenLocation As Range, _
    ByVal SearchText As String) _
As Range
    
    ' These two could be additionally used as arguments of the function.
    Const FirstRow As Long = 1
    Const ColOffset As Long = -1
    
    If GivenLocation Is Nothing Then Exit Function
    ' There's nothing to left of column `A`:
    If GivenLocation.Column + ColOffset < 1 Then Exit Function
    If FirstRow > GivenLocation.Row Then Exit Function
    
    Dim ws As Worksheet: Set ws = GivenLocation.Worksheet
    
    If GivenLocation.Column + ColOffset > GivenLocation.Columns.Count _
        Then Exit Function
    If FirstRow > GivenLocation.Rows.Count Then Exit Function
    
    Dim lCell As Range: Set lCell = GivenLocation.Cells(1).Offset(0, ColOffset)
    Dim fCell As Range: Set fCell = ws.Cells(FirstRow, lCell.Column)
    
    Dim rg As Range: Set rg = ws.Range(fCell, lCell)
    
    Dim rCell As Range
    Set rCell = rg.Find(SearchText, , xlFormulas, xlWhole, , xlPrevious)
    If rCell Is Nothing Then Exit Function
    
    Set SearchForTotal = rCell

End Function

【讨论】:

  • 感谢您的宝贵时间,您的代码可能也是正确的,但对我来说太复杂了(抱歉,我只是一个菜鸟)所以我使用了其他答案,无论如何,谢谢。
猜你喜欢
  • 2013-03-18
  • 2018-09-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-10-31
  • 2017-10-25
相关资源
最近更新 更多