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