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