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

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

Чем отличается реквизит формы от реквизита объекта в 1С

Разбираем разницу между реквизитом формы и реквизитом объекта в 1С: где хранятся данные, время жизни, типичные ошибки разработчиков и примеры кода.

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

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

Что такое реквизит объекта и где он хранится

Реквизит объекта создаётся в конфигураторе на закладке «Данные» соответствующего объекта метаданных: справочника, документа, плана видов характеристик, регистра и т. д. Платформа автоматически создаёт под такой реквизит поле в таблице базы данных. Значение реквизита привязано к конкретному экземпляру объекта — например, реквизит «ОсновнойДоговор» у конкретного контрагента.

Ключевые свойства реквизита объекта:

  • хранится в базе данных и доступен из любого сеанса, отчёта, запроса;
  • участвует в обменах данными, выгрузках, печатных формах;
  • изменение состава реквизитов требует обновления конфигурации базы данных;
  • доступен в запросах напрямую по имени, например Справочник.Контрагенты.ОсновнойДоговор.

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

Что такое реквизит формы и когда он существует

Реквизит формы — это переменная данных формы, объявленная в редакторе формы (панель «Реквизиты») или программно методом ИзменитьРеквизиты(). Он живёт в памяти сервера или толстого клиента, пока форма открыта. После закрытия формы значение безвозвратно теряется, если разработчик не позаботился о сохранении.

Когда пользователь открывает форму элемента справочника, платформа автоматически создаёт главный реквизит формы типа «ДанныеФормыСтруктура» с именем «Объект» — в нём и находятся реквизиты объекта. Все остальные реквизиты формы (счётчики, признаки, временные таблицы значений, промежуточные итоги) — это самостоятельные данные, к объекту отношения не имеющие.

Типичные задачи, для которых реквизит формы — правильный выбор:

  • признак «форма изменена вручную» для управления доступностью кнопок;
  • временная таблица значений для подбора товаров до переноса в табличную часть;
  • текущее значение отбора динамического списка, не требующее хранения;
  • счётчик попыток, флаг режима редактирования, промежуточные суммы.

Сравнение по ключевым параметрам

ПараметрРеквизит объектаРеквизит формы
Где объявляетсяВ метаданных объекта (конфигуратор)В редакторе формы или программно
ХранениеВ таблице базы данныхВ памяти, пока открыта форма
Время жизниПостоянно, пока существует объектДо закрытия формы
Доступ из запросов и отчётовДа, напрямуюНет
Доступ из других форм и сеансовДа, через ссылку на объектНет
Изменение составаТребует обновления конфигурации БДИзменяется только форма, база не затрагивается
Участие в обменах и синхронизацииДаНет

Как обращаться к реквизитам в коде формы

Главная практическая сложность — синтаксис обращения. Реквизит формы доступен в модуле формы напрямую по имени, потому что контекст формы включает её реквизиты: достаточно написать РежимРедактирования = Истина;. Реквизит объекта, лежащий внутри главного реквизита «Объект», доступен либо через Объект.Наименование, либо тоже напрямую — платформа поддерживает такое «прозрачное» обращение в управляемых формах, что и порождает путаницу.

Проблема возникает при переносе кода между контекстами. В модуле объекта или в серверной процедуре общего модуля обращение Объект.Наименование не сработает — там нужно получить объект вызовом ПолучитьОбъект() по ссылке. А в модуле формы прямое обращение к реквизиту объекта без префикса может неожиданно пересечься с одноимённым реквизитом формы.

bsl
&НаСервере
Процедура ЗаписатьДопДанные()
    // Реквизит формы - просто по имени
    ПризнакИзменен = Истина;
    // Реквизит объекта - через главный реквизит формы
    Объект.Комментарий = "Проверено";
    // Преобразование реквизита формы в объект для записи
    ТекущийОбъект = РеквизитФормыВЗначение("Объект");
    ТекущийОбъект.Записать();
КонецПроцедуры

Методы РеквизитФормыВЗначение() и ЗначениеВРеквизитФормы() — мост между миром форм и миром объектов. Первый преобразует данные формы в прикладной объект, с которым можно работать привычными методами (запись, проведение), второй загружает данные объекта обратно в форму. Без этих преобразований на сервере управляемой формы объект записать нельзя.

Типичные ошибки и их последствия

Типичные ошибки
01
Добавление служебного поля как реквизита объекта: структура базы раздувается, появляются конфликты при обновлении типовой конфигурации, хотя данные нужны только на форме.
02
Хранение важных данных в реквизите формы: при закрытии формы или перезапуске сеанса значения теряются, пользователи жалуются на «исчезающие» данные.
03
Обращение к реквизиту формы из серверной процедуры вне контекста формы: ошибка «Переменная не определена», потому что реквизит формы существует только внутри формы.
04
Ожидание, что реквизит формы виден в запросе или отчёте: запросы работают только с данными базы, реквизиты формы туда не попадают.
05
Запись объекта через РеквизитФормыВЗначение без возврата данных в форму: на экране остаются устаревшие значения, пользователь видит рассинхронизацию.

Отдельный класс проблем — попытка использовать реквизит формы там, где нужен реквизит объекта. Например, разработчик добавляет на форму документа поле «Согласовал» как реквизит формы. Пока форма открыта, всё работает. Но после записи и закрытия документа информация о согласовании исчезает, построить по ней отчёт невозможно, а в списке документов её не вывести.

Обратная ошибка — добавление в объект реквизитов «для интерфейса»: текущий шаг мастера, временный пароль, признак развёрнутой группы. Такие поля засоряют базу, попадают в обмены и выгрузки, увеличивают таблицы и создают лишние вопросы при обновлении.

Как выбрать: реквизит объекта или реквизит формы

Маршрут решения

Как выбрать действие

Значение должно сохраняться после закрытия формы и быть доступно в отчётах, запросах, обменахСоздавайте реквизит объекта в метаданных или используйте дополнительные реквизиты/сведения
Значение нужно только для логики открытой формы: отборы, флаги, временные таблицыСоздавайте реквизит формы — база данных не изменится
Данные относятся к объекту, но конфигурация типовая и на поддержкеИспользуйте механизм дополнительных реквизитов и сведений вместо изменения метаданных
Нужна временная таблица для подбора или промежуточного расчётаРеквизит формы типа ТаблицаЗначений, перенос в табличную часть только по команде пользователя

Простой критерий: задайте вопрос «потеряется ли что-то важное, если форму закрыть прямо сейчас?». Если да — данным место в объекте. Если нет, и значение можно вычислить или ввести заново — это кандидат в реквизиты формы.

Второй критерий — аудитория данных. Реквизит объекта виден всем: другим пользователям, отчётам, обменам, регламентным заданиям. Реквизит формы — только коду этой конкретной формы в этом конкретном сеансе. Если хотя бы один сценарий требует доступа к данным вне формы, выбор очевиден.

Как проверить, что выбор сделан правильно

После внедрения изменений пройдите базовый сценарий проверки: введите значение, запишите объект, закройте форму, откройте объект заново. Если значение на месте — хранение организовано корректно. Дополнительно проверьте доступность данных вне формы: постройте простой отчёт или выполните запрос в консоли запросов.

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

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

Значение после переоткрытия формы
Норма

Данные реквизита объекта восстановлены из базы

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

Поле пустое — вероятно, данные хранились в реквизите формы

Доступность в запросе/отчёте
Норма

Поле выбирается в конструкторе запроса

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

Поля нет в метаданных — это реквизит формы

Поведение при записи
Норма

После Записать() данные формы и объекта синхронны

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

На форме старые значения — забыли ЗначениеВРеквизитФормы()

При отладке удобно смотреть состав реквизитов формы через «Ещё → Изменить форму» или в конфигураторе: если поле есть в дереве элементов, но его нет в списке реквизитов объекта в метаданных — это реквизит формы, и ждать его в базе бессмысленно.
ПЗ
Практическое замечание

Ответы на частые вопросы

Почему в модуле формы реквизит объекта доступен без префикса «Объект.»?

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

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

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

Чем реквизит формы отличается от переменной модуля формы?

Переменная модуля существует только на той стороне, где объявлена (клиент или сервер вызова), и теряется при каждом серверном вызове в управляемой форме, если не объявлена с директивой контекста. Реквизит формы переживает серверные вызовы, может быть связан с элементами формы и отображаться пользователю.

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

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

Что быстрее: чтение реквизита объекта через форму или через запрос?

Внутри открытой формы данные объекта уже загружены в реквизит формы «Объект», и чтение мгновенно. Запрос имеет смысл, когда нужны данные других объектов или агрегаты по множеству записей. Делать запрос ради полей уже открытого объекта — лишнее обращение к базе.

Нужно ли обновлять конфигурацию базы данных при добавлении реквизита формы?

Нет. Реквизит формы — часть формы, а не структуры данных. Достаточно обновить конфигурацию без реструктуризации (или динамически, если изменения касаются только форм). Обновление структуры базы требуется только при изменении реквизитов объектов метаданных.

Итог

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

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