При разработке и настройке обменов данными в 1С программисты часто используют метод ЗарегистрироватьИзменения менеджера планов обмена. В большинстве случаев регистрация проходит гладко, однако иногда при попытке зарегистрировать изменения конкретного справочника или документа система выдает ошибку: Недопустимое значение параметра (параметр номер '2'). Рассмотрим подробнее, почему возникает эта проблема, и разберем по шагам все возможные способы ее решения.
Обычно вызов метода выглядит следующим образом:
ПланыОбмена.ЗарегистрироватьИзменения(МассивУзлов, Объект);
В первом параметре мы передаем ссылку на узел или массив узлов, а во втором — сам объект данных, ссылку на него или объект метаданных. Ошибка указывает на то, что платформе «не нравится» переданный во втором параметре объект. Выясним причину такого поведения.
Проанализируем ситуацию, с которой столкнулся автор на форуме. У него корректно регистрировались все документы и справочники, кроме одного конкретного. Как выяснилось при отладке, переменная Объект содержала правильные данные (объект справочника), права доступа были настроены верно, но ошибка все равно возникала.
Проблема крылась в архитектуре самого обмена. Данные для текущего обмена поступали из другого обмена. Если справочник не включен в состав хотя бы одного обмена (или связанного обмена, из которого тянутся данные), у него физически не создается таблица регистрации изменений в базе данных. Платформе просто негде хранить записи о том, что этот элемент изменился. Решением стало включение проблемного справочника в состав нужного плана обмена. Напомним, что добавление нового объекта метаданных в состав плана обмена (установка галочки в конфигураторе) требует реструктуризации базы данных.
Вторым важным аспектом является жесткая проверка платформой состава плана обмена для каждого узла. Если в первый параметр передается массив узлов обмена, платформа проверяет, входит ли объект метаданных (наш справочник) в состав плана обмена для каждого узла из этого массива.
Если хотя бы для одного узла в массиве данный справочник не включен в состав плана обмена, метод выдаст ошибку второго параметра. Разберем по шагам, как это исправить:
Существует специфическая особенность платформы 1С, связанная с длиной кода справочника. Если у справочника отключена длина кода (в метаданных свойство Длина кода равно нулю), попытка программно зарегистрировать его изменения для нового (еще не записанного в базу) элемента в обработчике ПередЗаписью гарантированно приведет к ошибке.
Платформа не может корректно идентифицировать объект для регистрации до момента его фактической записи, если у него нет кода. Решение здесь очень простое: перенесите вызов метода регистрации изменений в события ПриЗаписи или ПослеЗаписи. На этом этапе объект уже имеет внутренний идентификатор (ссылку), и регистрация пройдет успешно.
В 1С есть возможность снять регистрацию изменений (или зарегистрировать их) сразу для всех данных, если передать во второй параметр значение Неопределено. Посмотрим на пример, который часто вызывает ошибку:
// ОШИБОЧНЫЙ ВАРИАНТ
МассивУзлов = Новый Массив;
МассивУзлов.Добавить(Узел1);
МассивУзлов.Добавить(Узел2);
ПланыОбмена.ЗарегистрироватьИзменения(МассивУзлов, Неопределено);
По правилам платформы 1С, если второй параметр равен Неопределено, то первым параметром может выступать только одиночный узел, а не массив узлов. Если передать массив, платформа выдаст ошибку параметра номер 2. Правильный подход — регистрировать изменения в цикле по каждому узлу:
// ПРАВИЛЬНЫЙ ВАРИАНТ
Для Каждого ТекущийУзел Из МассивУзлов Цикл
ПланыОбмена.ЗарегистрироватьИзменения(ТекущийУзел, Неопределено);
КонецЦикла;
У каждого плана обмена существует предопределенный узел (узел текущей информационной базы), который в режиме Предприятия помечается специальной пиктограммой с точкой. Информационная база не может регистрировать изменения «сама для себя».
Если при формировании выборки узлов или заполнении массива вы случайно добавили этот предопределенный узел (например, забыли наложить условие ЭтотУзел = Ложь), платформа откажется выполнять регистрацию и вернет ошибку недопустимого значения параметра. Всегда проверяйте, что вы не пытаетесь передать узел текущей базы в метод.
Часто проблема проявляется при автоматической синхронизации данных (например, между 1С:Бухгалтерией и 1С:ЗУП) после проведения пользователями процедуры поиска и удаления дублей.
Если в кэше, фоновом задании или правилах обмена осталась ссылка на уже удаленный из базы элемент (битая ссылка), платформа при вызове метода не сможет определить метаданные этого объекта. В результате второй параметр будет воспринят как некорректный. В такой ситуации необходимо очистить кэш или проверить узлы регистрации на наличие ссылок типа <Объект не найден> и снять с них регистрацию вручную (например, через типовую обработку "Регистрация изменений для обмена").
Наконец, проанализируем ситуацию, которая часто встречается в распределенных информационных базах (РИБ). Даже если вы проверили состав плана обмена и справочник там присутствует, платформа все равно может выдавать ошибку. Это происходит из-за сбоя внутреннего кэша метаданных.
Чтобы решить эту проблему, используйте программный «передерг» состава плана обмена:
Эта простая процедура принудительно пересоздает таблицы регистрации изменений на уровне СУБД и обновляет кэши платформы, после чего метод ПланыОбмена.ЗарегистрироватьИзменения начинает работать без ошибок.