К статье
Практический материал

Разработка и Конфигурация · 10 мин

1С: как запомнить значение реквизита на форме

Как запомнить значение реквизита формы в 1С: реквизиты формы, параметры, ХранилищеОбщихНастроек, кэш в переменных модуля. Примеры кода и типичные ошибки.

Задача «запомнить значение реквизита на форме» возникает у разработчика 1С в нескольких типовых ситуациях: нужно сравнить новое значение со старым при изменении поля, сохранить данные между вызовами серверных процедур, восстановить введённое пользователем значение при следующем открытии формы или передать данные между формами. У каждой ситуации — свой правильный инструмент, и типичная ошибка новичка — пытаться решить все задачи одним способом.

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

Определите, где именно нужно хранить значение

Прежде чем писать код, ответьте на два вопроса: как долго должно жить значение и где оно будет использоваться. От этого зависит выбор механизма.

  • Только пока открыта форма, между клиентом и сервером — реквизит формы или переменная модуля формы.
  • Между открытиями формы для конкретного пользователя — ХранилищеОбщихНастроек (стандартный механизм «запомнить последние введённые данные»).
  • Постоянно, для всех пользователей — константа, регистр сведений или реквизит самого объекта.
  • Передать значение при открытии формы — параметры формы.
Маршрут решения

Как выбрать способ

Значение нужно только внутри одной открытой формыСоздайте реквизит формы или переменную модуля
Нужно восстановить ввод при следующем открытии формыИспользуйте ХранилищеОбщихНастроек.Сохранить/Загрузить
Значение относится к данным объекта и должно храниться в базеДобавьте реквизит объекта и записывайте объект
Нужно передать значение из одной формы в другуюПередайте его через параметры формы или ОписаниеОповещения

Реквизит формы — основной способ запомнить значение

Реквизит формы — это данные, которые платформа автоматически переносит между клиентом и сервером вместе с формой. Это самый надёжный способ «запомнить» что-либо в рамках жизни формы.

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

Обращение к реквизиту в коде модуля формы выполняется напрямую по имени, если контекст формы, либо через ЭтаФорма.ИмяРеквизита:

&НаСервере

Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)

// Запоминаем исходное значение при открытии

СтароеЗначениеЦены = Объект.Цена;

КонецПроцедуры

&НаКлиенте

Процедура ЦенаПриИзменении(Элемент)

Если Объект.Цена < СтароеЗначениеЦены Тогда

ПоказатьПредупреждение(, "Цена снижена относительно исходной!");

КонецЕсли;

КонецПроцедуры

Переменные модуля формы и их ограничения

Переменные, объявленные в разделе описания переменных модуля формы, живут на клиенте до закрытия формы. Они удобны для временных данных, которые не нужны на сервере: признаки, флаги, промежуточные результаты расчётов.

&НаКлиенте

Перем ПредыдущееЗначение; // живёт, пока открыта форма

&НаКлиенте

Процедура ПолеПриИзменении(Элемент)

Если ПредыдущееЗначение <> Неопределено Тогда

// сравнение со старым значением

КонецЕсли;

ПредыдущееЗначение = Объект.Количество;

КонецПроцедуры

Ключевое ограничение: при серверном вызове контекст формы пересоздаётся, и клиентские переменные модуля на сервере недоступны, а серверные переменные модуля формы между вызовами не сохраняются. Если значение нужно и на клиенте, и на сервере — заводите реквизит формы, а не переменную.

Типичные ошибки
01
Объявление серверной переменной модуля для хранения значения между вызовами — после серверного вызова переменная обнуляется, потому что форма пересоздаётся
02
Использование &НаСервереБезКонтекста и попытка обратиться к реквизиту формы — такой код не скомпилируется или не увидит данные
03
Попытка сохранить в реквизит формы несериализуемый тип (например, COMОбъект или запрос с открытым результатом) — форма упадёт при передаче между клиентом и сервером
04
Забытое начальное значение: сравнение с Неопределено без проверки приводит к ложным срабатываниям

Запоминание значения между сеансами: ХранилищеОбщихНастроек

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

&НаСервере

Процедура СохранитьНастройку()

ХранилищеОбщихНастроек.Сохранить(

"МояОбработка", // ключ объекта

"ОсновнойСклад", // ключ настройки

Объект.Склад); // сохраняемое значение

КонецПроцедуры

&НаСервере

Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)

СохраненныйСклад = ХранилищеОбщихНастроек.Загрузить("МояОбработка", "ОсновнойСклад");

Если СохраненныйСклад <> Неопределено Тогда

Объект.Склад = СохраненныйСклад;

КонецЕсли;

КонецПроцедуры

Сохранять настройку логично в обработчике ПередЗакрытием или ПриЗакрытии формы, а загружать — в ПриСозданииНаСервере. Всегда проверяйте загруженное значение на Неопределено: при первом запуске настройки ещё нет.

Порядок действий для запоминания настройки пользователя
  1. 1
    Определите уникальный ключ объекта настроек (имя формы или обработки)
  2. 2
    В ПриСозданииНаСервере загрузите значение через ХранилищеОбщихНастроек.Загрузить
  3. 3
    Проверьте результат на Неопределено и подставьте значение по умолчанию
  4. 4
    В ПриЗакрытии или ПередЗакрытием сохраните текущее значение через ХранилищеОбщихНастроек.Сохранить
  5. 5
    Откройте форму, измените значение, закройте и откройте снова — проверьте восстановление

Параметры формы и передача значений между формами

Если значение нужно «запомнить» в момент открытия другой формы, используйте параметры. В управляемых формах параметры объявляются в редакторе формы на закладке «Параметры», либо передаются динамически через структуру при вызове ОткрытьФорму.

&НаКлиенте

Процедура ОткрытьПодбор(Команда)

ПараметрыФормы = Новый Структура;

ПараметрыФормы.Вставить("ТекущийСклад", Объект.Склад);

ОткрытьФорму("Обработка.ПодборТоваров.Форма", ПараметрыФормы, ЭтаФорма);

КонецПроцедуры

В открываемой форме параметр доступен в ПриСозданииНаСервере через Параметры.ТекущийСклад. Если нужно вернуть результат обратно — используйте ОписаниеОповещения при открытии формы или метод Оповестить.

Длительное хранение: реквизиты объекта, константы, регистры

Когда значение является частью бизнес-данных (а не служебной настройкой интерфейса), его нужно хранить в базе данных, а не на форме. Правильные места:

  • Реквизит объекта — если значение относится к конкретному документу или элементу справочника. Оно сохранится при записи объекта.
  • Константа — единственное значение на всю систему (например, «склад по умолчанию»).
  • Регистр сведений — значения в разрезе измерений: по пользователям, организациям, периодам.

Помните: запись в базу — это транзакция. Не записывайте объект из обработчика ПриИзменении каждого поля — это создаст лишнюю нагрузку и риск блокировок. Записывайте по явному действию пользователя (кнопка «Сохранить», закрытие формы).

Проверка результата и отладка

После внедрения механизма проверьте три сценария: значение сохраняется между серверными вызовами внутри одной открытой формы; значение восстанавливается после закрытия и повторного открытия (если используется хранилище настроек); поведение корректно при первом запуске, когда сохранённого значения ещё нет.

Для отладки удобно выводить текущее состояние через Сообщить() или смотреть значения в табло (Ctrl+Shift+F9 в конфигураторе при остановке в точке останова). Убедитесь, что реквизит формы виден и на клиенте, и на сервере — это подтверждает, что сериализация работает.

Контрольные точки

Как проверить результат

Значение после серверного вызова
Норма

Реквизит формы содержит то же значение, что было установлено на клиенте

Тревожный признак

Значение сброшено — значит, использовалась переменная модуля вместо реквизита

Повторное открытие формы
Норма

Поле заполнено последним сохранённым значением

Тревожный признак

Поле пустое — проверьте ключи Сохранить/Загрузить, они должны совпадать

Первый запуск без настроек
Норма

Подставляется значение по умолчанию, ошибок нет

Тревожный признак

Ошибка или пустое обязательное поле — нет проверки на Неопределено

Часто задаваемые вопросы

Почему переменная модуля формы обнуляется после серверного вызова?

Управляемая форма между серверными вызовами сериализуется и пересоздаётся, поэтому серверный контекст модуля не сохраняется. Для данных, переживающих вызовы, используйте реквизиты формы — платформа переносит их автоматически.

Как запомнить значение поля до его изменения пользователем?

Сохраните исходное значение в служебный реквизит формы при создании формы (ПриСозданииНаСервере) или при получении данных. В обработчике ПриИзменении сравнивайте текущее значение с сохранённым и при необходимости обновляйте сохранённое.

Чем ХранилищеОбщихНастроек отличается от константы?

ХранилищеОбщихНастроек сохраняет значения в разрезе пользователей и предназначено для интерфейсных настроек (последние введённые значения, настройки форм). Константа — единое значение на всю информационную базу, доступное всем пользователям, и относится к бизнес-данным.

Можно ли сохранить в реквизит формы таблицу значений?

Да, реквизит формы может иметь тип «ТаблицаЗначений» с описанными колонками — такие данные корректно переносятся между клиентом и сервером. Избегайте хранения несериализуемых типов: COM-объектов, открытых запросов, потоков.

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

Передайте в ОткрытьФорму описание оповещения (ОписаниеОповещения) и вызовите ВыполнитьОбработкуОповещения из открываемой формы, либо используйте Оповестить() с уникальным именем события и обработчик ОбработкаОповещения в родительской форме.

Итог

Что важно запомнить

Внутри открытой формы значения храните в реквизитах формы — они переживают серверные вызовы. Между сеансами пользователя — в ХранилищеОбщихНастроек. Бизнес-данные — в реквизитах объектов, константах и регистрах. Секреты на форме в открытом виде не храните.