Как обратиться к реквизитам формы из модуля внешней обработки в 1С 8.3

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

При разработке внешних обработок в управляемом приложении 1С начинающие и даже опытные разработчики иногда сталкиваются с ситуацией, когда из модуля объекта внешней обработки требуется получить данные, введённые пользователем на форме. В этой статье разберем, почему прямое обращение к элементам и реквизитам формы из модуля объекта невозможно, и проанализируем правильные способы передачи данных на сервер, в том числе при работе с фоновыми заданиями.

Почему из модуля объекта нельзя обратиться к реквизитам формы напрямую

Проанализируем контекст выполнения кода в платформах 1С:Предприятие 8.3 с управляемыми формами:

  1. Разделение контекстов: Модуль формы работает на клиенте (или на сервере в контексте формы), а модуль объекта внешней обработки создается и исполняется исключительно на сервере.
  2. Изоляция объекта: Экземпляр объекта внешней обработки, созданный на сервере, ничего не знает о существовании управляющей формы на клиенте. В нем присутствуют только реквизиты самого объекта (добавленные в дереве метаданных обработки), но не реквизиты формы.
  3. Ограничение фоновых заданий: Фоновое задание выполняется в изолированном сеансе на сервере, где физически отсутствует интерфейсный контекст формы.

Поэтому любые попытки обратиться из модуля объекта к элементам формы напрямую (например, по имени элемента) приведут к ошибке компиляции или выполнения.

Способ 1. Передача значений реквизитов формы в экспортные процедуры модуля объекта

Выясним, как передать данные из формы в модуль объекта при обычном вызове серверной процедуры. Если вы вызываете экспортную процедуру модуля объекта из модуля формы, значения реквизитов необходимо передавать через параметры вызова.

Рассмотрим пример. Допустим, на форме есть реквизиты ВремяЗавершенияСпящегоСеанса и ВремяЗасыпанияПассивногоСеанса. Чтобы обработать их в модуле объекта, напишем следующий код в модуле формы:


&НаСервере
Процедура ВыполнитьОбработкуНаСервере()
    
    // Преобразуем объект формы в эквивалентный объект внешней обработки
    ОбработкаОбъект = РеквизитФормыВЗначение("Объект");
    
    // Вызываем экспортную процедуру и передаем простые значения реквизитов формы в качестве параметров
    ОбработкаОбъект.МассоваяНастройкаПараметровИБ(
        Объект.База, 
        ВремяЗавершенияСпящегоСеанса, 
        ВремяЗасыпанияПассивногоСеанса
    );
    
КонецПроцедуры

В модуле объекта внешней обработки объявляем процедуру с соответствующими параметрами:


Процедура МассоваяНастройкаПараметровИБ(База, ВремяЗавершения, ВремяЗасыпания) Экспорт
    
    // Внутри процедуры используем переданные значения
    Соединение = УправлениеПодключениемСервер.ПодключитьсяКБазе(База);
    Если Соединение <> Неопределено Тогда
        Соединение.УстановитьВремяЗавершенияСпящегоСеанса(ВремяЗавершения);
        Соединение.УстановитьВремяЗасыпанияПассивногоСеанса(ВремяЗасыпания);
    КонецЕсли;
    
КонецПроцедуры

Обратите внимание: функция РеквизитФормыВЗначение() применяется для преобразования сложных данных (например, основной реквизит Объект или таблицы значений). Простые типы (числа, строки, даты, булево) передаются напрямую как значения.

Способ 2. Передача параметров реквизитов формы в фоновое задание

Рассмотрим более сложную ситуацию, когда выполнение процедуры внешней обработки выносится в фоновое задание через метод ФоновыеЗадания.Выполнить().

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

Разберем по шагам, как правильно сформировать структуру параметров и передать её в фоновое задание.

Шаг 1. Формирование структуры параметров в модуле формы:


&НаСервере
Процедура ЗапуститьФоновоеЗадание(Стр)
    
    // Упаковываем все реквизиты формы и данные строки в единую структуру
    ПараметрыИБ = Новый Структура;
    ПараметрыИБ.Вставить("База", Стр.База);
    ПараметрыИБ.Вставить("ВремяЗавершенияСпящегоСеанса", ВремяЗавершенияСпящегоСеанса);
    ПараметрыИБ.Вставить("ВремяЗасыпанияПассивногоСеанса", ВремяЗасыпанияПассивногоСеанса);
    ПараметрыИБ.Вставить("ВремяОжиданияБлокировкиДанных", ВремяОжиданияБлокировкиДанных);
    ПараметрыИБ.Вставить("МинимальнаяДлинаПаролейПользователей", МинимальнаяДлинаПаролейПользователей);
    ПараметрыИБ.Вставить("ПроверкаСложностиПаролейПользователей", ПроверкаСложностиПаролейПользователей);
    
    // Формируем массив параметров для универсальной процедуры выполнения
    МассивПараметров = Новый Массив;
    МассивПараметров.Добавить(ИмяФайла); // Путь к файлу внешней обработки
    МассивПараметров.Добавить("МассоваяНастройкаПараметровИБ"); // Имя вызываемой процедуры
    МассивПараметров.Добавить("ПараметрыИБ"); // Имя формального параметра
    МассивПараметров.Добавить(ПараметрыИБ); // Значение структуры с данными
    МассивПараметров.Добавить(Истина); // Признак внешней обработки
    МассивПараметров.Добавить(ПолучитьИзВременногоХранилища(Адрес)); // Двоичные данные файла
    
    Ключ = "Настройка параметров ИБ: " + Строка(Стр.База);
    
    ФЗ = ФоновыеЗадания.Выполнить(
        "ВыполнениеОтчетовОбработокСервер.ВыполнитьПроцедуруОбработкиФоновымЗаданием", 
        МассивПараметров, 
        Ключ, 
        Ключ
    );
    
КонецПроцедуры

Шаг 2. Прием параметров в модуле объекта внешней обработки:

Чтобы избежать ошибок нехватки аргументов, в модуле объекта экспортная процедура должна принимать ровно один параметр — структуру, переданную из формы:


Процедура МассоваяНастройкаПараметровИБ(ПараметрыИБ) Экспорт
    
    Ошибка = "";
    База = ПараметрыИБ.База;
    
    Соединение = УправлениеПодключениемСервер.ПодключитьсяКБазе(База, , , Ошибка);
    
    Если Соединение = Неопределено Тогда
        ВызватьИсключение "При подключении к базе " + Строка(База) + " произошла ошибка: " + Ошибка;
    Иначе
        Соединение.УстановитьВремяОжиданияБлокировкиДанных(ПараметрыИБ.ВремяОжиданияБлокировкиДанных);
        Соединение.УстановитьМинимальнуюДлинуПаролейПользователей(ПараметрыИБ.МинимальнаяДлинаПаролейПользователей);
        Соединение.УстановитьПроверкуСложностиПаролейПользователей(ПараметрыИБ.ПроверкаСложностиПаролейПользователей);
        Соединение.УстановитьВремяЗасыпанияПассивногоСеанса(ПараметрыИБ.ВремяЗасыпанияПассивногоСеанса);
        Соединение.УстановитьВремяЗавершенияСпящегоСеанса(ПараметрыИБ.ВремяЗавершенияСпящегоСеанса);
    КонецЕсли;
    
КонецПроцедуры

Как сделать параметры процедуры необязательными

Если сигнатуру экспортной процедуры меняют без возможности скорректировать все места её вызова в системе, значение по умолчанию объявляют прямо в заголовке процедуры:


Процедура МассоваяНастройкаПараметровИБ(База, ДопПараметры = Неопределено) Экспорт
    Если ДопПараметры <> Неопределено Тогда
        // Обработка дополнительных параметров
    КонецЕсли;
КонецПроцедуры

Указание Параметр = Неопределено позволяет передавать меньшее количество аргументов без возникновения ошибки «Недостаточно фактических параметров» при вызове функции.

Резюме

Подведем итоги работы с реквизитами формы в модулях внешних обработок 1С:

← На главную