Как извлечь подмассив из массива в функции листа? - PullRequest
9 голосов
/ 19 октября 2011

Есть ли какой-нибудь способ получить массив в Excel меньшего размера, чем начальный массив в функции таблицы ячеек?

Так что если бы у меня было:

{23, "", 34, 46, "", "16"}

Я бы закончил с:

{23, 34, 46, 16}

, которой я мог бы потом манипулировать с другой функцией.

Вывод: Если бы мне нужно было сделать много из них, я бы определенно использовал решение для расчесывания UDF от jtolle. Формула, которую использует PPC, близка, но, обнаружив, что тестирование приводит к ошибкам в пустых слотах, пропускает первое значение, и есть более простой способ получить номера строк, поэтому вот мое окончательное решение: *

=IFERROR(INDEX($A$1:$A$6, SMALL(IF(($A$1:$A$6<>""),ROW($A$1:$A$6)),ROW(1:6))),"")

Который должен быть введен как формула массива (CTRL-SHIFT-ENTER). Если он отображается, он должен быть введен как минимум в область размером с набор результатов, чтобы показать все результаты.

Ответы [ 3 ]

7 голосов
/ 19 октября 2011

Если все, что вы хотите сделать, это получить подмножество массива, и вы уже знаете позиции элементов, которые вы хотите , вы можете просто использовать INDEX с массивом для аргумента индекса.То есть:

=INDEX({11,22,33,44,55},{2,3,5})

возвращает {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

Я разместил только псевдокод, потому что мой реальный код - это все вызовы библиотечных функций, включая операции сбора позиций и операции копирования с позиций.Это, вероятно, затеняет основную идею, которая довольно проста.

Вы бы назвали такой UDF следующим образом:

=combSeq({23, "", 34, 46, "", "16"}, {23, "", 34, 46, "", "16"} <> "")

или

=combSeq(Q1:Q42, SIN(Z1:Z42) > 0.5)

и использоватьОбычная механика массива в Excel для генерации «гребенки».Это легкий, дружественный к Excel способ получить множество преимуществ более стандартной функции filter(list-to-filter, test-function), которую вы можете увидеть в других системах программирования.

Я использую имя «гребень», потому что «фильтр» обычно означает «фильтр с этой функцией», а в Excel вы должны применить функцию теста перед вызовом функции фильтрации.Также может быть полезно вычислить одну «расческу» в качестве промежуточного результата, а затем использовать ее для ... э-э, расчесывания ... нескольких списков.

5 голосов
/ 04 апреля 2012

На этом сайте есть ответ: 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)
         )
      )

Вот объяснение:

  • ROW () - ROW ($ B $ 1) - это просто трюк, который даст вам увеличивающееся число (т. Е. 1 в B1, 2 в B2 ...)
  • IF (..., ROW ($ A $ 2: $ A $ 6)) является основной частью трюка: он строит массив номеров строк, где Условие IF верно (обратите внимание, что IF не имеет значения 'else')
  • SMALL (..) вернет X-е наименьшее значение этого массива (в нашем случае номер X-й непустой строки), где X - номер строки текущая ячейка (1 в B1 ...)
  • INDEX преобразует номер строки в его значение
  • Обратите внимание, что INDEX и ROW начинаются на одну строку выше фактической таблицы, чтобы всегда иметь смещение> 0 (INDEX не как нули)
1 голос
/ 19 июля 2015

Возможное решение функции листа:

=INDEX(A1:A6,N(IF(1,MODE.MULT(IF(A1:A6<>"",ROW(1:6)*{1,1})))))

Функция MODE.MULT возвращает сокращенный массив индексов, и N(IF(1,.)) вставляется так, что массив передается по ссылке к функции INDEX.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...