При переносе логики работы с документами в регламентные задания разработчики часто сталкиваются с ситуацией, когда код, успешно работающий в интерактивном сеансе, аварийно завершается в фоновом процессе. Типичный пример — ошибка инициализации общего модуля с сообщением «Тип не определен (ДиалогВыбораФайла)». Разберем механизм возникновения этой ошибки и способы ее правильного устранения.
Проанализируем типовую ситуацию: в фоновом задании программно создается и проводится документ (например, ПоступлениеТоваровУслуг). В процессе проведения платформа 1С аварийно завершает работу со следующей диагностикой:
Ошибка инициализации модуля: ОбщийМодуль.РаботаСТорговымОборудованием.Модуль по причине: {ОбщийМодуль.РаботаСТорговымОборудованием.Модуль(900,18)}: Тип не определен (ДиалогВыбораФайла)
При этом указанная строка находится в процедуре, которая вообще не должна вызываться в текущем сценарии. Выясним причину такого поведения платформы.
Платформа 1С:Предприятие выполняет компиляцию программного модуля целиком при первом обращении к любому его экспортируемому методу или переменной из текущего контекста. Процесс компиляции переводит исходный текст модуля в промежуточный байт-код.
Если серверный процесс (фоновое или регламентное задание) обращается хотя бы к одной функции общего модуля, на сервере компилируется весь текст этого модуля. Если в свойствах общего модуля установлен флаг Сервер, а внутри присутствуют типы, доступные исключительно в клиентском контексте (такие как ДиалогВыбораФайла, ТабличноеПоле или вызовы оконных предупреждений), компилятор сервера не сможет распознать эти типы и выдаст исключение еще на этапе инициализации модуля до вызова целевой функции.
Посмотрим на типовой источник проблемы: разработчики включают флаг Сервер у клиентского модуля (например, РаботаСТорговымОборудованием), чтобы вызвать из серверного кода вспомогательную функцию (генерацию штрихкода, форматирование данных), не учитывая, что модуль перегружен клиентскими интерфейсными конструкциями.
Самым надежным и архитектурно правильным решением является разделение серверного и клиентского контекстов по разным модулям. Не следует включать флаг Сервер у чисто клиентских модулей торгового оборудования.
РаботаСТорговымОборудованиемСервер или ШтрихкодированиеСервер.РаботаСТорговымОборудованием снимем ошибочно установленный флаг Сервер, вернув его в исходное клиентское состояние.Если разделение модуля по отдельным объектам метаданных нежелательно, используем директивы препроцессора для экранирования интерактивных типов от серверного компилятора. Инструкции препроцессора исключают указанные блоки кода из компиляции в несовместимом контексте.
Посмотрим на пример оборачивания клиентского кода:
#Если Клиент И НЕ ТонкийКлиент Тогда
Процедура ВыбратьФайлНаКлиенте() Экспорт
Диалог = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Открытие);
Диалог.Заголовок = "Выберите файл для загрузки";
Если Диалог.Выбрать() Тогда
ПутьКФайлу = Диалог.ПолноеИмяФайла;
КонецЕсли;
КонецПроцедуры
#КонецЕсли
Для конфигураций на обычных формах (например, УПП 1.3 или КА 1.1) также используется проверка режима толстого клиента:
#Если ТолстыйКлиентОбычноеПриложение Тогда
// Код работы с интерактивными диалогами и оборудованием на клиенте
#КонецЕсли
Если вызов логики торгового оборудования зашит в событиях объекта (ПередЗаписью или ОбработкаПроведения), в регламентных операциях его необходимо явно отключать через свойство ДополнительныеСвойства.
Разберем по шагам, как передать признак программного проведения:
// В процедуре регламентного задания при формировании документа
ДокументОбъект = Документы.ПоступлениеТоваровУслуг.СоздатьДокумент();
// Заполняем реквизиты документа...
ДокументОбъект.ДополнительныеСвойства.Вставить("ОтказОтОбработкиШтрихкодов", Истина);
ДокументОбъект.Записать(РежимЗаписиДокумента.Проведение);
В модуле объекта проверяем наличие флага перед обращением к модулям оборудования:
Процедура ПередЗаписью(Отказ, РежимЗаписи, РежимПроведения)
ПропускатьОбработку = Ложь;
Если ДополнительныеСвойства.Свойство("ОтказОтОбработкиШтрихкодов", ПропускатьОбработку) И ПропускатьОбработку Тогда
// Пропускаем формирование штрихкодов и работу с торговым оборудованием
Иначе
// Стандартная обработка для интерактивного режима
КонецЕсли;
КонецПроцедуры
Чтобы заранее обнаружить подобные проблемы до запуска регламентных операций в рабочей базе, выполним встроенную проверку конфигурации:
ДиалогВыбораФайла.