В процессе разработки на управляемых формах многие программисты, привыкшие к архитектуре обычных форм, сталкиваются с ситуацией, когда переменные, объявленные через Перем в модуле формы, внезапно оказываются пустыми при повторном обращении. Давайте разберем, почему это происходит и какие архитектурные решения позволяют корректно передавать и хранить данные в 1С.
В управляемом приложении взаимодействие клиента и сервера происходит через механизм вызовов контекста. Когда вы вызываете серверную процедуру, платформа:
Переменные, объявленные в модуле формы, живут ровно столько, сколько длится конкретный вызов процедуры &НаСервере. Они не сохраняются в памяти между разными нажатиями кнопок или вызовами функций. Даже если кажется, что переменная «глобальная» для модуля, при следующем обращении к серверу для формы создается «чистый» экземпляр модуля с пустыми переменными.
Самый надежный и стандартизированный способ хранения данных, которые должны «жить» в форме — это реквизиты формы. В отличие от обычных переменных, реквизиты формы автоматически сериализуются платформой и передаются между клиентом и сервером. Это избавляет вас от необходимости вручную управлять состоянием данных.
Разберем по шагам:
ДанныеДляХранения) с нужным типом.ЭтотОбъект.ДанныеДляХранения или просто по имени реквизита.Пример использования:
&НаСервере
Процедура ИзменитьДанныеНаСервере(НовоеЗначение)
// Реквизит формы будет доступен и сохранен между вызовами
Объект.МойРеквизит = НовоеЗначение;
КонецПроцедуры
Если данные должны быть доступны не только внутри одной формы, но и во всем сеансе работы пользователя (например, текущие настройки или идентификаторы), следует использовать ПараметрыСеанса. Это глобальное хранилище данных, которое инициализируется при входе в систему.
Преимущества: отсутствие «магии» с очисткой памяти и доступность из любого модуля конфигурации.
Важно: не злоупотребляйте этим инструментом для хранения временных промежуточных данных конкретной формы — для таких целей реквизит формы подходит гораздо лучше.
Если данные не обязательно хранить в форме, а они нужны лишь для выполнения цепочки действий, передавайте их явно через параметры процедур. Это делает код прозрачным и предсказуемым, так как разработчику не нужно гадать, в какой момент и кем была изменена переменная.
&НаКлиенте
Процедура КомандаВыполнить(Команда)
Данные = ПолучитьДанные();
ВыполнитьОбработку(Данные);
КонецПроцедуры
&НаСервере
Процедура ВыполнитьОбработку(ЗначениеДляОбработки)
// Работа с данными напрямую через параметр
Сообщить(ЗначениеДляОбработки);
КонецПроцедуры
Иногда возникает соблазн использовать ПоместитьВоВременноеХранилище для передачи данных между вызовами. Рассмотрим риски:
Использование ВременногоХранилища оправдано только для передачи больших объемов данных (например, файлов или таблиц) между клиентом и сервером при формировании отчетов или загрузках, но не как замена «глобальной переменной» для логики формы.
Мы проанализировали ситуацию и выяснили, что попытки «обмануть» платформу и создать глобальную переменную в модуле формы — это путь к нестабильной работе программы. Лучшей практикой для разработчика является использование реквизитов формы. Это избавляет от архитектурных «костылей» и обеспечивает предсказуемое поведение вашей прикладной логики.