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