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