Как исправить ошибку при удалении записи из регистра сведений «Соответствия объектов информационных баз»?

Программист 1С v8.3 (Управляемые формы) 1C:Бухгалтерия IT и автоматизация бизнеса
← На главную

При администрировании и разработке в системах 1С:Предприятие, особенно при настройке синхронизации данных между конфигурациями (например, «Бухгалтерия предприятия» и «Зарплата и управление персоналом»), специалисты часто сталкиваются с необходимостью ручной корректировки или удаления записей в служебных регистрах. Одним из ключевых регистров, обеспечивающих сопоставление объектов в разных базах, является СоответствияОбъектовИнформационныхБаз.

Попытка напрямую удалить некорректную строку через стандартный интерфейс «Все функции» («Функции для технического специалиста») или с помощью простого кода часто оборачивается неприятными ошибками. В этой статье мы подробно разберем две взаимосвязанные проблемы, возникающие при попытке очистить или изменить записи в этом регистре, выясним причины их появления и найдем элегантные пути их решения.

Проблема №1: Ошибка «Недопустимое значение параметра (параметр номер '1')» при удалении записи

Рассмотрим ситуацию: пользователь открывает регистр сведений, находит ошибочную запись, нажимает кнопку «Удалить» и сталкивается со следующим системным сообщением:


Ошибка при выполнении обработчика - 'ПередЗаписью'
по причине:
{РегистрСведений.СоответствияОбъектовИнформационныхБаз.МодульНабораЗаписей(32)}: Ошибка при вызове метода контекста (Добавить)
    ОбменДанными.Получатели.Добавить(Отбор.УзелИнформационнойБазы.Значение);
по причине:
Недопустимое значение параметра (параметр номер '1')

Проанализируем, почему это происходит. В модуле набора записей регистра СоответствияОбъектовИнформационныхБаз в обработчике события ПередЗаписью прописана бизнес-логика автоматической регистрации изменений. Система пытается добавить узел обмена, указанный в измерении УзелИнформационнойБазы, в список получателей для выгрузки изменений.

Однако, если в этом измерении по ошибке оказался указан узел, соответствующий текущей информационной базе (так называемый «Этот узел»), платформа 1С выдает ошибку. Согласно архитектуре планов обмена, информационная база не может регистрировать изменения для самой себя. Передача ссылки на предопределенный элемент «Этот узел» в метод ОбменДанными.Получатели.Добавить() категорически запрещена на уровне платформы.

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

Проблема №2: Ошибка «Поле объекта не обнаружено (ОбменДанными)» при программном удалении

Пытаясь обойти первую ошибку программно, разработчики логично решают использовать стандартный механизм платформы — отключение обработчиков событий через признак загрузки данных. Для этого пишется следующий код:


ЗаписьРС = РегистрыСведений.СоответствияОбъектовИнформационныхБаз.СоздатьМенеджерЗаписи();
// Заполнение ключевых полей ...
ЗаписьРС.ОбменДанными.Загрузка = Истина;
ЗаписьРС.Прочитать();
Если ЗаписьРС.Выбран() Тогда
    ЗаписьРС.Удалить();
КонецЕсли;

При выполнении этого кода система выбрасывает новое исключение: Поле объекта не обнаружено (ОбменДанными). Выясним причину этой ошибки.

В платформе 1С:Предприятие объект типа РегистрСведенийМенеджерЗаписи является упрощенной моделью для работы с единичной строкой регистра. Архитектурно этот объект не имеет свойства ОбменДанными. Данное свойство доступно исключительно у объектов типа РегистрСведенийНаборЗаписей. Платформа спроектирована так, что управление транзакционными механизмами и отключение триггеров (обработчиков событий модуля) возможно только при работе с коллекциями данных — наборами записей.

Решение: Как правильно и безопасно удалить проблемную запись?

Для успешного удаления ошибочной записи в обход стандартных обработчиков событий нам необходимо использовать объект РегистрСведенийНаборЗаписей с обязательной установкой флага ОбменДанными.Загрузка = Истина. Разберем по шагам, как это реализовать.

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


// Шаг 1. Создаем объект набора записей регистра
НаборЗаписей = РегистрыСведений.СоответствияОбъектовИнформационныхБаз.СоздатьНаборЗаписей();

// Шаг 2. Устанавливаем жесткие отборы по ключевым измерениям. 
// Внимание! Если не установить отбор, при записи набора сотрется ВЕСЬ регистр!
НаборЗаписей.Отбор.УзелИнформационнойБазы.Установить(СсылкаНаПроблемныйУзел);

// При необходимости уточняем отбор другими измерениями, например, уникальными идентификаторами
// НаборЗаписей.Отбор.УникальныйИдентификаторИсточника.Установить(НужныйИдентификатор);

// Шаг 3. Включаем режим загрузки. 
// Это ключевое действие, которое отключает вызов обработчика "ПередЗаписью" в модуле регистра.
НаборЗаписей.ОбменДанными.Загрузка = Истина;

// Шаг 4. Записываем пустой набор. 
// Так как в самом наборе нет ни одной строки, а отбор установлен, 
// это действие полностью удалит из базы данных строки, соответствующие отбору.
Попытка
    НаборЗаписей.Записать();
    Сообщить("Запись успешно удалена из регистра.");
Исключение
    Сообщить("Ошибка при удалении записи: " + ОписаниеОшибки());
КонецПопытки;

Альтернативное решение с использованием Библиотеки стандартных подсистем (БСП)

Если вы работаете в современной конфигурации, разработанной на базе БСП (например, «1С:Бухгалтерия предприятия 3.0», «1С:Зарплата и управление персоналом 3.1», «1С:ERP Управление предприятием»), настоятельно рекомендуется использовать стандартные механизмы общего модуля для установки флага загрузки. Это гарантирует корректную отработку всех подсистем БСП при манипуляции с данными.

Рассмотрим пример кода с использованием БСП:


НаборЗаписей = РегистрыСведений.СоответствияОбъектовИнформационныхБаз.СоздатьНаборЗаписей();
НаборЗаписей.Отбор.УзелИнформационнойБазы.Установить(ПроблемныйУзел);

// Используем типовую процедуру БСП для установки режима загрузки
ОбменДаннымиСервер.УстановитьОбменДаннымиЗагрузку(НаборЗаписей, Истина);

// Выполняем удаление
НаборЗаписей.Записать();

Резюме и лучшие практики

Подведем итоги нашего разбора. При работе со служебными регистрами сведений обмена данными всегда придерживайтесь следующих правил:

  1. Никогда не используйте РегистрСведенийМенеджерЗаписи для операций, требующих обхода бизнес-логики и отключения проверок, так как у него отсутствует свойство ОбменДанными.
  2. Всегда используйте РегистрСведенийНаборЗаписей, когда нужно применить свойство ОбменДанными.Загрузка = Истина.
  3. Будьте предельно внимательны при установке отборов перед вызовом метода Записать() у пустого набора записей. Всегда проверяйте, что отбор установлен корректно, чтобы случайно не очистить всю таблицу регистра в базе данных.
  4. При написании собственных обработок обмена данными тщательно проверяйте передаваемые узлы планов обмена, исключая возможность записи данных с узлом «Этот узел» текущей информационной базы.
← На главную