Как правильно суммировать количество при обнаружении дублей в табличной части 1С?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При разработке конфигураций на платформе 1С часто возникает задача: не допускать дублирования строк в табличной части, а при попытке добавить уже существующий товар — просто увеличивать количество в уже имеющейся строке. Если вы столкнулись с тем, что стандартная функция Свернуть() вам не подходит из-за наличия дополнительных уникальных колонок, давайте разберем, как решить эту задачу профессионально и эффективно.

Решение 1: Интерактивная проверка в момент добавления

Самый правильный подход — не допускать появления дублей в момент взаимодействия пользователя с табличной частью. Вместо того чтобы исправлять ошибки «задним числом» в процедуре ПередЗаписью(), мы будем проверять наличие строки прямо в момент подбора или ввода номенклатуры.

Для поиска строки по одному или нескольким критериям используем методы Найти() или НайтиСтроки(). Рассмотрим на примере, как это реализовать:


// Предположим, у нас есть ТоварИзПодбора и КоличествоИзПодбора
СтруктураПоиска = Новый Структура("Продукт", ТоварИзПодбора);
НайденныеСтроки = Объект.Состав.НайтиСтроки(СтруктураПоиска);

Если НайденныеСтроки.Количество() > 0 Тогда
    // Если строка найдена, суммируем количество в первой же найденной
    Строка = НайденныеСтроки[0];
    Строка.Количество = Строка.Количество + КоличествоИзПодбора;
Иначе
    // Если не найдена, добавляем новую строку
    НоваяСтрока = Объект.Состав.Добавить();
    НоваяСтрока.Продукт = ТоварИзПодбора;
    НоваяСтрока.Количество = КоличествоИзПодбора;
КонецЕсли;

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

Решение 2: Обработка существующих дублей (алгоритм свертки)

Если данные уже накоплены и их нужно привести в порядок, или вы работаете с загрузкой из внешних файлов, где дубли могут возникнуть массово, используем алгоритм с временной таблицей. Основная сложность — сохранить данные в «важных» неключевых колонках. Мы сделаем это через метод выгрузки и обратного поиска.

Разберем алгоритм по шагам:

  1. Выгружаем табличную часть в ТаблицаЗначений.
  2. Сворачиваем ТаблицаЗначений по ключевым полям (например, по номенклатуре), суммируя количество.
  3. Проходим по свернутой таблице и ищем соответствующие строки в исходной табличной части объекта.
  4. Обновляем количество в найденных строках и помечаем лишние строки к удалению.

// Колонки, по которым мы группируем товары
КолонкиГруппировок = "Продукт";
ТЗ = Объект.Состав.Выгрузить();
ТЗ.Свернуть(КолонкиГруппировок, "Количество");

// Очищаем текущую ТЧ, чтобы заполнить ее заново корректными данными
Объект.Состав.Очистить();

Для Каждого Запись Из ТЗ Цикл
    НоваяСтрока = Объект.Состав.Добавить();
    ЗаполнитьЗначенияСвойств(НоваяСтрока, Запись);
КонецЦикла;

Важное примечание: Если вам необходимо сохранить уникальные значения в других колонках (например, индивидуальные комментарии к каждой строке), свертка по всем полям не сработает. В таком случае необходимо использовать Запрос к табличной части объекта. Запрос позволяет сгруппировать данные по выбранным полям и просуммировать количество, оставив остальные данные за пределами группировки или выбрав их через МАКСИМУМ() или СУММА().

Почему не стоит удалять строки циклом "Для Каждого"

При написании собственного кода будьте осторожны: удаление строк из коллекции во время обхода этой же коллекции через цикл Для Каждого приводит к «съезжанию» индексов. Это часто становится причиной того, что часть строк просто не проверяется алгоритмом. Если вам все же нужно удалить строки, используйте обратный цикл:


// Удаление строк с конца таблицы
Для Индекс = Объект.Состав.Количество() - 1 По 0 Шаг -1 Цикл
    Строка = Объект.Состав[Индекс];
    Если УсловиеДляУдаления(Строка) Тогда
        Объект.Состав.Удалить(Индекс);
    КонецЕсли;
КонецЦикла;

Мы рекомендуем всегда отдавать предпочтение методам поиска НайтиСтроки() в связке с объектом Структура, так как это наиболее лаконичный и быстрый способ работы с табличными частями в 1С. Удачи в оптимизации ваших алгоритмов!

← На главную