При разработке конфигураций на платформе 1С часто возникает задача: не допускать дублирования строк в табличной части, а при попытке добавить уже существующий товар — просто увеличивать количество в уже имеющейся строке. Если вы столкнулись с тем, что стандартная функция Свернуть() вам не подходит из-за наличия дополнительных уникальных колонок, давайте разберем, как решить эту задачу профессионально и эффективно.
Самый правильный подход — не допускать появления дублей в момент взаимодействия пользователя с табличной частью. Вместо того чтобы исправлять ошибки «задним числом» в процедуре ПередЗаписью(), мы будем проверять наличие строки прямо в момент подбора или ввода номенклатуры.
Для поиска строки по одному или нескольким критериям используем методы Найти() или НайтиСтроки(). Рассмотрим на примере, как это реализовать:
// Предположим, у нас есть ТоварИзПодбора и КоличествоИзПодбора
СтруктураПоиска = Новый Структура("Продукт", ТоварИзПодбора);
НайденныеСтроки = Объект.Состав.НайтиСтроки(СтруктураПоиска);
Если НайденныеСтроки.Количество() > 0 Тогда
// Если строка найдена, суммируем количество в первой же найденной
Строка = НайденныеСтроки[0];
Строка.Количество = Строка.Количество + КоличествоИзПодбора;
Иначе
// Если не найдена, добавляем новую строку
НоваяСтрока = Объект.Состав.Добавить();
НоваяСтрока.Продукт = ТоварИзПодбора;
НоваяСтрока.Количество = КоличествоИзПодбора;
КонецЕсли;
Этот метод исключает появление лишних строк на этапе ввода, что делает работу пользователя более предсказуемой, а данные — чистыми.
Если данные уже накоплены и их нужно привести в порядок, или вы работаете с загрузкой из внешних файлов, где дубли могут возникнуть массово, используем алгоритм с временной таблицей. Основная сложность — сохранить данные в «важных» неключевых колонках. Мы сделаем это через метод выгрузки и обратного поиска.
Разберем алгоритм по шагам:
ТаблицаЗначений.ТаблицаЗначений по ключевым полям (например, по номенклатуре), суммируя количество.
// Колонки, по которым мы группируем товары
КолонкиГруппировок = "Продукт";
ТЗ = Объект.Состав.Выгрузить();
ТЗ.Свернуть(КолонкиГруппировок, "Количество");
// Очищаем текущую ТЧ, чтобы заполнить ее заново корректными данными
Объект.Состав.Очистить();
Для Каждого Запись Из ТЗ Цикл
НоваяСтрока = Объект.Состав.Добавить();
ЗаполнитьЗначенияСвойств(НоваяСтрока, Запись);
КонецЦикла;
Важное примечание: Если вам необходимо сохранить уникальные значения в других колонках (например, индивидуальные комментарии к каждой строке), свертка по всем полям не сработает. В таком случае необходимо использовать Запрос к табличной части объекта. Запрос позволяет сгруппировать данные по выбранным полям и просуммировать количество, оставив остальные данные за пределами группировки или выбрав их через МАКСИМУМ() или СУММА().
При написании собственного кода будьте осторожны: удаление строк из коллекции во время обхода этой же коллекции через цикл Для Каждого приводит к «съезжанию» индексов. Это часто становится причиной того, что часть строк просто не проверяется алгоритмом. Если вам все же нужно удалить строки, используйте обратный цикл:
// Удаление строк с конца таблицы
Для Индекс = Объект.Состав.Количество() - 1 По 0 Шаг -1 Цикл
Строка = Объект.Состав[Индекс];
Если УсловиеДляУдаления(Строка) Тогда
Объект.Состав.Удалить(Индекс);
КонецЕсли;
КонецЦикла;
Мы рекомендуем всегда отдавать предпочтение методам поиска НайтиСтроки() в связке с объектом Структура, так как это наиболее лаконичный и быстрый способ работы с табличными частями в 1С. Удачи в оптимизации ваших алгоритмов!