![使用 Excel VBA 查找最后一行匹配](https://linux22.com/image/1500177/%E4%BD%BF%E7%94%A8%20Excel%20VBA%20%E6%9F%A5%E6%89%BE%E6%9C%80%E5%90%8E%E4%B8%80%E8%A1%8C%E5%8C%B9%E9%85%8D.png)
我有一个包含日期和 ActionCode 列的电子表格。我使用 Worksheet_Change 事件在用户输入 ActionCode 后运行一些代码。我希望有一个过程(当用户输入特定代码时)在同一列中找到该代码的最近上一个实例,然后返回该列中的日期。例如:
Date |ActionCode
11/4/1999| 2
12/5/1999| 3
1/2/2000 | 2
2/3/2001 | 5
3/1/2001 | 2
当用户在 2001 年 3 月 1 日输入 ActionCode“2”时,我希望返回代码1/2/2000
而不是11/4/1999
。我查看了MATCH
,但似乎只会返回11/4/1999
。我发现了许多通过在工作表中输入公式来执行此操作的建议,但我不知道如何将它们适应 VBA。
答案1
VBA解决方案:
这是一个使用 Worksheet_Change 事件的 VBA 解决方案,正如您所建议的那样。它将从 F1 读取用户输入并将输出放在 F2 中。数据假定位于 A 列和 B 列中。要更改这些位置,您需要将每个实例替换为所需的输入、输出和数据地址。
Private Sub Worksheet_Change(ByVal Target As Range)
Dim userInput As Variant, codeTable() As Variant, maxDate As Long
Application.EnableEvents = False
'Make sure worksheet change affected user input cell
If Not Intersect(Range("F1"), Target) Is Nothing Then
userInput = Range("F1").Value
If userInput = "" Then
Range("F2") = ""
Else
'Store table data in an array for fast processing
codeTable = Range("A2", Range("B1").End(xlDown)).Value
maxDate = 0
'Find max date for input code
For i = LBound(codeTable, 1) To UBound(codeTable, 1)
If codeTable(i, 2) = userInput Then
maxDate = Application.WorksheetFunction.Max(maxDate, codeTable(i, 1))
End If
Next i
'Print output to sheet
If maxDate = 0 Then
Range("F2") = "No records"
Else
Range("F2") = Format(maxDate, "m/d/yyyy")
End If
End If
End If
Application.EnableEvents = True
End Sub
配方解决方案:
您可以使用数组公式获得相同的结果——无需将 VBA 添加到您的工作簿。
在您想要的输出单元格中,将以下内容粘贴到公式栏中,然后按Ctrl+ Shift+ Enter。
=MAX(($B$2:$B$21=F1)*A2:A21)
在此公式中,B2:B21
保存您的操作代码并A2:A21
关联日期。
示例输出(两种解决方案):
答案2
您可以使用公式:
=AGGREGATE(14,6,(Dates<J2)*(ActionCode=J3)*Dates,1)
- J2 = 用户输入的日期,或者
TODAY()
如果您的字面意思就是这个。 - J3 = 用户输入的操作代码
因为我们对符合小于用户输入条件的日期使用 LARGE 函数,并且操作代码 = 用户输入,所以日期输入顺序无关紧要。
如果日期按升序排列,那么您可以使用更简单的公式:
=LOOKUP(2,1/((Dates<J2)*(ActionCode=J3)),Dates)