Как передать значение реквизита формы внешней обработки в общий модуль на сервере

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

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

Понимание контекста: почему сервер «не видит» форму

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

Способ 1. Передача данных через структуру параметров (Рекомендуемый)

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

Рассмотрим пошагово, как это реализовать. Предположим, у нас есть внешняя обработка с реквизитом ДатаНачала и Контрагент. Нам нужно передать их в общий модуль МойМодульСервер.

Шаг 1. Подготовка данных в модуле формы:


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

Шаг 2. Прием данных в общем модуле:

Важно убедиться, что у общего модуля стоят галочки «Сервер» и «Вызов сервера» (или модуль вызывается из другого серверного контекста).


// В общем модуле МойМодульСервер
Процедура ОбработатьДанныеНаСервере(Параметры) Экспорт
    
    // Извлекаем данные из структуры
    ТекущаяДата = Параметры.ДатаНачала;
    ВыбранныйКонтрагент = Параметры.Контрагент;
    
    // Выполняем логику
    // ...
    
КонецПроцедуры

Использование Структура позволяет вам в будущем легко добавить новый реквизит в передачу, не меняя сигнатуру (количество параметров) метода в общем модуле.

Способ 2. Использование временного хранилища

Если вам нужно передать не просто пару значений, а тяжелые данные (например, таблицу значений, файл или саму внешнюю обработку целиком), лучше всего использовать ПоместитьВоВременноеХранилище. Этот метод позволяет передать на сервер уникальный адрес (строку), по которому сервер сможет забрать объект.

Разберем ситуацию, когда нам нужно передать таблицу, созданную на форме:


&НаКлиенте
Процедура ПередатьТаблицуНаСервер()
    
    // Преобразуем данные формы в структуру или таблицу (если это реквизит объекта)
    АдресДанных = ПоместитьВоВременноеХранилище(Объект.ТЧ_Товары.Выгрузить(), ЭтаФорма.УникальныйИдентификатор);
    
    // Передаем только адрес
    МойМодульСервер.ЗагрузитьДанныеИзХранилища(АдресДанных);
    
КонецПроцедуры

В общем модуле на сервере мы извлечем данные функцией ПолучитьИзВременногоХранилища. Это очень эффективно, так как минимизирует объем данных, передаваемых непосредственно в момент вызова метода.

Способ 3. Преобразование формы в объект (РеквизитФормыВЗначение)

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

Проанализируем пример кода в модуле формы:


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

Способ 4. Хранилище настроек (Решение автора темы)

Иногда возникает специфическая задача: значение реквизита должно быть доступно в общем модуле даже без прямой передачи параметров (например, при работе в фоновом задании или в глубоко вложенных вызовах подсистем). В этом случае можно использовать ХранилищеНастроек или ХранилищеОбщихНастроек.

Принцип работы:

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

Рассмотрим пример записи данных:


&НаКлиенте
Процедура СохранитьНастройкуДляСервера()
    КлючОбъекта = "НастройкиМоейВнешнейОбработки";
    КлючНастройки = "ТекущийСклад";
    ХранилищеОбщихНастроек.Сохранить(КлючОбъекта, КлючНастройки, Объект.Склад);
КонецПроцедуры

И пример чтения в общем модуле на сервере:


Функция ПолучитьСкладИзНастроек() Экспорт
    КлючОбъекта = "НастройкиМоейВнешнейОбработки";
    КлючНастройки = "ТекущийСклад";
    Возврат ХранилищеОбщихНастроек.Загрузить(КлючОбъекта, КлючНастройки);
КонецФункции

Важное предостережение: Хотя этот способ рабочий, он создает нагрузку на базу данных (выполняется реальная запись в таблицу настроек). Используйте его только тогда, когда прямая передача параметров через Структура невозможна по архитектурным соображениям.

Типичные ошибки начинающих

Разберем, почему некоторые подходы, озвученные на форумах, могут не работать:

Резюме

Для эффективной работы мы рекомендуем придерживаться правила «явной передачи». Если общему модулю нужны данные из формы — передайте их в параметрах функции. Это делает ваш код прозрачным, легким в отладке и независимым от состояния сеанса пользователя. Если же вы столкнулись с ситуацией, когда структуру передать невозможно, используйте ХранилищеОбщихНастроек, как это сделал автор рассмотренной темы, но помните о производительности.

← На главную