[英]Excel Match Multiple Criteria Lookup Array: Find columns that contains all values from a list and return the columns position in the array
[英]MS Excel: “MATCH()” does not find cells containing text if lookup array is too large
我正在创建一个庞大而复杂的日程表,我想要一个视图,该视图将日程表显示为日间网格,而另一个视图则允许该视图从字母列表中按名称查找发言人。 我在这里发布了一个简化的示例:
在字母列表中,日期和时间应由使用MATCH的函数填充。 举个例子,我手动输入了Jones希望发生的情况。
我无法通过MATCH()在时间表中正确找到发言人的姓名。 没有隐藏的字符:请注意,在单元格D15中,Excel正确识别出G2和C7相同。
如果我将各种代码放入H2,会发生以下情况:
我想要将= MATCH(G2,$ A $ 1:$ D $ 9)放入H2,然后将单元格填充到H25,并让Excel指出出现相邻名称的日期的列号,然后使用INDIRECT或将其转换为星期几的方法。
由于数据类型不同,在搜索数组中包含列A可能会导致问题。 作为实验,我将第一列放入TEXT,在这种情况下= MATCH(G2,$ A $ 7:$ D $ 7)错误地返回1!
即使这样,我也无法理解为什么$ B $ 7:$ D $ 7起作用,但是$ C $ 2:$ C $ 9或$ B $ 7:$ D $ 8都不起作用。
任何解决方法或替代策略,将不胜感激,谢谢。
为此,您需要添加其他逻辑以找到正确的列和行。 此AGGREGATE()函数完成此工作。
日间使用:
=INDEX($A$1:$D$1,AGGREGATE(15,6,COLUMN($A$2:$D$9)/(($A$2:$D$9=G2)),1))
每小时:
=INDEX($A$1:$A$9,AGGREGATE(15,6,ROW($B$1:$D$9)/(($B$1:$D$9=G2)),1))
Excel 2010中引入了AGGREGATE()函数。
对于其他版本:
在2010年之前,它们将需要是数组公式:
天:
=INDEX($A$1:$D$1,MIN(IF($A$2:$D$9=G2,COLUMN($A$2:$D$9))))
小时:
=INDEX($A$1:$A$9,MIN(IF($B$1:$D$9=G2,ROW($B$1:$D$9))))
作为数组公式,退出编辑模式时必须通过Ctrl-Shift-Enter确认。 正确完成后,Excel会自动在公式周围放置{}来表示数组公式。
最新的Office 360或在线:
天:
=INDEX($A$1:$D$1,MINIFS(COLUMN($A$2:$D$9),$A$2:$D$9,G2))
小时:
=INDEX($A$1:$A$9,MINIFS(ROW($B$1:$D$9),$B$1:$D$9,G2))
至于MATCH在这种情况下将无法工作的原因:
MATCH()仅适用于单行或单列,而不适用于多列/行范围。 它设置为返回等于找到的顺序的数字,因此必须是一维数组。
在给定数据集的情况下,最有效的方法是使用三个MATCH查询-每列一个。
对于Day,它看起来像这样:
=IF(ISERROR(MATCH(G2,$B$2:$B$10,0)),"",$B$1)&IF(ISERROR(MATCH(G2,$C$2:$C$10,0)),"",$C$1)&IF(ISERROR(MATCH(G2,$D$2:$D$10,0)),"",$D$1)
对于“时间”,它看起来像这样:
=INDEX($A$2:$A$10,IFERROR(MATCH(G2,$B$2:$B$10,0),0) + IFERROR(MATCH(G2,$C$2:$C$10,0),0) + IFERROR(MATCH(G2,$D$2:$D$10,0),0))
...但是说实话,在像这样的小型数据集上,与Scott的AGGREGATE方法相比,您不会注意到此方法的任何性能差异。 在大型数据集(数千行)上,您可能会这样做。
请注意,您的初始方法失败的另一个原因是您没有指定MATCH的第3个参数,因此Excel使用了默认值,该默认值假定您的列表数据按字母顺序排序。 您几乎永远不想忽略该参数,并且几乎总是想要使用FALSE(或零,这意味着从FALSE到Excel)
vba和listobjects的替代解决方案(您需要给两个表命名,如下面的代码所示)工作表屏幕快照 Public Sub makeAppointmentList()Dim aSheet As Worksheet Set aSheet = ThisWorkbook.Worksheets(“ sheet1”)
Dim aSchedule As ListObject
Set aSchedule = aSheet.ListObjects("schedule")
Dim anAppointmentList As ListObject
Set anAppointmentList = aSheet.ListObjects("appointmentList")
On Error Resume Next
anAppointmentList.DataBodyRange.Delete
On Error GoTo 0
Dim c As ListColumn
Dim r As ListRow
Dim newRow As ListRow
For Each c In aSchedule.ListColumns
For Each r In aSchedule.ListRows
If c.Index > 1 And Intersect(c.Range, r.Range) <> "" Then
Set newRow = anAppointmentList.ListRows.Add
Intersect(newRow.Range, anAppointmentList.ListColumns("Name").Range).Value = Intersect(c.Range, r.Range)
Intersect(newRow.Range, anAppointmentList.ListColumns("Day").Range).Value = Intersect(c.Range, aSchedule.HeaderRowRange)
Intersect(newRow.Range, anAppointmentList.ListColumns("Time").Range).Value = Intersect(aSchedule.ListColumns(1).Range, r.Range)
End If
Next r
Next c
anAppointmentList.Sort.SortFields.Clear
anAppointmentList.Sort.SortFields.Add Key:=Intersect(anAppointmentList.HeaderRowRange, _
anAppointmentList.ListColumns("Name").Range)
anAppointmentList.Sort.SortFields.Add Key:=Intersect(anAppointmentList.HeaderRowRange, _
anAppointmentList.ListColumns("Day").Range), _
CustomOrder:="Mon,Tue,Wed,Thu,Fri,Sat,Sun"
anAppointmentList.Sort.SortFields.Add Key:=Intersect(anAppointmentList.HeaderRowRange, _
anAppointmentList.ListColumns("Time").Range)
anAppointmentList.Sort.Apply
Dim s As SortField
End Sub
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.