Как выгрузить данные из управляемой формы в 1С:Конвертация данных 2.0

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

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

Разберем причину: Почему форма недоступна при выгрузке?

Для начала проанализируем архитектурную ситуацию. Процесс выгрузки данных через универсальную обработку выгрузки (например, V8Exchan82.epf) всегда происходит на сервере. Управляемая форма — это объект клиентского уровня. Когда работает программный код конвертации, он оперирует объектами базы данных (ДокументОбъект, СправочникОбъект), которые ничего «не знают» о том, открыта ли сейчас форма у пользователя и что в ней заполнено.

Нужно четко понимать: форма — это лишь визуальное представление. Если на форме есть данные, которых нет в реквизитах объекта, значит, они либо рассчитываются динамически по какому-то алгоритму, либо выбираются запросом из других таблиц (регистров, справочников) в момент открытия или обновления формы. Поэтому наша задача — не «нажать на кнопку формы», а воспроизвести ту же логику получения данных в правилах конвертации.

Решение 1: Использование обработчика «Перед выгрузкой» в ПКС

Рассмотрим самый распространенный вариант: нам нужно заполнить реквизит в базе-приемнике, основываясь на данных, которые в базе-источнике видны только на форме. Для этого в Правилах Конвертации Объектов (ПКО) мы создаем новое Правило Конвертации Свойства (ПКС).

  1. В ПКС оставляем поле «Источник» пустым.
  2. В поле «Приемник» указываем имя реквизита в целевой конфигурации.
  3. Переходим на закладку «Обработчики событий» и находим событие Перед выгрузкой.

В этом обработчике нам необходимо написать код, который вычислит значение и присвоит его специальной переменной Значение. Рассмотрим пример, когда на форме документа отображается остаток товара на складе, и мы хотим передать этот остаток в приемник:


// Пример получения данных запросом в ПКС
Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |   ТоварыНаСкладахОстатки.В НаличииОстаток КАК Остаток
    |ИЗ
    |   РегистрНакопления.ТоварыНаСкладах.Остатки(, Номенклатура = &Номенклатура) КАК ТоварыНаСкладахОстатки";

Запрос.УстановитьПараметр("Номенклатура", Источник.Номенклатура);
Выборка = Запрос.Выполнить().Выбрать();

Если Выборка.Следующий() Тогда
    Значение = Выборка.Остаток;
Иначе
    Значение = 0;
КонецЕсли;

Таким образом, мы полностью игнорируем форму и получаем данные напрямую из первоисточника — регистров базы данных.

Решение 2: Передача данных через входящие данные в ПВД

Если логика получения данных очень сложная и требует обращения к множеству таблиц, проанализируем возможность использования Правил Выгрузки Данных (ПВД). Если в ПВД выбран способ выборки «Произвольный алгоритм», мы можем подготовить структуру ВходящиеДанные и передать её в ПКО.

Посмотрим на пример реализации в обработчике ПВД Перед обработкой:


// В ПВД формируем запрос, который соберет данные сразу для всех объектов
Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ Ссылка, СпецифическийПараметр ИЗ Справочник.Номенклатура ГДЕ ...";
РезультатЗапроса = Запрос.Выполнить().Выгрузить();

Для Каждого СтрокаДанных Из РезультатЗапроса Цикл
    СтруктураВходящихДанных = Новый Структура;
    СтруктураВходящихДанных.Вставить("ДопРеквизит", СтрокаДанных.СпецифическийПараметр);
    
    // Передаем структуру в правило конвертации объекта
    ВыгрузитьПоПравилу(СтрокаДанных.Ссылка, , СтруктураВходящихДанных, , "ИмяПКО_Номенклатура");
КонецЦикла;

Затем в ПКС нужного свойства в ПКО достаточно будет написать: Значение = ВходящиеДанные.ДопРеквизит;. Это гораздо эффективнее, чем делать по одному мелкому запросу для каждого объекта.

Решение 3: Поиск логики в модуле менеджера

Часто в современных конфигурациях (на базе БСП) разработчики выносят логику заполнения «экранных» данных в модуль менеджера объекта. Выясним, есть ли там подходящие функции. Если в модуле менеджера документа есть экспортная функция ПолучитьДанныеДляФормы(Ссылка), мы можем вызвать её напрямую из обработчика КД 2.0:

Пример в ПКС «Перед выгрузкой»:


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

Этот подход позволяет избежать дублирования кода и гарантирует, что в выгрузку попадут ровно те же цифры, что видит пользователь на экране.

Оптимизация: Как не замедлить выгрузку

Проанализируем ситуацию с производительностью. Если мы добавим сложный запрос в каждое ПКС, выгрузка 10 000 документов может затянуться на часы. Чтобы этого избежать, используем глобальные параметры конвертации.

  1. В обработчике Перед выгрузкой данных (глобальный обработчик правил) выполняем один массивный запрос.
  2. Результат помещаем в Соответствие, где ключом будет Ссылка на объект, а значением — наши «данные с формы».
  3. Помещаем это соответствие в структуру Параметры.
  4. В ПКС просто извлекаем значение: Значение = Параметры.МоеСоответствие.Получить(Источник.Ссылка);.

Важный совет: Всегда проверяйте, не является ли «реквизит формы» на самом деле Дополнительным реквизитом (характерно для БСП). Если это так, то данные хранятся в табличной части ДополнительныеРеквизиты или в аналогичном регистре сведений, и их нужно доставать оттуда стандартным запросом по владельцу.

Резюме

Выясним краткий алгоритм действий, если вам нужны данные «с формы»:

  1. Забудьте про форму как объект интерфейса.
  2. Найдите в коде конфигурации (модуль формы, модуль объекта или модуль менеджера), каким именно запросом или алгоритмом заполняется этот элемент.
  3. Перенесите этот запрос в обработчики КД 2.0 (Перед выгрузкой).
  4. Используйте ВходящиеДанные или Параметры для оптимизации, чтобы не нагружать базу лишними вызовами.

Таким образом, соблюдая правила серверной разработки, вы сможете перенести любую информацию, даже если она кажется исключительно «визуальной».

← На главную