【问题标题】:VLOOKUP return an array for SMALL functionVLOOKUP 为 SMALL 函数返回一个数组
【发布时间】:2014-04-18 17:13:10
【问题描述】:

我正在尝试使用 VLOOKUP 为 SMALL 函数返回一个数组,以便我可以根据查找来评估 X 个最小值。查找表如图所示。

上图来自“使用多少”工作表。我正在使用以下公式=VLOOKUP(COUNTA($N9:AA9),'How Many to Use'!A2:C14,3),但 Excel 扼杀了我的公式 (#VALUE),因为它返回预期的数组,但将其作为文本返回,而不是我希望用于 SMALL 函数的真正数组。 有没有办法将其转换为实际数组?

上下文中的完整公式试图在我的主工作表中的数组中平均使用一定数量的值,并根据行值中的完整计数来平均最小的 X 值。

=IF(COUNT($N9:Z9)<>0,IF(COUNT($N9:Z9)<=3,AVERAGE($N9:Z9),SUM(SMALL(INDEX($N9:Z9,MATCH(TRUE,COLUMN($N9:Z9)=LARGE(NOT(ISBLANK($N9:Z9))*COLUMN($N9:Z9),COUNTA($N9:AA9)),0)):Z9,VLOOKUP(COUNTA($N9:AA9),'How Many to Use'!A2:C14,3)))/VLOOKUP(COUNTA($N9:AA9),'How Many to Use'!A2:C14,2)),"")

【问题讨论】:

    标签: excel excel-formula


    【解决方案1】:

    从狭隘开始,向外努力:

    (1) 要直接回答您的问题,您可以使用 VBA 将字符串转换为数组,例如:

    Function Eval(formulaText As String, Optional stable As Boolean = False) As Variant
        Application.Volatile Not stable
        Eval = Evaluate(formulaText)
    End Function
    

    =Eval(VLOOKUP(COUNTA($N9:AA9),'How Many to Use'!A2:C14,3),true)

    (请注意,即使您在这里不需要它,我也包含了 volatile 机制,因为您使用它的方式是不需要声明 volatile 的特殊情况。除非您知道得更好。)

    但是,这并不是必须的。

    (2) 我通常生成一个 1-k 整数数组的方法是:

    =COLUMN(A1:INDEX(1:1,k))
    

    (跟随你的脚步,使用行数组,虽然我倾向于使用列。显然必须在数组公式中。)

    (3) 但是您真正想做的是平均一个数组中的 k 个最小值。为此,我会这样做:

    =AVERAGE(IF(RANK(A1:Z1,A1:Z1,1)+COLUMN(A1:Z1)/COLUMNS(A1:Z1)<=SMALL(RANK(A1:Z1,A1:Z1,1)+COLUMN(A1:Z1)/COLUMNS(A1:Z1),10),A1:Z1,""))
    

    其中A1:Z1 是数组,10 是要包含的项目数,以数组公式的形式输入。

    您不能只使用 SMALL 作为包含测试的原因,您无疑已经知道,这是因为第 k 个项目可能是具有相同值的多个项目之一。所以,我使用 RANK 为每个值分配一个整数(如果它们已经是整数,这不是必需的)然后我根据出现的顺序添加一个分数来为每个保持其位置的值生成一个 id:RANK(A1:Z1,A1:Z1,1)+COLUMN(A1:Z1)/COLUMNS(A1:Z1)如果一个值的 id 是最小值之一(在我的示例中为最小的 10),则包含该值,否则我将 "" 传递给 AVERAGE 函数。

    要获取要使用的项目数(在我的示例中代替“10”),您可以使用表查找或使用诸如 MAX(1,MIN(10,COUNT(A1:Z1)-1)) 之类的规则。

    因此,使用您的范围的最终公式可能是:

    =AVERAGE(IF(RANK($N9:AA9,$N9:AA9,1)+COLUMN($N9:AA9)/COLUMNS($N9:AA9)<=SMALL(RANK($N9:AA9,$N9:AA9,1)+COLUMN($N9:AA9)/COLUMNS($N9:AA9),MAX(1,MIN(10,COUNT($N9:AA9)-1))),$N9:AA9,""))
    

    【讨论】:

    • 感谢您的精彩解释和创造性思维。我将其插入并遵循您的公式,我认为它会出现一个例外 - 空白单元格返回 #N/A 用于 RANK 函数。我对如何避免空白单元格的 N/A 有点困惑。再次感谢您的周到分析。
    • @p0werenner 您可以将 RANK($N9:AA9,$N9:AA9,1) 替换为 IFERROR(RANK($N9:AA9,$N9:AA9,1),COUNT($N9: AA9)+1)
    猜你喜欢
    • 2017-02-03
    • 1970-01-01
    • 1970-01-01
    • 2011-06-23
    • 2012-04-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-08
    相关资源
    最近更新 更多