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