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