Формула Excel для заполнения массива

Примеры. Скажем, у меня есть несколько одномерных массивов, таких как A, B и C:

 A    B    C
---  ---  ---
 2    4    99
 3    5    37
 4    6    42
      7

Я хочу использовать формулу для заполнения каждого из этих массивов (которые являются именованными диапазонами), чтобы они имели одинаковое количество строк. (Отредактировано, чтобы дать более полное объяснение:) Я также хотел бы иметь возможность сдвигать начальную позицию каждого массива на указанное количество строк. Вот пример вывода, где я сдвигаю A на два, B на три и C на одну позицию:

 A'   B'   C'
---  ---  ---
 0    0    0
 0    0    99
 2    0    37
 3    0    42
 4    4    0
 0    5    0
 0    6    0
 0    7    0

Таким образом, «формула» (на самом деле комбинация нескольких существующих стандартных формул) для заполнения одного из массивов будет фактически иметь четыре входа: имя/диапазон исходного массива, количество значений для заполнения в начале исходного массива, число для заполнения в конце и значение заполнения (т. е. 0, NA() и т. д.).

Первоначальный подход. Моей первой попыткой было объединить три части массива (начальный массив заполнения, исходный массив и конечный массив заполнения) в один массив следующим образом:

=INDIRECT("{" & IF(_NPadBegin>0, REPT(_PadVal&",", _NPadBegin-1) & _PadVal&",", "") & _ArrayName & IF(_NPadEnd>0, "," & REPT(_PadVal&",", _NPadEnd-1) & _PadVal, "") &"}")

(где переменные с подчеркиванием являются именованными диапазонами для четырех входов)

Однако построить такой массив не представляется возможным. Я искал другие методы объединения одномерных массивов с использованием формулы, но ничего не нашел.

Другой подход может заключаться в создании массива окончательной желаемой длины и первоначальном заполнении его значением заполнения. Например, создайте массив A' с восемью строками, равными 0. (Я могу выполнить этот шаг в динамической формуле.) Затем вы можете перезаписать значения в этом инициализированном массиве исходным массивом, убедившись, что исходный массив сдвинут к правильное расположение. Например, перезапишите значения 0 в строках со 2 по 4 строки A' значениями A. (Я не могу понять, как сделать этот второй шаг...)

Общие сведения. У меня есть несколько одномерных массивов данных (сгенерированных с использованием динамических именованных диапазонов), которые я хотел бы отобразить вместе на одной линейной диаграмме. Однако массивы имеют разную длину, поэтому мне нужно заполнить каждый массив определенным количеством значений NA() в начале/конце массива. Их также необходимо «выстроить» на основе индекса.

Вероятно, было бы несложно добиться этого в VBA, но я бы предпочел (не определяемое пользователем) решение на основе формул.


person dnlbrky    schedule 04.12.2012    source источник


Ответы (1)


Если у вас есть значения 2, 3 и 4 в A2: A4, попробуйте эту формулу

=IF(COUNTIF(A2:A4,ROW(INDIRECT("1:"&D2))-1),ROW(INDIRECT("1:"&D2))-1,0)

где D2 содержит количество значений (8 в вашем примере).

Это вернет этот массив

{0;0;2;3;4;0;0;0}

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

ОК, согласно комментариям, вы можете сделать это с помощью этой формулы массива

=IF((ROW(INDIRECT("1:"&NPadBegin+NPadEnd+ROWS(_ArrayName)))>NPadBegin)*(ROW(INDIRECT("1:"&NPadBegin+NPadEnd+ROWS(_ArrayName)))<=ROWS(_ArrayName)+NPadBegin),N(OFFSET(_ArrayName,ROW(INDIRECT("1:"&NPadBegin+NPadEnd+ROWS(_ArrayName)))-1-NPadBegin,0,1)),PadVal)

предполагается, что _ArrayName является вертикальным одномерным массивом

person barry houdini    schedule 04.12.2012
comment
Спасибо, Барри. Насколько я понимаю ваше решение, оно предполагает, что A2: A4 (он же _ArrayName) на самом деле является индексом массива. Итак, если бы у меня был массив C, равный {99;37;42}, это решение не сработало бы. Я попытался расширить ваше решение, но застрял при попытке вставить ROW(INDIRECT("1:"&ROWS(_ArrayName)))+_NPadBegin-1, где у вас есть A2:A4 в начальном COUNTIF. Это дает мне #VALUE! ошибок. - person dnlbrky; 06.12.2012
comment
Хорошо, я, наверное, не совсем понимаю, что вы хотите. Если {99;37;42} является базовым массивом, то какой результат вы ожидаете? Я предположил, что вам понадобится массив значений, которые все равны нулю, за исключением этих трех (99,37 и 42) в правильных позициях, но это имеет смысл в моем решении, только если D2 (размер массива) равен 100 или выше. - person barry houdini; 06.12.2012
comment
Для входных данных _ArrayName = {99;37;42}, _NPadBegin = 2, _NPadEnd = 3 и PadVal = 0 я ожидаю, что на выходе будет {0;0;99;37;42;0;0;0}. - person dnlbrky; 06.12.2012
comment
Попался! как вы узнали, это непросто сделать с помощью формулы - VBA может быть проще (хотя я не могу сказать вам, как это сделать в VBA!), но я отредактировал свой ответ, чтобы показать метод формулы. - person barry houdini; 06.12.2012
comment
Похоже, обновленное решение делает именно то, что я хотел. Завтра я еще немного протестирую это, а также посмотрю, смогу ли (попытаюсь) понять, как это работает, а затем отмечу ответ. Спасибо! - person dnlbrky; 06.12.2012
comment
Да, это работает! Вот альтернативная версия, в которой вы можете указать окончательную длину массива (_NFinal), как первоначально предложил Барри, а не количество контактных площадок, которые нужно добавить в конце (_NPadEnd), что делает его немного проще: =IF((ROW(INDIRECT("1:"&_NFinal))>_NPadBegin)*(ROW(INDIRECT("1:"&_NFinal))<=ROWS(_ArrayName)+_NPadBegin),N(OFFSET(_ArrayName,ROW(INDIRECT("1:"&_NFinal))-1-_NPadBegin,0,1)),_PadVal) - person dnlbrky; 06.12.2012
comment
У меня возникают проблемы со смещением, когда _ArrayName содержит такую ​​функцию, как TREND. Я разместил это отдельно в другом вопросе. [ссылка]stackoverflow.com/questions/13770919/ - person dnlbrky; 08.12.2012