将数组公式的文本结果转换为可用的格式

当数组公式的结果是数字时,我发现通常很容易find合适的方法将数组合并到一个结果中。 然而,当一个数组公式的结果是文本,我发现很难操纵公式的方式提供了一个单一的预期结果。 总之, 有没有一种方法来处理我忽略的文本结果数组? 看到这个问题的底部,最后的期望公式不起作用,并要求解决scheme。

*编辑 – 再次阅读后,我可以交替总结我的问题:有没有一种方法来访问“公式数组结果”,而不是单独select(例如:与INDEX)多个文本元素?

Array Formulas工作的示例,其中Result Array是数字值

(1)示例1:假定列A行1-500是产品ID的列表,格式为xyz123,列B行1-500显示该产品的总销售额。 如果我想find销售额最高的产品的销售额,那么ID的最后3位数字在400以上,我可以像这样使用数组公式(按CTRL + SHIFT + ENTER而不是ENTER键确认):

=MAX(IF(VALUE(RIGHT(A1:A500,3))>400,B1:B500,"")) 

(2)示例2现在假定列B包含产品名称而不是销售。 我现在想简单地返回与产品ID的最后三位数字大于400的条件匹配的名字。这可以如下完成:

 =INDEX(B1:B500,MIN(IF(VALUE(RIGHT(A1:A500,3))>400,ROW(A1:A500),""))) 

在这里,我已经做了一些操作,以便公式[IF(RIGHT(A1:A500,3 …)]的实际数组部分返回值结果[单元格A1:A500的行的最后3位数大于400];因此我可以使用MIN来显示只匹配的第一个ROW#,然后我可以在一个普通的INDEX函数中使用这个折叠的结果。

(3)例3对于最后一个例子,请看这里的类似问题的讨论[比我下面的总结示例更深入,与这个问题没有直接关系]: https : //stackoverflow.com/a /五百○九万○二十七分之三千一百三十二万五千九百三十五

现在假设您想要一个所有产品名称的列表,其中产品ID的最后3位数字大于400。 据我所知,这不能在一个Cell中完成,只能通过将每个单独的结果放在一个后续的单元上来完成。 例如,可以在C1中放置以下公式,并向下拖动10行,然后显示产品ID的前3位数字大于400的前10个产品名称。

 =INDEX($B$1:$B$500,SMALL(IF(VALUE(RIGHT($A$1:$A$500,3))>400,ROW($A$1:$A$500),""),ROW())) 

数组公式不起作用,其中结果数组是文本值

现在假设我想要在示例3中获得结果,并对它们执行一些文本操作。 例如,假设我想将它们连接成一个文本string。 下面是不行的,因为连接不会像这样的结果数组作为可接受的参数。

 =CONCATENATE((IF(VALUE(RIGHT($A$1:$A$500,3))>400,ROW($B$1:$B$500),""))) 

所以问题是 :有谁知道如何得到这个最后的公式工作? 或者,如何获得一个公式来处理需要一系列文本结果的公式,并将其转换为“可用范围”[因此可以插入上面的Concatenate中],或者可以立即使用文本参数进行处理[如mid ,search,替代等]? 现在我可以看到的唯一方法是使用上面的例子3,然后进一步说,例如,连接(C1,C2,C3 … C10)。

如前所述,没有本地的function,可以做你想在一个单一的细胞。 如果你绝对不能使用VBA,那么你可以使用一个辅助列(如果愿意,可以隐藏列),然后让你想要的结果只显示帮助列的最后一个单元格。

例:

 Produce Name Type Apple Fruit Broccoli Vegetable Carrot Vegetable Orange Fruit 

假设您想要一个单元格显示所有水果结果。 您可以使用另一列来承载此公式。 稍后你会隐藏这个列,所以让我们使用一个,比如Z列。我们也想很容易地改变你正在寻找的东西,所以我们把条件放在D2单元格中。 在单元格Z2中复制下来,您将使用此公式:

 =IF(B2=$D$2,IF(Z1="",A2,Z1&", "&A2),IF(Z1="","",Z1)) 

这将导致以下结果:

 Produce Name Type Search For (other columns until you get to Z) Apple Fruit Fruit Apple Broccoli Vegetable Apple Carrot Vegetable Apple Orange Fruit Apple, Orange 

然后在任何你想要的结果单元格中,我们会说D3,只需使用这个公式从帮助程序列中获取最后的结果,然后隐藏帮助程序列。

 =Z5 

其结果如下:

 Produce Name Type Search For Apple Fruit Fruit Broccoli Vegetable Apple, Orange Carrot Vegetable Orange Fruit 

你可以使用一个dynamic的命名范围,而不是简单的=Z5 ,以确保你总是得到你的帮助列中的最后一个单元格,以便您的数据可以增长或缩小,你仍然会得到正确的结果。 但现在你可以改变Fruit的细胞D2的内容为Vegetable ,现在结果细胞将显示Broccoli, Carrot 。 希望这样的东西可以适应您的需求。

为了重申其他的反应,我没有find在数组上使用连接函数的方法。 然而,我确实find了一种方法来连接“产品名称”,只使用一个数组函数,而不是所谓的“帮助列”。 虽然这是相当长和乏味的,但我认为这可能会增加讨论。 一方面,如果实际上要使用这样的公式来达到某种有效的目的,或者为了克服特定的障碍,可以通过复制和粘贴公式(即实际上相对适应性更强)来轻松使用。 另一方面,如果你的兴趣更多的是好奇心,我的回答可能比你想象的更平庸。

在我的模拟你的问题,我也有两列,但行计数缩短为40.最左列(“C”)包含三个字母和三个数字序列,而右列(“D”)包含随机序列模拟“产品名称”的字母和数字。

我使用了嵌套replace和连接函数的组合。 下面的函数被切断,以聚焦函数的“基本单位”为重点。

基地单位

 REPLACE(INDEX($D$1:$D$40,SMALL(IF(VALUE(RIGHT($C$1:$C$40,3))>400,ROW($D$1:$D$40),""),1)),1,LEN(INDEX($D$1:$D$40,SMALL(IF(VALUE(RIGHT($C$1:$C$40,3))>400,ROW($D$1:$D$40),""),1))),CONCATENATE(INDEX($D$1:$D$40,SMALL(IF(VALUE(RIGHT($C$1:$C$40,3))>400,ROW($D$1:$D$40),""),1)),".",IF(ISERR(INDEX($D$1:$D$40,SMALL(IF(VALUE(RIGHT($C$1:$C$40,3))>400,ROW($D$1:$D$40),""),2)))=TRUE,””, 

上面的公式基本上是查看具有数字序列> 400的相应产品ID的第一个产品名称,然后将其replace为串联,因为存在符合相同产品ID条件的其他产品。 这可以被认为是一个“累积”级联,从最里面的括号开始。 公式的这个“基本单位”可以任意地重复。 也就是说,如果您认为满足您设置的产品ID标准的列表中有200到280个产品,则可以重复此基本代码280次。 正如你看到的,如果公式试图连接不存在的产品名称(你有280个公式基本单位,只有275个产品符合标准),公式自行终止…在某种意义上。 它实际上开始连续不断地重复,直到所有的基地单位制定。 结果将是在一个单元格中连接的所有需要​​的产品名称,并将每个单元格分隔开来。

只有一个数字从base-block变成base-block,这就是SMALL数组的第k个元素。 这些variables显然会在每个基本单位中逐步增加。 对于我的testing,我使用了14个基本单位。

完整的公式与14个基本单位

 =REPLACE(INDEX($D$1:$D$40,SMALL(IF(VALUE(RIGHT($C$1:$C$40,3))>400,ROW($D$1:$D$40),""),1)),1,LEN(INDEX($D$1:$D$40,SMALL(IF(VALUE(RIGHT($C$1:$C$40,3))>400,ROW($D$1:$D$40),""),1))),CONCATENATE(INDEX($D$1:$D$40,SMALL(IF(VALUE(RIGHT($C$1:$C$40,3))>400,ROW($D$1:$D$40),""),1)),".",IF(ISERR(INDEX($D$1:$D$40,SMALL(IF(VALUE(RIGHT($C$1:$C$40,3))>400,ROW($D$1:$D$40),""),2)))=TRUE,””,REPLACE(INDEX($D$1:$D$40,SMALL(IF(VALUE(RIGHT($C$1:$C$40,3))>400,ROW($D$1:$D$40),""),2)),1,LEN(INDEX($D$1:$D$40,SMALL(IF(VALUE(RIGHT($C$1:$C$40,3))>400,ROW($D$1:$D$40),""),2))),CONCATENATE(INDEX($D$1:$D$40,SMALL(IF(VALUE(RIGHT($C$1:$C$40,3))>400,ROW($D$1:$D$40),""),2)),".",IF(ISERR(INDEX($D$1:$D$40,SMALL(IF(VALUE(RIGHT($C$1:$C$40,3))>400,ROW($D$1:$D$40),""),3)))=TRUE,””,REPLACE(INDEX($D$1:$D$40,SMALL(IF(VALUE(RIGHT($C$1:$C$40,3))>400,ROW($D$1:$D$40),""),3)),1,LEN(INDEX($D$1:$D$40,SMALL(IF(VALUE(RIGHT($C$1:$C$40,3))>400,ROW($D$1:$D$40),""),3))),CONCATENATE(INDEX($D$1:$D$40,SMALL(IF(VALUE(RIGHT($C$1:$C$40,3))>400,ROW($D$1:$D$40),""),3)),".",IF(ISERR(INDEX($D$1:$D$40,SMALL(IF(VALUE(RIGHT($C$1:$C$40,3))>400,ROW($D$1:$D$40),""),4)))=TRUE,””,REPLACE(INDEX($D$1:$D$40,SMALL(IF(VALUE(RIGHT($C$1:$C$40,3))>400,ROW($D$1:$D$40),""),4)),1,LEN(INDEX($D$1:$D$40,SMALL(IF(VALUE(RIGHT($C$1:$C$40,3))>400,ROW($D$1:$D$40),""),4))),CONCATENATE(INDEX($D$1:$D$40,SMALL(IF(VALUE(RIGHT($C$1:$C$40,3))>400,ROW($D$1:$D$40),""),4)),".",IF(ISERR(INDEX($D$1:$D$40,SMALL(IF(VALUE(RIGHT($C$1:$C$40,3))>400,ROW($D$1:$D$40),""),5)))=TRUE,””,REPLACE(INDEX($D$1:$D$40,SMALL(IF(VALUE(RIGHT($C$1:$C$40,3))>400,ROW($D$1:$D$40),""),5)),1,LEN(INDEX($D$1:$D$40,SMALL(IF(VALUE(RIGHT($C$1:$C$40,3))>400,ROW($D$1:$D$40),""),5))),CONCATENATE(INDEX($D$1:$D$40,SMALL(IF(VALUE(RIGHT($C$1:$C$40,3))>400,ROW($D$1:$D$40),""),5)),".",IF(ISERR(INDEX($D$1:$D$40,SMALL(IF(VALUE(RIGHT($C$1:$C$40,3))>400,ROW($D$1:$D$40),""),6)))=TRUE,””,REPLACE(INDEX($D$1:$D$40,SMALL(IF(VALUE(RIGHT($C$1:$C$40,3))>400,ROW($D$1:$D$40),""),6)),1,LEN(INDEX($D$1:$D$40,SMALL(IF(VALUE(RIGHT($C$1:$C$40,3))>400,ROW($D$1:$D$40),""),6))),CONCATENATE(INDEX($D$1:$D$40,SMALL(IF(VALUE(RIGHT($C$1:$C$40,3))>400,ROW($D$1:$D$40),""),6)),".",IF(ISERR(INDEX($D$1:$D$40,SMALL(IF(VALUE(RIGHT($C$1:$C$40,3))>400,ROW($D$1:$D$40),""),7)))=TRUE,””,REPLACE(INDEX($D$1:$D$40,SMALL(IF(VALUE(RIGHT($C$1:$C$40,3))>400,ROW($D$1:$D$40),""),7)),1,LEN(INDEX($D$1:$D$40,SMALL(IF(VALUE(RIGHT($C$1:$C$40,3))>400,ROW($D$1:$D$40),""),7))),CONCATENATE(INDEX($D$1:$D$40,SMALL(IF(VALUE(RIGHT($C$1:$C$40,3))>400,ROW($D$1:$D$40),""),7)),".",IF(ISERR(INDEX($D$1:$D$40,SMALL(IF(VALUE(RIGHT($C$1:$C$40,3))>400,ROW($D$1:$D$40),""),8)))=TRUE,””,REPLACE(INDEX($D$1:$D$40,SMALL(IF(VALUE(RIGHT($C$1:$C$40,3))>400,ROW($D$1:$D$40),""),8)),1,LEN(INDEX($D$1:$D$40,SMALL(IF(VALUE(RIGHT($C$1:$C$40,3))>400,ROW($D$1:$D$40),""),8))),CONCATENATE(INDEX($D$1:$D$40,SMALL(IF(VALUE(RIGHT($C$1:$C$40,3))>400,ROW($D$1:$D$40),""),8)),".",IF(ISERR(INDEX($D$1:$D$40,SMALL(IF(VALUE(RIGHT($C$1:$C$40,3))>400,ROW($D$1:$D$40),""),9)))=TRUE,””,REPLACE(INDEX($D$1:$D$40,SMALL(IF(VALUE(RIGHT($C$1:$C$40,3))>400,ROW($D$1:$D$40),""),9)),1,LEN(INDEX($D$1:$D$40,SMALL(IF(VALUE(RIGHT($C$1:$C$40,3))>400,ROW($D$1:$D$40),""),9))),CONCATENATE(INDEX($D$1:$D$40,SMALL(IF(VALUE(RIGHT($C$1:$C$40,3))>400,ROW($D$1:$D$40),""),9)),".",IF(ISERR(INDEX($D$1:$D$40,SMALL(IF(VALUE(RIGHT($C$1:$C$40,3))>400,ROW($D$1:$D$40),""),10)))=TRUE,””,REPLACE(INDEX($D$1:$D$40,SMALL(IF(VALUE(RIGHT($C$1:$C$40,3))>400,ROW($D$1:$D$40),""),10)),1,LEN(INDEX($D$1:$D$40,SMALL(IF(VALUE(RIGHT($C$1:$C$40,3))>400,ROW($D$1:$D$40),""),10))),CONCATENATE(INDEX($D$1:$D$40,SMALL(IF(VALUE(RIGHT($C$1:$C$40,3))>400,ROW($D$1:$D$40),""),10)),".",IF(ISERR(INDEX($D$1:$D$40,SMALL(IF(VALUE(RIGHT($C$1:$C$40,3))>400,ROW($D$1:$D$40),""),11)))=TRUE,””,REPLACE(INDEX($D$1:$D$40,SMALL(IF(VALUE(RIGHT($C$1:$C$40,3))>400,ROW($D$1:$D$40),""),11)),1,LEN(INDEX($D$1:$D$40,SMALL(IF(VALUE(RIGHT($C$1:$C$40,3))>400,ROW($D$1:$D$40),""),11))),CONCATENATE(INDEX($D$1:$D$40,SMALL(IF(VALUE(RIGHT($C$1:$C$40,3))>400,ROW($D$1:$D$40),""),11)),".",IF(ISERR(INDEX($D$1:$D$40,SMALL(IF(VALUE(RIGHT($C$1:$C$40,3))>400,ROW($D$1:$D$40),""),12)))=TRUE,””,**REPLACE(INDEX($D$1:$D$40,SMALL(IF(VALUE(RIGHT($C$1:$C$40,3))>400,ROW($D$1:$D$40),""),12)),1,LEN(INDEX($D$1:$D$40,SMALL(IF(VALUE(RIGHT($C$1:$C$40,3))>400,ROW($D$1:$D$40),""),12))),CONCATENATE(INDEX($D$1:$D$40,SMALL(IF(VALUE(RIGHT($C$1:$C$40,3))>400,ROW($D$1:$D$40),""),12)),".",IF(ISERR(INDEX($D$1:$D$40,SMALL(IF(VALUE(RIGHT($C$1:$C$40,3))>400,ROW($D$1:$D$40),""),13)))=TRUE,””,REPLACE(INDEX($D$1:$D$40,SMALL(IF(VALUE(RIGHT($C$1:$C$40,3))>400,ROW($D$1:$D$40),""),13)),1,LEN(INDEX($D$1:$D$40,SMALL(IF(VALUE(RIGHT($C$1:$C$40,3))>400,ROW($D$1:$D$40),""),13))),CONCATENATE(INDEX($D$1:$D$40,SMALL(IF(VALUE(RIGHT($C$1:$C$40,3))>400,ROW($D$1:$D$40),""),13)),".",IF(ISERR(INDEX($D$1:$D$40,SMALL(IF(VALUE(RIGHT($C$1:$C$40,3))>400,ROW($D$1:$D$40),""),14)))=TRUE,””,INDEX($D$1:$D$40,SMALL(IF(VALUE(RIGHT($C$1:$C$40,3))>400,ROW($D$1:$D$40),""),14))))))))))))))))))))))))))))))))))))))))) 

显然,如果你看看整个公式,这是相当难解的。 但是,从基本单位的angular度来看,你可能会看到如何复制和粘贴它(在编写初始基本单元之后,花费大约2分钟时间来完成)。

这是一个无需VBA的解决scheme,它使用Excel 2016中的Get&Transform或Power Query Add-In for之前的版本:

 let Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content], ExtractLast3Digits = Table.AddColumn(Source, "Value", each Text.End([ProductID],3)), ChangeToNumber = Table.TransformColumnTypes(ExtractLast3Digits,{{"Value", type number}}), FilterAbove400 = Table.SelectRows(ChangeToNumber, each [Value] > 400), Concatenate = Text.Combine(FilterAbove400[ProductName]) in Concatenate 

你可以在“数组输出”(“FilterAbove400”步骤)上执行各种文本处理,在这个例子中,我只是连接了没有分隔符,因为我理解你的请求。

它把你的input数据以表格的forms在第一步(Source)中命名为“Table1”。

链接到解决scheme文件: https : //www.dropbox.com/s/utsraj0bec5ewqk/SE_ConvertArrayFormulasTextResult.xlsx?dl = 0

您可以创build自己的聚合函数来处理公式数组的结果。 它确实需要一点VBA …但并不困难。 这将允许您对值数组进行各种string操作或数值分析。

要做你的连接函数,打开一个VBA代码窗口,并通过右键单击项目 – >插入 – >新模块来创build一个新模块。 双击新模块并插入此代码以创build将数组连接成一个大string的函数:

 Function ConcatenateArray(ParamArray Nums() As Variant) As Variant Dim BigString As String Dim N As Long Dim A() As Variant Let A = Nums(0) BigString = "" For N = LBound(A) To UBound(A) BigString = BigString & A(N, 1) Next ConcatenateArray = BigString End Function 

然后将单元格中的数组公式更改为:

 =ConcatenateArray(IF(VALUE(RIGHT($A$1:$A$500,3))>400,$A$1:$A$500,"")) 

当然,你必须按CTRL + SHIFT + ENTER键而不是ENTER键来确认单元格为数组公式。

我会尽力解决在这篇文章中提出的几个问题:

如何获得一个公式的工作,其中需要一个文本结果数组,并将其转换成'可用范围'[所以它可以插入上面的连接],

即使这个问题的第一部分是可行的,因为CONCATENATE函数没有把范围作为参数,所以最后一部分(即“[因此可以插入到上面的并集中]”是不可能的。

或者可以立即使用文本参数进行操作[比如mid,search,substitute等]? 现在我可以看到的唯一方法是使用上面的例子3,然后进一步说,例如,连接(C1,C2,C3 … C10)。

这当然是一种方法,但请试试这个:

我们从这个开始:

现在假设我想要在示例3中获得结果,并对它们执行一些文本操作。 例如,假设我想将它们连接成一个文本string。

但首先让我们假设如下:

– 。 数据范围位于D10:F510 ,包括ProductProductSalesProduct Name (Selection) *

*用于列举实例3中公式的结果

。 – 数据包含符合实例1中定义的标准的23条logging(见图1)

.-值400在单元格E4input,以便于修改标准而不是公式中的硬代码(参见图3)

图。1 图。1

现在, 为了生成一个带有连接结果的数组,并将其发布到一个可用范围 ,让我们对示例3中的公式应用一个小修改。在G11input该公式数组,并复制到最后一条logging(不只是10行)

 =TRIM(CONCATENATE( IF(ROW(G11)-ROW(G$11)+1=1,"",G10)," ", IFERROR(INDEX($E$11:$E$510, SMALL(IF(VALUE(RIGHT($D$11:$D$510,3))>$E$4,ROW($D$11:$D$510)-ROW($D$11)+1,""), ROW(G11)-ROW(G$11)+1)),""))) 

在这里输入图像说明 图2

D4:E8摘要部分中 ,我们得到了示例1和2的结果以及带有所选产品列表连锁结果(见图3) 。 在E8input此公式(build议将行高增加到最大值409,并将文本换行为真)

 =INDEX($M$11:$M$510,1+MAX(ROW($M$11:$M$510))-ROW($D$11)) 

在这里输入图像说明

图3

关于这个问题:

有没有一种方法可以从“公式数组结果”中访问多个文本元素,而不需要单独select(例如:使用INDEX)?

在这种特殊的情况下(即数组元素的连接),我会应用不同的透视图,并生成带有连接结果的数组,然后select需要的元素,即使需要使用INDEX。

最后我想对这些公式做个小logging:

例2:

 =INDEX(B1:B500,MIN(IF(VALUE(RIGHT(A1:A500,3))>400,ROW(A1:A500),""))) 

如果数据范围没有在Row 1开始,请使用以下公式:

 =INDEX($E$11:$E$510,MIN(IF(VALUE(RIGHT($D$11:$D$510,3))>400, 1+ROW($D$11:$D$510)-ROW($D$11),""))) 

例3:

 =INDEX($B$1:$B$500,SMALL(IF(VALUE(RIGHT($A$1:$A$500,3))>400,ROW($A$1:$A$500),""),ROW())) 

如果数据范围没有在Row 1开始,请使用以下公式:

 =IFERROR(INDEX($E$11:$E$510, SMALL(IF(VALUE(RIGHT($D$11:$D$510,3))>$E$4, 1+ROW($D$11:$D$510)-ROW($D$11),""), 1+ROW()-ROW($K$11))),"")