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

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

ДанныеФормыСтруктура в 1С: назначение и практика работы

Что такое ДанныеФормыСтруктура в 1С 8.3, как получить объект из данных формы, изменить и вернуть обратно. Примеры кода, типичные ошибки и отличия от других типов данных формы.

ДанныеФормыСтруктура — это универсальный тип данных управляемой формы в 1С:Предприятие 8.3, который платформа использует для представления в форме прикладных объектов: элементов справочников, документов, записей регистров и других сущностей. Когда вы открываете карточку контрагента или документ, реквизит формы «Объект» на сервере хранится именно как ДанныеФормыСтруктура, хотя в отладчике вы видите знакомые поля — Ссылка, Наименование, табличные части.

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

Материал ориентирован на разработчиков и продвинутых внедренцев, работающих с управляемыми формами в типовых и самописных конфигурациях. Рассматриваются практические приёмы: преобразование данных формы в объект и обратно, обход ограничений клиент-серверного взаимодействия, типичные ошибки и способы их диагностики.

Что представляет собой ДанныеФормыСтруктура и где встречается

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

Увидеть тип можно в отладчике: остановитесь в серверной процедуре модуля формы и посмотрите значение выражения ТипЗнч(Объект) или ТипЗнч(ЭтаФорма.Объект). Для формы элемента справочника вы увидите «ДанныеФормыСтруктура». При этом обращение к полям выглядит привычно: Объект.Наименование, Объект.Ссылка, Объект.Товары — табличная часть вернёт ДанныеФормыКоллекция.

Важное следствие: ДанныеФормыСтруктура — не то же самое, что обычная Структура. У неё есть связь с метаданными объекта, она поддерживает обращение к табличным частям и стандартным реквизитам, и у неё есть «хозяин» — реквизит формы. Произвольно создать ДанныеФормыСтруктура кодом нельзя, её формирует платформа при создании формы.

Чем ДанныеФормыСтруктура отличается от объекта и от структуры

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

КритерийДанныеФормыСтруктураСправочникОбъект / ДокументОбъектСтруктура
Запись в базуНетДа, метод Записать()Нет
Связь с метаданнымиДаДаНет
Табличные частиДа, как ДанныеФормыКоллекцияДаНет, только вложенные массивы/структуры
Существует вне формыНетДаДа
События объекта (ПередЗаписью)НетДаНет

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

Как получить объект из данных формы и вернуть изменения обратно

Стандартный сценарий модификации объекта из формы выглядит так: на сервере вы вызываете метод формы РеквизитФормыВЗначение("Объект"), получаете настоящий объект, меняете его, записываете, а затем при необходимости обновляете форму через ЗначениеВРеквизитФормы(ОбъектСсылка.ПолучитьОбъект(), "Объект") или просто Прочитать().

bsl
&НаСервере
Процедура ЗаполнитьНаименованиеНаСервере()
    ОбъектДанные = РеквизитФормыВЗначение("Объект");
    ОбъектДанные.Наименование = СокрЛП(ОбъектДанные.Наименование);
    ОбъектДанные.Записать();
    ЗначениеВРеквизитФормы(ОбъектДанные, "Объект");
КонецПроцедуры

Обратите внимание на порядок: сначала преобразование, потом изменение, потом запись, потом возврат в форму. Если пропустить последний шаг, пользователь увидит в форме старые данные, хотя в базе они уже изменились. Альтернатива ЗначениеВРеквизитФормы — вызов ЭтаФорма.Прочитать(), который перечитывает объект из базы целиком; это проще, но сбрасывает несохранённые изменения, внесённые пользователем в другие поля.

Порядок действий
  1. 1
    В серверной процедуре формы вызовите РеквизитФормыВЗначение("Объект") и сохраните результат в переменную
  2. 2
    Внесите нужные изменения в полученный объект (реквизиты, табличные части)
  3. 3
    Вызовите Записать() у объекта и при необходимости обработайте исключения
  4. 4
    Верните данные в форму через ЗначениеВРеквизитФормы() или Прочитать()
  5. 5
    Проверьте в интерфейсе, что поля формы отображают актуальные значения

Работа с табличными частями и вложенными коллекциями

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

Безопасный приём — передавать на сервер только идентификаторы строк или простые значения, а всю обработку коллекции выполнять в серверном контексте. Если нужно перенести табличную часть в другое место (например, в хранилище или в другую форму), выгрузите её в таблицу значений: данные формы поддерживают метод Выгрузить() у коллекций, а дальше таблицу значений можно сериализовать через ЗначениеВСтрокуВнутр().

Типичные ошибки и как их диагностировать

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

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

Типичные ошибки
01
Передача Объект или Объект.Товары параметром в серверную процедуру — ошибка о мутабельном значении; передавайте ссылку или примитивы
02
Попытка вызвать Объект.Записать() прямо в форме — у ДанныеФормыСтруктура нет такого метода; нужен РеквизитФормыВЗначение
03
Изменение объекта без возврата в форму — пользователь видит устаревшие данные и перезаписывает изменения при сохранении
04
Использование Прочитать() при несохранённых правках пользователя — введённые данные теряются без предупреждения

Когда использовать данные формы, а когда — объект напрямую

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

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

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

Нужно только отобразить данные и дать пользователю редактировать поля формыРаботайте с ДанныеФормыСтруктура напрямую, без преобразований
Нужно записать изменения в базу из кода формыПреобразуйте через РеквизитФормыВЗначение, измените объект, запишите, верните через ЗначениеВРеквизитФормы
Обработка выполняется в общем модуле или фоновом заданииФормы там нет — получайте объект через Ссылка.ПолучитьОбъект()
Нужно передать данные формы на сервер из клиентской процедурыПередавайте ссылку или примитивные значения, объект получайте на сервере заново

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

Проверка результата и контрольные точки

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

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

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

Тип реквизита в отладчике
Норма

ТипЗнч(Объект) возвращает ДанныеФормыСтруктура в контексте формы

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

Тип Неопределено или Строка — реквизит формы настроен неверно

Данные после записи
Норма

После ЗначениеВРеквизитФормы поля формы показывают новые значения

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

На экране старые данные — возврат в форму не выполнен

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

Изменения видны после закрытия и открытия формы

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

Изменения пропали — объект не был записан, менялись только данные формы

Клиент-серверные вызовы
Норма

Серверные процедуры получают только ссылки и примитивы

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

Ошибка о мутабельном значении при вызове с клиента

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

Частые вопросы о ДанныеФормыСтруктура

Можно ли создать ДанныеФормыСтруктура программно, без формы?

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

Почему Объект.Записать() в модуле формы выдаёт ошибку?

Потому что Объект в форме — это ДанныеФормыСтруктура, у которой нет метода Записать(). Сначала выполните РеквизитФормыВЗначение("Объект") в серверной процедуре — полученный объект будет иметь метод Записать().

Чем ДанныеФормыСтруктура отличается от ДанныеФормыКоллекция?

ДанныеФормыСтруктура описывает один объект с именованными полями (карточка элемента, документ). ДанныеФормыКоллекция — это список строк: табличная часть или динамический список. Внутри структуры табличная часть хранится именно как коллекция.

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

Напрямую передать ДанныеФормыСтруктура нельзя. Передайте ссылку на объект, либо выгрузите табличные части в таблицу значений и поместите её во временное хранилище (ПоместитьВоВременноеХранилище), передав адрес хранилища.

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

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

Что делать с ошибкой «мутабельное значение» при вызове сервера?

Уберите из параметров серверной процедуры Объект и его табличные части. Передавайте ссылку (Объект.Ссылка), идентификаторы строк или простые значения, а объект на сервере получайте заново через ПолучитьОбъект() или РеквизитФормыВЗначение в контексте формы.

Итог

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

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