RE: Как программно вычесть две таблицы значений по ключам в 1С?

#33470
bot_avaOdin — Одинэсник
Участник

    Функционально задача сводится к вычислению разности двух таблиц значений по ключу (Организация, Подразделение), при этом учитывается Количество, и в итоговой таблице должны остаться только те строки, которые есть в одной из таблиц, но отсутствуют в другой (сравнение по Организация + Подразделение).

    Для решения можно использовать алгоритм с объединением таблиц и сверткой с подсчетом разницы, как в классическом способе сравнения таблиц значений.

    Пример кода на 1С:

    1C
    Функция ПолучитьРазностьТаблиц(Таблица1, Таблица2) Экспорт
        // Ключевые колонки для сравнения
        Ключи = "Организация,Подразделение";
        ИмяКолонкиСверки = "__Сверка__";
    
        // Копируем Таблицу1, добавляем колонку для сверки и заполняем -1
        ТаблРезультат = Таблица1.Скопировать();
        Если Не ТаблРезультат.Колонки.Найти(ИмяКолонкиСверки) Тогда
            ТаблРезультат.Колонки.Добавить(ИмяКолонкиСверки, Новый ОписаниеТипов("Число"));
        КонецЕсли;
        ТаблРезультат.ЗаполнитьЗначения(-1, ИмяКолонкиСверки);
    
        // Добавляем строки из Таблица2 с +1 в колонке сверки
        Для Каждого Строка Из Таблица2 Цикл
            НоваяСтрока = ТаблРезультат.Добавить();
            ЗаполнитьЗначенияСвойств(НоваяСтрока, Строка);
            НоваяСтрока[ИмяКолонкиСверки] = 1;
        КонецЦикла;
    
        // Свертываем таблицу по ключам, суммируя колонку сверки и Количество
        // Для Количество нужно суммирование, для ключей группировка
        ТаблРезультат.Свернуть(Ключи, "Количество," + ИмяКолонкиСверки);
    
        // Оставляем только строки, где сумма сверки не равна 0 (т.е. уникальные)
        ИтоговаяТаблица = Новый ТаблицаЗначений;
        // Добавляем колонки из исходных таблиц (Организация, Подразделение, Количество)
        Для Каждого Колонка Из ТаблРезультат.Колонки Цикл
            Если Колонка.Имя  ИмяКолонкиСверки Тогда
                ИтоговаяТаблица.Колонки.Добавить(Колонка.Имя, Колонка.Тип);
            КонецЕсли;
        КонецЦикла;
    
        Для Каждого Строка Из ТаблРезультат Цикл
            Если Строка[ИмяКолонкиСверки]  0 Тогда
                НоваяСтрока = ИтоговаяТаблица.Добавить();
                Для Каждого Колонка Из ИтоговаяТаблица.Колонки Цикл
                    НоваяСтрока[Колонка.Имя] = Строка[Колонка.Имя];
                КонецЦикла;
            КонецЕсли;
        КонецЦикла;
    
        Возврат ИтоговаяТаблица;
    КонецФункции
    

    Объяснение:

    — В колонке `__Сверка__` для строк из первой таблицы ставим -1, для второй +1.
    — Объединяем обе таблицы.
    — Свертываем по ключам (Организация, Подразделение), суммируя Количество и колонку сверки.
    — Если сумма в колонке сверки равна 0 — значит строки с таким ключом есть в обеих таблицах, их исключаем.
    — В итоговую таблицу попадают только уникальные строки с разницей по ключам.

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

    Рекомендую посмотреть здесь: https://infostart.ru/1c/articles/375490/

    База знаний 1С