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