繁体   English   中英

MS Excel:如果查找数组太大,“ MATCH()”将找不到包含文本的单元格

[英]MS Excel: “MATCH()” does not find cells containing text if lookup array is too large

我正在创建一个庞大而复杂的日程表,我想要一个视图,该视图将日程表显示为日间网格,而另一个视图则允许该视图从字母列表中按名称查找发言人。 我在这里发布了一个简化的示例:

http://www.calpoly.edu/~epearse/excel-issue.png

在字母列表中,日期和时间应由使用MATCH的函数填充。 举个例子,我手动输入了Jones希望发生的情况。

我无法通过MATCH()在时间表中正确找到发言人的姓名。 没有隐藏的字符:请注意,在单元格D15中,Excel正确识别出G2和C7相同。

如果我将各种代码放入H2,会发生以下情况:

  • = MATCH(G2,$ A $ 1:$ D $ 9)结果为#N / A
  • = MATCH(G2,$ C $ 2:$ C $ 9)结果为#N / A
  • = MATCH(G2,$ B $ 7:$ D $ 7)结果为2(正确!)
  • = MATCH(G2,$ A $ 7:$ D $ 7)结果为#N / A

我想要将= 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM