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