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