如何从工作表函数中的数组中提取子数组?

Lan*_*rts 9 arrays excel worksheet-function

有没有办法在Excel中获取比单元格工作表函数中的起始数组更小的数组?

所以,如果我有:

{23, "", 34, 46, "", "16"}
Run Code Online (Sandbox Code Playgroud)

我最终得到:

{23, 34, 46, 16}
Run Code Online (Sandbox Code Playgroud)

然后,我可以使用其他一些功能进行操作.

结论:如果我要做很多这些,我肯定会使用jtolle的UDF梳子解决方案.PPC使用的公式很接近,但潜入并测试,我发现它在空插槽中出错,错过了第一个值,并且有更简单的方法来获取行号,所以这是我的最终解决方案:

=IFERROR(INDEX($A$1:$A$6, SMALL(IF(($A$1:$A$6<>""),ROW($A$1:$A$6)),ROW(1:6))),"")
Run Code Online (Sandbox Code Playgroud)

必须以数组公式(CTRL-SHIFT-ENTER)输入.如果显示,则必须至少输入与结果集一样大的区域以显示所有结果.

jto*_*lle 7

如果您只想获取数组的子集,并且已经知道所需元素的位置,则可以使用INDEX数组作为索引参数.那是:

=INDEX({11,22,33,44,55},{2,3,5})
Run Code Online (Sandbox Code Playgroud)

回报{22,33,55}.但这通常不是很有用,因为你不知道这些位置,而且我不知道如何在没有UDF的情况下获得它们.

我为这种工作表数组过滤所做的是用以下形式编写UDF:

'Filters an input sequence based on a second "comb" sequence.
'Non-False-equivalent, non-error values in the comb represent the positions of elements
'to be kept.
Public Function combSeq(seqToComb, seqOfCombValues)

    'various library calls to work with 1xn or nx1 arrays or ranges as well as 1-D arrays

    'iterate the "comb" and collect positions of keeper elements

    'create a new array of the right length and copy in the keeper elements

End Function
Run Code Online (Sandbox Code Playgroud)

我只发布了伪代码,因为我的实际代码是对库函数的所有调用,包括collect-positions和copy-from-positions操作.它可能会掩盖基本思想,这很简单.

你会像这样调用这样的UDF:

=combSeq({23, "", 34, 46, "", "16"}, {23, "", 34, 46, "", "16"} <> "")
Run Code Online (Sandbox Code Playgroud)

要么

=combSeq(Q1:Q42, SIN(Z1:Z42) > 0.5)
Run Code Online (Sandbox Code Playgroud)

并使用Excel的常规数组机制生成"梳子".它是一种轻量级,Excel友好的方式,可以获得filter(list-to-filter, test-function)您在其他编程系统中看到的更标准功能的许多好处.

我使用名称"梳子",因为"过滤器"通常表示"使用此功能过滤",而使用Excel,您必须在调用过滤功能之前应用测试功能.计算一个"梳子"作为中间结果,然后用它来梳理......多个列表也很有用.

  • @Lance,啊哈,我需要进一步获得资格.在`= INDEX({11,22,33,44,55},{2,3,5})`情况下,公式所在的范围必须是水平数组.如果你把它放在一个垂直数组中,你将只重复22,除非你使用分号,即`= INDEX({11; 22; 33; 44; 55},{2; 3; 5})`. (2认同)

PPC*_*PPC 5

这个网站上有一个答案:http://www.mrexcel.com/forum/showthread.php?t = 112002.但是解释不多.

假设您在A列上有空白单元格的数据,并将其放在B列中; 将以跳过空白的相同顺序检索数据

=INDEX(  $A$1:$A$6, 
         SMALL(  
            IF(
               ($A$2:$A$6<>""), 
               ROW($A$2:$A$6)
            ), 
         ROW()-ROW($B$1)
         )
      )
Run Code Online (Sandbox Code Playgroud)

这是解释:

  • ROW() - 行($ B $ 1)只是一个技巧,可以给你一个递增的数字(即B1中的1,B2中的2 ......)
  • IF(...,ROW($ A $ 2:$ A $ 6))是这个技巧的主要部分:它构建了IF条件为真的行号数组(注意IF没有'else'值)
  • SMALL(..)将返回该数组的第X个最小值(在我们的例子中是第X个非空行的编号),其中X是当前单元格的行号(B1中的1 ...)
  • 然后, INDEX将从行号转换为其值
  • 请注意,INDEXROW在实际表上方开始一行,以始终具有偏移> 0(INDEX不喜欢零)