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