求助:如何用公式/VBA按序提取另一工作表中重复产品的订单ID
实现重复查询时按顺序提取未获取的订单ID
一、函数公式方案(适合新手快速上手)
1. 兼容旧版Excel的数组公式
假设Lookup表中产品名称在A列,要提取的订单ID放在B列,原始表(Original Sheet)的产品列是A列、订单ID列是B列。在Lookup表的B2单元格输入以下公式,旧版Excel按Ctrl+Shift+Enter确认,Excel 365/2021直接回车即可:
=INDEX(Original!$B:$B,SMALL(IF(Original!$A:$A=$A2,ROW(Original!$A:$A)),COUNTIF($A$2:$A2,$A2)))
- 逻辑说明:
COUNTIF($A$2:$A2,$A2)统计当前行及以上该产品出现的次数(第一次输入产品返回1,第二次返回2);IF(Original!$A:$A=$A2,ROW(Original!$A:$A))获取原始表中所有匹配产品的行号;SMALL取第N个行号,最后用INDEX提取对应订单ID。
2. Excel 365/2021简化公式
如果用的是新版Excel,直接用FILTER筛选后取对应位置的元素,公式更直观:
=INDEX(FILTER(Original!$B:$B,Original!$A:$A=$A2),COUNTIF($A$2:$A2,$A2))
- 逻辑说明:
FILTER先把原始表中该产品的所有订单ID筛选成一个列表,再用INDEX根据COUNTIF统计的次数取列表中第N个值。
二、VBA自定义函数方案(更灵活可控)
如果需要更灵活的逻辑(比如无数据时自定义提示),可以写个简单的自定义函数:
- 按
Alt+F11打开VBA编辑器,右键点击当前工作簿→插入→模块; - 粘贴以下代码:
Function GetNextOrder(productName As String, srcProductRange As Range, srcOrderRange As Range, currentRow As Long) As String Dim matchTimes As Integer Dim i As Integer Dim cell As Range '统计当前行及以上该产品的输入次数 matchTimes = Application.WorksheetFunction.CountIf(srcProductRange.Worksheet.Range(srcProductRange.Cells(1), srcProductRange.Worksheet.Cells(currentRow, srcProductRange.Column)), productName) '遍历原始表找对应次数的订单ID i = 0 For Each cell In srcProductRange If cell.Value = productName Then i = i + 1 If i = matchTimes Then GetNextOrder = srcOrderRange.Cells(cell.Row - srcProductRange.Row + 1).Value Exit Function End If End If Next cell '无更多数据时返回提示 GetNextOrder = "无剩余订单" End Function
- 回到Lookup表,在B2单元格输入:
=GetNextOrder(A2,Original!$A:$A,Original!$B:$B,ROW())
下拉填充即可。
注意事项
- 尽量缩小公式或VBA中的引用范围(比如用
Original!$A$2:$A$1000代替Original!$A:$A),避免整列引用拖慢Excel运行速度; - 确保原始表的产品和订单ID一一对应,无空行或错误值。
内容的提问来源于stack exchange,提问作者Jhon
相关产品推荐
相关产品推荐

