СУММПРОИЗВЕД(массивы, разные листы и длина)

Вопрос или проблема

Я испытываю трудности с функцией СУММПРОИЗВ. У меня есть две таблицы, одна из которых представляет собой физических лиц, а другая — проекции на определённый период времени.

Для каждой строки в таблице 1 мне нужно посчитать произведение суммы столбцов “фактор”, “вес”, “снижение” и “скидка” (где состояние = состояние, пол = пол и возраст между возрастом и максимальным возрастом) и из таблицы 2 столбцы “ставка” и “количество” (где возраст в таблице 2 = возраст в таблице 1 и время в таблице 2 <= максимальный возраст + 1 в таблице 1).

По сути, я хочу
=СУММПРОИЗВ(($C$2:$C$2801>=C2)*($C$2:$C$2801<=H2)*($A$2:$A$2801=A2)*($B$2:$B$2801=B2)*($D$2:$D$2801)*($E$2:$E$2801)*($F$2:$F$2801)*($G$2:$G$2801),(Лист2!$B$2:$B$5051=$C2)*(Лист2!$A$2:$A$5051<=$H2+1)*(Лист2!$C$2:$C$5051)*(Лист2!$D$2:$D$5051))

Но это не сработает, так как массивы разной длины, даже если после обработки условий “если” массивы фактически одинаковой длины. Мне удалось найти способ, чтобы достичь решения, но поскольку множители (значения в других столбцах) контролируются другими выборами, когда нужно выполнить расчет, это в основном бесполезно (даже с всего ~50 тыс. строк).

Вот два способа, которыми я смог это сделать (по сути, это одно и то же):

=СУММПРОИЗВ(ФИЛЬТР(ФИЛЬТР($A$2:$H$2801,($C$2:$C$2801>=C2)*($C$2:$C$2801<=H2)*($A$2:$A$2801=A2)*($B$2:$B$2801=B2),""),($A$1:$H$1="фактор"),""),ФИЛЬТР(ФИЛЬТР($A$2:$H$2801,($C$2:$C$2801>=C2)*($C$2:$C$2801<=H2)*($A$2:$A$2801=A2)*($B$2:$B$2801=B2),""),($A$1:$H$1="вес"),""),ФИЛЬТР(ФИЛЬТР($A$2:$H$2801,($C$2:$C$2801>=C2)*($C$2:$C$2801<=H2)*($A$2:$A$2801=A2)*($B$2:$B$2801=B2),""),($A$1:$H$1="снижение"),""),ФИЛЬТР(ФИЛЬТР($A$2:$H$2801,($C$2:$C$2801>=C2)*($C$2:$C$2801<=H2)*($A$2:$A$2801=A2)*($B$2:$B$2801=B2),""),($A$1:$H$1="скидка"),""),ФИЛЬТР(ФИЛЬТР(Лист2!$A$2:$D$5051,((Лист2!$B$2:$B$5051=$C2)*(Лист2!$A$2:$A$5051<=$H2+1)),""),(Лист2!$A$1:$D$1="ставка"),""),ФИЛЬТР(ФИЛЬТР(Лист2!$A$2:$D$5051,((Лист2!$B$2:$B$5051=$C2)*(Лист2!$A$2:$A$5051<=$H2+1)),""),(Лист2!$A$1:$D$1="количество"),""))

Или с помощью LET(

=LET(Array1,ФИЛЬТР($A$2:$H$2801,(($C$2:$C$2801>=$C2)*($C$2:$C$2801<=$H2)*($B$2:$B$2801=$B2)*($A$2:$A$2801=$A2)),""),Array1A,ФИЛЬТР(Array1,($A$1:$H$1="фактор"),""),Array1B,ФИЛЬТР(Array1,($A$1:$H$1="вес"),""),Array1C,ФИЛЬТР(Array1,($A$1:$H$1="снижение"),""),Array1D,ФИЛЬТР(Array1,($A$1:$H$1="скидка"),""),Array2,ФИЛЬТР(Лист2!$A$2:$D$5051,((Лист2!$B$2:$B$5051=$C2)*(Лист2!$A$2:$A$5051<=$H2+1)),""),Array2A,ФИЛЬТР(Array2,(Лист2!$A$1:$D$1="ставка"),""),Array2B,ФИЛЬТР(Array2,(Лист2!$A$1:$D$1="количество"),""),СУММПРОИЗВ(Array1A,Array1B,Array1C,Array1D,Array2A,Array2B))

Исходная книга полагалась на огромное количество функций ССЫЛКА и НЕКТорг, что делало её такой медленной, что было невозможно использовать, поэтому меня попросили найти лучший способ. Они хотят это без использования VBA, хотя я начинаю думать, что этого не избежать. Единственная другая идея, которую я имею, — это множество дополнительных столбцов.


Данные в текстовом формате:
Таблица 1:


состояние пол возраст фактор вес снижение скидка максимальный возраст
1 M 0 0.7957 0.4980 0.9170 0.4596 49

Таблица 2:


время возраст ставка количество
1 0 0.9186 592.6036

В основном для заданного возраста/состояния/пола создается значение суммы произведения для следующих 50 лет возраста и каждого значения времени, соответствующего начальному возрасту (и соответствующему следующему возрасту). Таким образом, первое наблюдение дает эти 50 строк, которые затем образуют столбец произведений. Сумма этого произведения (сумма произведений) = 564.7810.

Таблица 3:


фактор вес снижение скидка ставка количество произведение
0.7957 0.4980 0.9170 0.4596 0.9186 592.6036 90.9004

К сожалению, я только что осознал, что это не работает, как только я перейду за пределы 50 лет (вероятно, из-за размеров массивов), но это всё равно выводит всё правильно до этого момента. В общем, я в замешательстве.

Ответ или решение

Чтобы решить проблему с использованием функции SUMPRODUCT для работы с массивами из разных листов в Excel, нужно учитывать несколько важных аспектов, особенно когда длины массивов различаются. Давайте разберем это подробнее.

Проблема

У вас есть две таблицы: первая таблица (Table1) содержит данные о физических лицах и включает такие поля, как "state", "sex", "age", "factor", "weight", "reduction", "discount" и "maxage". Вторая таблица (Table2) содержит проекции по времени и включает поля, такие как "time", "age", "rate" и "count". Задача заключается в том, чтобы для каждой строки в первой таблице вычислить сумму произведений значений столбцов из обеих таблиц на основании определенных условий, связанных со значениями возраста, пола и штата.

Условия

  1. Возраст из таблицы 1 должен быть в диапазоне от "age" до "maxage".
  2. Пол и штат должны совпадать.
  3. Возраст во второй таблице должен соответствовать значению из первой таблицы, а время должно быть меньше или равно "maxage + 1".

Решение

  1. Использование FILTER: Одним из подходов для получения значений, которые соответствуют условиям, является использование функции FILTER, которая позволяет фильтровать массивы по заданным критериям, тем самым избегая ошибки различия в длине массивов.

  2. Оптимизация с использованием LET: Функция LET позволяет создавать переменные для обеспечения более ясного, читаемого и производительного кода.

Вот как может выглядеть решение вашей задачи:

=LET(
    // Данные из первой таблицы (Таблица 1)
    tb1_data, A2:H2801,
    filter_tb1, FILTER(tb1_data, 
                 (INDEX(tb1_data,,3) >= C2) * (INDEX(tb1_data,,3) <= H2) * 
                 (INDEX(tb1_data,,1) = A2) * (INDEX(tb1_data,,2) = B2)),

    // Данные из второй таблицы (Таблица 2)
    tb2_data, Sheet2!A2:D5051,
    filter_tb2, FILTER(tb2_data, 
                 (INDEX(tb2_data,,2) = C2) * 
                 (INDEX(tb2_data,,1) <= H2 + 1)),

    // Получение значений factor, weight, reduction, discount
    factor, INDEX(filter_tb1, , 4),
    weight, INDEX(filter_tb1, , 5),
    reduction, INDEX(filter_tb1, , 6),
    discount, INDEX(filter_tb1, , 7),

    // Получение значений rate и count
    rate, INDEX(filter_tb2, , 3),
    count, INDEX(filter_tb2, , 4),

    // Вычисление результата
    SUMPRODUCT(factor * weight * reduction * discount * rate * count)
)

Объяснение

  • Фильтрация данных: В функции LET, содержимое обеих таблиц фильтруется на основании заданных условий.
  • Выбор столбцов: После фильтрации мы используем функции INDEX, чтобы выбрать нужные столбцы (factor, weight и т. д.).
  • Вычисление результата: Мы применяем SUMPRODUCT для всех отфильтрованных значений, чтобы получить итог.

Заключение

Использование FILTER в сочетании с LET оснащает вашу формулу необходимыми гибкостью и мощью, предотвращая проблемы с различием в длине массивов. Надеюсь, это поможет вам эффективно решить вашу задачу с проекциями и суммами в Excel без использования VBA.

Оцените материал
Добавить комментарий

Капча загружается...