Перевод функционала из интерактивного режима (через форму) в автоматический (через регламентные или фоновые задания) — это частая задача для разработчика 1С. При этом новички часто сталкиваются с проблемой «невидимости» контекста формы в модуле объекта. Проанализируем, как правильно организовать доступ к данным и методам объекта, когда работа идет на стороне сервера без участия пользователя.
В управляемых формах (УФ) данные, с которыми мы работаем, представлены реквизитом Объект. В модуле формы этот реквизит имеет тип ДанныеФормыСтруктура. Чтобы превратить его в «настоящий» объект (обработку или документ) для выполнения серверных методов, мы используем функцию РеквизитФормыВЗначение("Объект"). Однако, когда мы перемещаемся в Модуль объекта, ситуация в корне меняется.
Разберем основной нюанс: внутри модуля объекта вы уже находитесь внутри самого объекта. Методы типа РеквизитФормыВЗначение там недоступны и не нужны, так как они относятся к контексту формы. В модуле объекта для обращения к собственным реквизитам и методам используется ключевое слово ЭтотОбъект или прямое обращение к именам реквизитов.
Рассмотрим ситуацию на примере переноса логики из стандартной обработки V8Exchan83 (Универсальный обмен данными XML). Если в форме мы писали код для получения объекта, то в модуле объекта он упрощается. Посмотрим на типичную ошибку и ее исправление:
Неправильно (попытка использовать методы формы в модуле объекта):
// Это вызовет ошибку "Процедура или функция не определена"
ОбъектДляСервера = РеквизитФормыВЗначение("Объект");
ОбъектДляСервера.ВыполнитьЗагрузку();
Правильно (использование встроенного контекста):
// Мы уже в объекте, просто вызываем метод
ЭтотОбъект.ВыполнитьЗагрузку();
// Или даже просто:
ВыполнитьЗагрузку();
Проанализируем пример настройки параметров загрузки непосредственно в модуле объекта перед выполнением основной логики:
Процедура ИнициализироватьЗагрузку() Экспорт
ЭтотОбъект.ИмяФайлаОбмена = "\\SRV\Exchange\data.xml";
ЭтотОбъект.ЗагружатьДанныеВРежимеОбмена = Истина;
ЭтотОбъект.ЗаписыватьВИнформационнуюБазуТолькоИзмененныеОбъекты = Истина;
ЭтотОбъект.РежимОбмена = "Загрузка";
ЭтотОбъект.ВыполнитьЗагрузку();
КонецПроцедуры
Если вы делаете дополнительную обработку, которая должна запускаться как регламентное задание через справочник «Дополнительные отчеты и обработки», важно соблюдать стандарты БСП. Выясним, как должна выглядеть структура экспортных методов.
Во-первых, функция СведенияОВнешнейОбработке() должна указывать способ использования ВызовСерверногоМетода:
Функция СведенияОВнешнейОбработке() Экспорт
ПараметрыРегистрации = ДополнительныеОтчетыИОбработки.СведенияОВнешнейОбработке("2.2.2.1");
ПараметрыРегистрации.Вид = ДополнительныеОтчетыИОбработкиКлиентСервер.ВидОбработкиДополнительнаяОбработка();
НоваяКоманда = ПараметрыРегистрации.Команды.Добавить();
НоваяКоманда.Представление = "Выполнить загрузку (фон)";
НоваяКоманда.Идентификатор = "ЗагрузкаДанных";
НоваяКоманда.Использование = ДополнительныеОтчетыИОбработкиКлиентСервер.ТипКомандыВызовСерверногоМетода();
Возврат ПараметрыРегистрации;
КонецФункции
Во-вторых, в модуле объекта обязательно должна присутствовать процедура ВыполнитьКоманду с правильным количеством параметров. Проанализируем ее сигнатуру:
// Важно: параметров должно быть два, даже если второй не используется
Процедура ВыполнитьКоманду(ИдентификаторКоманды, ПараметрыВыполненияКоманды) Экспорт
Если ИдентификаторКоманды = "ЗагрузкаДанных" Тогда
// Здесь вызываем нашу логику
ЗапуститьРоботЗагрузки();
КонецЕсли;
КонецПроцедуры
Если код в ручном режиме (через форму) работает, а в фоновом — нет (хотя Журнал Регистрации пишет «Успешное завершение»), рассмотрим следующие причины:
USR1CV8). У этой записи часто нет прав на доступ к сетевым папкам типа \\Server\Folder. Попробуйте использовать локальный путь на диске сервера для теста.Предупреждение(), Вопрос(), Сообщить() (если они не перенаправлены в журнал). Любое модальное окно «подвесит» или мгновенно завершит поток с ошибкой.БезопасныйРежим = Ложь.Выясним, как поймать ошибку в коде, который выполняется невидимо для нас. Для этого выполним следующие шаги:
-debug. Проверьте это в реестре Windows в строке запуска службы.Отладка -> Подключение -> Автоматическое подключение. Установите флажки «Фоновые задания» и «Серверные вызовы».ЗаписьЖурналаРегистрации(). Расставьте такие записи в начале и конце ключевых процедур. Это позволит понять, до какого момента доходит исполнение.Пример диагностического кода:
ЗаписьЖурналаРегистрации("МояОбработка.Старт", УровеньЖурналаРегистрации.Информация, , , "Начинаем загрузку файла: " + ИмяФайла);
Попытка
ЭтотОбъект.ВыполнитьЗагрузку();
ЗаписьЖурналаРегистрации("МояОбработка.Успех", УровеньЖурналаРегистрации.Информация);
Исключение
ЗаписьЖурналаРегистрации("МояОбработка.Ошибка", УровеньЖурналаРегистрации.Ошибка, , , ОписаниеОшибки());
КонецПопытки;
Таким образом, для успешной работы в модуле объекта нам нужно отказаться от «форменных» привычек (типа РеквизитФормыВЗначение), правильно описать экспортный интерфейс для БСП и обеспечить серверу необходимые права доступа к внешним ресурсам.