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