Excel динамически рассчитывает стоимость продуктов на основе спецификации материалов (BOM) и истории закупочных цен

РЕДАКТИРОВАТЬ 1 → 30 марта 2024 г.:

  • Включены параметры в лямбда-функции, поэтому имена таблиц и столбцов могут быть введены пользователем.
  • Обновлены лямбда-функции с такими параметрами.
  • Несмотря на то, что я нашел решение, я протестировал всю программу, и она действительно требует больших ресурсов и памяти.

Должен быть способ оптимизировать/упростить его.



Цель:

Рассчитать себестоимость продукции за диапазон дат на основе спецификации материалов и истории закупочных цен каждого материала (компонента).


Процесс:

Получите компоненты и количества продуктов до уровня покупки, а затем умножьте их на цену покупки каждый месяц.

Источник данных

TableBOM содержит набор компонентов, необходимых для каждого продукта (Q = количество).

Компонент 1 1 квартал Компонент 2 2 квартал Результат Папель 1 1 Тарьета личный 20 Тарьета x20 Папель 2 2 Таржетон 40 Таржетон x40 Каха пе 4 Эмпаке пекеньо Синта пе 5 Эмпаке пекеньо Сепарадор пе 6 Эмпаке пекеньо Тарьета x20 1 Эмпаке пекеньо 1 Tarjeta empaque pe Таржетон x40 1 Эмпаке Гранде 1 Тарьетон эмпак гр. Каха гр 7 Эмпаке Гранде Синта гр 8 Эмпаке Гранде Нота 1 Эмпаке пекеньо 1 Nota empaque pe Тарьета x20 1 Эмпаке Гранде 1 Tarjeta empaque гр. Тарьетон эмпак гр. 1 Nota empaque pe 2 Таржетон + нота Папель 3 3 Таржетон Диви гр 9 Эмпаке Гранде Собре 4 1 Нота Сола 1 Нота

TablePurchaseComponent содержит исторические цены на каждый материал (компонент).

Феча Компонент Унитарная цена 01.01.2023 Каха гр 100 01.01.2023 Каха пе 110 01.01.2023 Синта гр 120 01.01.2023 Синта пе 130 01.01.2023 Диви гр 140 01.01.2023 Нота Сола 150 01.01.2023 Папель 1 10 01.01.2023 Папель 2 20 01.01.2023 Папель 3 30 01.01.2023 Сепарадор пе 190 01.01.2023 Собре 4 200 01.01.2023 Тарьета личный 2 01.01.2024 Каха гр 200 01.01.2024 Каха пе 220 01.01.2024 Синта гр 240 01.01.2024 Синта пе 260 01.01.2024 Диви гр 280 01.01.2024 Нота Сола 300 01.01.2024 Папель 1 20 01.01.2024 Папель 2 40 01.01.2024 Папель 3 60 01.01.2024 Сепарадор пе 380 01.01.2024 Собре 4 400 01.01.2024 Тарьета личный 4

Таблицы в листе:


Лямбда-функции (как определенные имена):

fxProcessVal:

Параметры → lookup_val;component1_cols;component2_cols;result_col

Код:

=LET(
    comp_res; VSTACK(
        FILTER(component1_cols; result_col = lookup_val);
        FILTER(component2_cols; result_col = lookup_val)
    );
    comp_res_fil; FILTER(comp_res; CHOOSECOLS(comp_res; 2) <> "");
    lookup_col; IFNA(EXPAND(lookup_val; ROWS(comp_res_fil)); lookup_val);
    IFERROR(HSTACK(lookup_col; comp_res_fil); "")
)

fxProcessCompRow:

Параметры → data;lookup_row;component1_cols;component2_cols;result_col

Код:

=LET(
    sourceData; fxProcessVal(
        INDEX(data; lookup_row; 2);
        component1_cols;
        component2_cols;
        result_col
    );
    res_val; INDEX(data; 1; 1);
    res_col; IFNA(EXPAND(res_val; ROWS(sourceData)); res_val);
    sourceRes; HSTACK(res_col; DROP(sourceData; 0; 1));
    IF(
        sourceData <> "";
        FILTER(sourceRes; CHOOSECOLS(sourceRes; 2) <> "");
        CHOOSEROWS(data; lookup_row)
    )
)

fxProcessComp:

Параметры → source;component1_cols;component2_cols;result_col

Код:

=LET(
    seq; SEQUENCE(ROWS(source));
    reducer; REDUCE(
        "";
        seq;
        LAMBDA(acc; curr;
            VSTACK(
                acc;
                IFNA(
                    fxProcessCompRow(source; curr; component1_cols; component2_cols; result_col);
                    HSTACK(""; ""; "")
                )
            )
        )
    );
    temp_res; DROP(reducer; 1);
    temp_res
)

fxCompCost:

Параметры → component1_cols;component2_cols;result_col

Код:

=IFNA(
    INDEX(
        unitprice_col;
        MATCH(
            MAXIFS(purchasedate_col; purchasedate_col; "< = " & date; purchasecomponent_col; comp) &
                comp;
            purchasedate_col & purchasecomponent_col;
            0
        )
    );
    0
)

прокси:

Параметры → seed;component1_cols;component2_cols;result_col

Код:

=LET(
    res; IF(
        COUNTA(seed) = 1;
        fxProcessVal(seed; component1_cols; component2_cols; result_col);
        fxProcessComp(seed; component1_cols; component2_cols; result_col)
    );
    comp; CONCAT(seed) = CONCAT(res);
    IF(comp; seed; prox(res; component1_cols; component2_cols; result_col))
)

Ссылка:

Формулы

Формула для развертывания списка спецификации (и дезагрегирования каждого материала и необходимого количества продукта):

=UNIQUE(DROP(REDUCE("";TableBOM[Resultado];LAMBDA(acc;curr;VSTACK(acc;prox(curr;TableBOM[[Componente 1]:[Q1]];TableBOM[[Componente 2]:[Q2]];TableBOM[Resultado]))));1))

Даты расчета стоимости каждого продукта динамически устанавливаются в диапазоне с использованием следующей формулы:

=DATE(YEAR(Q1);SEQUENCE(1;DATEDIF(Q1;Q2;"M")+1;MONTH(Q1);1);1)

ЗАСТРАИВАЕТСЯ ЗДЕСЬ:

Я хотел бы установить Q3 (диапазон дат в виде разлитого диапазона) и рассчитать стоимость каждого продукта в каждом месяце.

В настоящее время СУММПРОИЗВ вычисляет итоговую сумму за все месяцы (даты в диапазоне).

Я пробовал BYCOL и комбинацию MAP и Sequence, но так и не понял.

Любая помощь, я был бы признателен.

Ссылка на файл примера, доступный только для чтения (без макросов)

=LET(
     data;L4#;
     date;Q3#;
     res;INDEX(data;;1);
     comp;INDEX(data;;2);
     q;INDEX(data;;3);
     lab;UNIQUE(res);
     cost;q*fxCompCost(comp;date);
     rt;MAP(lab;LAMBDA(a; SUMPRODUCT((res=a)*cost)));
     temp;HSTACK(lab;rt);
temp
)

Желаемый результат:

Вы действительно хотите единую формулу для P22:AN33?

VBasic2008 30.03.2024 18:56

Точно. Для вывода меток и затрат за каждый месяц.

Ricardo Diaz 30.03.2024 18:58

Плюсом было бы также ввести диапазон дат в качестве переменных в формуле.

Ricardo Diaz 30.03.2024 19:10

Попробуйте использовать MAKEARRAY(), это, насколько я вижу, будет решением.

Mayukh Bhattacharya 31.03.2024 00:01

Сделаю. Спасибо, Маюх

Ricardo Diaz 31.03.2024 00:54
Преобразование HTML-таблицы в профессиональный документ Excel
Преобразование HTML-таблицы в профессиональный документ Excel
Это самый простой способ создания Excel из HTML-таблицы.
Импорт excel в laravel в базу данных
Импорт excel в laravel в базу данных
Здравствуйте, дорогой читатель, в этой статье я расскажу практическим и быстрым способом, как импортировать файл Excel в вашу базу данных с помощью...
1
5
83
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я использовал комбинацию REDUCE и SEQUENCE для перебора каждого столбца даты.

=LET(
     data;L4#;
     dateRow;DATE(YEAR(ParamStartDate);SEQUENCE(1;DATEDIF(ParamStartDate;ParamEndDate;"M")+1;MONTH(ParamStartDate);1);1);
     headers;HSTACK("";dateRow);
     date;dateRow;
     res;INDEX(data;;1);
     comp;INDEX(data;;2);
     q;INDEX(data;;3);
     lab;UNIQUE(res);
     cost;q*fxCompCost(comp;date);
     reducer;REDUCE("";SEQUENCE(COLUMNS(date));LAMBDA(acc;curr;HSTACK(acc;MAP(lab;LAMBDA(a; SUMPRODUCT((res=a)*CHOOSECOLS(cost;curr)))))));
     result;VSTACK(headers;HSTACK(lab;DROP(reducer;;1)));
     result
)

Имена, добавленные в рабочий лист:

ПарамСтартДата: Q2 ПарамЭндДата: Q3

Финал:

Если кто-то предложит лучшее решение даже для обработки спецификации, опубликуйте его.

Надеюсь, это поможет кому-то еще.

Другие вопросы по теме

Похожие вопросы

Как я могу просмотреть несколько листов Excel с именами листов, расположенными в диапазоне?
Вставка пустых строк и объединение ячеек в Excel с использованием Interop Excel C#
Помогите, пожалуйста, с суммой для нескольких отдельных строк с использованием нескольких критериев
Попытка придать цвет заголовкам полей столбцов в сводной таблице с помощью vba
Как импортировать диапазон в массив вариантов в Excel VBA и отсортировать его с помощью метода сортировки?
Сопоставление Индекса Excel+ Возвращает повторяющееся значение
Сценарий VBA для чтения значений с одного листа и записи на другой (проблема с заданным диапазоном)
Запрашивает формулу Excel для сравнения столбцов, но идет по порядку и пропускает пробелы
Повторите значение для каждого экземпляра другого значения в Excel без использования Power Query
Отобразить имя файла изображения в ячейке изображения