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