При работе с инструментом «1С:Конвертация данных 2.0» (КД 2.0) разработчики часто сталкиваются с ситуацией, когда нужная информация отображается в интерфейсе (на управляемой форме), но отсутствует в физических реквизитах самого объекта (документа или справочника). В этой статье мы подробно разберем, почему нельзя напрямую обратиться к элементам формы при выгрузке, и как правильно извлечь эти данные программными методами.
Для начала проанализируем архитектурную ситуацию. Процесс выгрузки данных через универсальную обработку выгрузки (например, V8Exchan82.epf) всегда происходит на сервере. Управляемая форма — это объект клиентского уровня. Когда работает программный код конвертации, он оперирует объектами базы данных (ДокументОбъект, СправочникОбъект), которые ничего «не знают» о том, открыта ли сейчас форма у пользователя и что в ней заполнено.
Нужно четко понимать: форма — это лишь визуальное представление. Если на форме есть данные, которых нет в реквизитах объекта, значит, они либо рассчитываются динамически по какому-то алгоритму, либо выбираются запросом из других таблиц (регистров, справочников) в момент открытия или обновления формы. Поэтому наша задача — не «нажать на кнопку формы», а воспроизвести ту же логику получения данных в правилах конвертации.
Рассмотрим самый распространенный вариант: нам нужно заполнить реквизит в базе-приемнике, основываясь на данных, которые в базе-источнике видны только на форме. Для этого в Правилах Конвертации Объектов (ПКО) мы создаем новое Правило Конвертации Свойства (ПКС).
Перед выгрузкой.В этом обработчике нам необходимо написать код, который вычислит значение и присвоит его специальной переменной Значение. Рассмотрим пример, когда на форме документа отображается остаток товара на складе, и мы хотим передать этот остаток в приемник:
// Пример получения данных запросом в ПКС
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ТоварыНаСкладахОстатки.В НаличииОстаток КАК Остаток
|ИЗ
| РегистрНакопления.ТоварыНаСкладах.Остатки(, Номенклатура = &Номенклатура) КАК ТоварыНаСкладахОстатки";
Запрос.УстановитьПараметр("Номенклатура", Источник.Номенклатура);
Выборка = Запрос.Выполнить().Выбрать();
Если Выборка.Следующий() Тогда
Значение = Выборка.Остаток;
Иначе
Значение = 0;
КонецЕсли;
Таким образом, мы полностью игнорируем форму и получаем данные напрямую из первоисточника — регистров базы данных.
Если логика получения данных очень сложная и требует обращения к множеству таблиц, проанализируем возможность использования Правил Выгрузки Данных (ПВД). Если в ПВД выбран способ выборки «Произвольный алгоритм», мы можем подготовить структуру ВходящиеДанные и передать её в ПКО.
Посмотрим на пример реализации в обработчике ПВД Перед обработкой:
// В ПВД формируем запрос, который соберет данные сразу для всех объектов
Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ Ссылка, СпецифическийПараметр ИЗ Справочник.Номенклатура ГДЕ ...";
РезультатЗапроса = Запрос.Выполнить().Выгрузить();
Для Каждого СтрокаДанных Из РезультатЗапроса Цикл
СтруктураВходящихДанных = Новый Структура;
СтруктураВходящихДанных.Вставить("ДопРеквизит", СтрокаДанных.СпецифическийПараметр);
// Передаем структуру в правило конвертации объекта
ВыгрузитьПоПравилу(СтрокаДанных.Ссылка, , СтруктураВходящихДанных, , "ИмяПКО_Номенклатура");
КонецЦикла;
Затем в ПКС нужного свойства в ПКО достаточно будет написать: Значение = ВходящиеДанные.ДопРеквизит;. Это гораздо эффективнее, чем делать по одному мелкому запросу для каждого объекта.
Часто в современных конфигурациях (на базе БСП) разработчики выносят логику заполнения «экранных» данных в модуль менеджера объекта. Выясним, есть ли там подходящие функции. Если в модуле менеджера документа есть экспортная функция ПолучитьДанныеДляФормы(Ссылка), мы можем вызвать её напрямую из обработчика КД 2.0:
Пример в ПКС «Перед выгрузкой»:
// Вызов серверного метода модуля менеджера
ДанныеОбъекта = Документы.РеализацияТоваровУслуг.ПолучитьДанныеДляФормы(Источник.Ссылка);
Значение = ДанныеОбъекта.НужныйНамПараметр;
Этот подход позволяет избежать дублирования кода и гарантирует, что в выгрузку попадут ровно те же цифры, что видит пользователь на экране.
Проанализируем ситуацию с производительностью. Если мы добавим сложный запрос в каждое ПКС, выгрузка 10 000 документов может затянуться на часы. Чтобы этого избежать, используем глобальные параметры конвертации.
Перед выгрузкой данных (глобальный обработчик правил) выполняем один массивный запрос.Соответствие, где ключом будет Ссылка на объект, а значением — наши «данные с формы».Параметры.Значение = Параметры.МоеСоответствие.Получить(Источник.Ссылка);.Важный совет: Всегда проверяйте, не является ли «реквизит формы» на самом деле Дополнительным реквизитом (характерно для БСП). Если это так, то данные хранятся в табличной части ДополнительныеРеквизиты или в аналогичном регистре сведений, и их нужно доставать оттуда стандартным запросом по владельцу.
Выясним краткий алгоритм действий, если вам нужны данные «с формы»:
Перед выгрузкой).ВходящиеДанные или Параметры для оптимизации, чтобы не нагружать базу лишними вызовами.Таким образом, соблюдая правила серверной разработки, вы сможете перенести любую информацию, даже если она кажется исключительно «визуальной».