Почему при проведении документа возникает ошибка «Запись не уникальна» с указанием на вторую строку?

Программист 1С v8.3 (Управляемые формы) 1С:Управление торговлей Управленческий учет Торговля и дистрибуция
← На главную

Понимание природы ошибки

В процессе разработки или доработки конфигураций 1С мы часто сталкиваемся с ошибкой вида «Запись не уникальна» при попытке провести документ. При этом сообщение об ошибке часто содержит уточнение, например: «строка 2» или «строка 5», хотя визуально в документе может быть всего одна строка или строки кажутся уникальными.

Разберемся, что именно происходит в платформе в этот момент. Когда мы проводим документ, система формирует движения по регистрам. В случае с регистрами сведений (например, «Цены номенклатуры» или «Штрихкоды»), уникальность записи определяется совокупностью его Измерений и Периода (для периодических регистров).

Сообщение о номере строки относится не к номеру строки в табличной части вашего документа, а к номеру записи в Наборе записей (RecordSet), который платформа пытается записать в базу данных.

Почему именно «строка 2»?

Давайте проанализируем механику возникновения ошибки. Представим, что в табличной части документа пользователь (или алгоритм загрузки) указал одну и ту же номенклатуру дважды.

  1. Алгоритм проведения перебирает строки документа.
  2. Формируется первая запись для регистра сведений (например, Товар: "Тефтельки", Цена: 100). Она помещается в коллекцию движений под индексом 0 (условно первая строка).
  3. Затем алгоритм обрабатывает следующую строку документа, где снова встречаются "Тефтельки". Формируется вторая запись с теми же ключевыми полями. Она помещается в коллекцию под индексом 1 (вторая строка).
  4. При попытке записать этот набор в базу данных, SQL-сервер или файловая СУБД проверяют уникальность индексов.
  5. Первая запись проходит проверку успешно.
  6. Вторая запись конфликтует с первой, так как их ключевые поля идентичны. Система выдает ошибку, указывая, что проблема возникла на второй записи в пакете.

Основные причины появления дублей

Рассмотрим наиболее частые сценарии, приводящие к такой ситуации:

1. Дубли в табличной части документа
Пользователь случайно добавил один и тот же товар двумя строками. Если логика проведения просто переносит строки в регистр без группировки, возникнет ошибка.

2. Незаполненные измерения
В регистре может быть несколько измерений, например, Номенклатура и Характеристика. Если в документе есть две строки с одной номенклатурой, но разными характеристиками, а в коде проведения мы забыли заполнить измерение Характеристика, то для регистра эти записи станут абсолютно одинаковыми (обе будут иметь пустую характеристику).

3. Программная генерация данных
Ошибки в циклах или неправильное соединение таблиц в запросе при проведении могут порождать дублирующие строки данных.

Решение проблемы: Свертка таблицы

Чтобы гарантированно избежать ошибки неуникальности при проведении, мы должны обрабатывать данные перед формированием движений. Самый надежный метод — это использование метода Свернуть таблицы значений или группировка в запросе.

Рассмотрим пример правильного алгоритма действий:

  1. Выгружаем табличную часть документа в Таблицу Значений или получаем данные запросом.
  2. Сворачиваем данные по ключевым полям (измерениям регистра).
  3. Формируем движения на основании уже свернутой (уникальной) таблицы.

Пример кода, который поможет устранить дубли перед записью:


// Получаем таблицу данных из табличной части
ТаблицаДвижений = ТаблицаТоваров.Выгрузить();

// Сворачиваем таблицу по полям, которые пойдут в Измерения регистра
// Ресурсы (например, Количество) суммируем, хотя для цен это может быть неактуально
ТаблицаДвижений.Свернуть("Номенклатура, Характеристика, Серия", "Цена");

// Теперь обходим уникальные строки и формируем движения
Для Каждого СтрокаТЗ Из ТаблицаДвижений Цикл
    Движение = Движения.ЦеныНоменклатуры.Добавить();
    Движение.Период = Дата;
    Движение.Номенклатура = СтрокаТЗ.Номенклатура;
    Движение.Характеристика = СтрокаТЗ.Характеристика;
    Движение.Цена = СтрокаТЗ.Цена;
КонецЦикла;

Диагностика и отладка

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

  1. Откройте модуль объекта документа.
  2. Найдите процедуру ОбработкаПроведения.
  3. Найдите конец процедуры или строку, где происходит запись движений (если она явная).
  4. Поставьте точку останова.
  5. Запустите проведение документа в режиме отладки.
  6. Когда выполнение остановится, откройте Вычислить выражение (Shift+F9) и посмотрите содержимое коллекции Движения.ИмяВашегоРегистра.

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

← На главную