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