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

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

Данные формы в 1С 8.3: что это и как с ними работать

Что такое данные формы в 1С 8.3: структура реквизитов, ДанныеФормыСтруктура, преобразование объекта в данные формы и обратно, типичные ошибки.

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

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

Материал ориентирован на начинающих разработчиков 1С, которые уже умеют создавать формы в конфигураторе, но путаются в типах ДанныеФормыСтруктура, ДанныеФормыКоллекция и методах преобразования.

Что такое данные формы и зачем они отделены от объектов базы

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

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

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

Структура данных формы: какие типы где используются

Чтобы ориентироваться в данных формы, полезно знать соответствие между тем, что объявлено в конфигураторе, и типом, который получает разработчик в коде.

Что объявлено в конфигуратореТип в данных формыКак обращаться в коде
Основной реквизит — объект (документ, справочник)ДанныеФормыСтруктураОбъект.Номенклатура
Табличная часть объектаДанныеФормыКоллекцияОбъект.Товары[0].Количество
Реквизит формы «ТаблицаЗначений»ДанныеФормыКоллекцияИмяРеквизита.Добавить()
Реквизит формы «ДеревоЗначений»ДанныеФормыДеревоИмяРеквизита.ПолучитьЭлементы()
Реквизит формы «ДинамическийСписок»ДинамическийСписокИмяРеквизита.Отбор
Простой реквизит (число, строка, ссылка)Примитивный тип или ссылкаИмяРеквизита

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

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

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

В модуле формы доступ к данным идёт через реквизиты формы по имени. Если основной реквизит называется «Объект», то поля документа читаются и изменяются напрямую: Объект.Комментарий = "Проверено";. При этом вы работаете не с объектом базы данных, а с данными формы — изменения попадут в базу только после записи.

Для табличных частей используется индексация и обход коллекции. Типичный пример — пересчёт сумм по строкам:

bsl
&НаСервере
Процедура ПересчитатьСуммы()
	Для Каждого СтрокаТовары Из Объект.Товары Цикл
		СтрокаТовары.Сумма = СтрокаТовары.Количество * СтрокаТовары.Цена;
	КонецЦикла;
КонецПроцедуры

На клиенте доступны те же данные формы, но с ограничениями: недоступны серверные методы объектов, запросы и прямое обращение к базе. Поэтому тяжёлую логику принято выносить в серверные процедуры с директивой &НаСервере или &НаСервереБезКонтекста.

Преобразование данных формы в объект и обратно

Главная операция при работе с ДанныеФормыСтруктура — преобразование в прикладной объект и обратно. Для этого существуют два метода формы:

  • РеквизитФормыВЗначение("Объект") — возвращает объект базы данных (например, ДокументОбъект), построенный из данных формы;
  • ЗначениеВРеквизитФормы(ОбъектБазы, "Объект") — помещает объект обратно в данные формы.

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

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

У преобразования есть стоимость: платформа копирует все данные, включая табличные части. На больших документах частые вызовы РеквизитФормыВЗначение заметно замедляют форму. Если нужно только прочитать пару полей, дешевле обратиться к ним напрямую через данные формы без преобразования.

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

Структура данных формы не фиксирована: реквизиты можно добавлять и удалять программно через метод ИзменитьРеквизиты(). Это используется в динамических формах, где набор полей зависит от настроек пользователя или вида объекта.

Порядок действий: сформировать массив добавляемых реквизитов (объекты типа РеквизитФормы с именем, типом и путём), массив удаляемых (строки путей), вызвать ИзменитьРеквизиты(Добавляемые, Удаляемые), затем создать элементы формы для новых реквизитов через Элементы.Добавить().

Порядок действий
  1. 1
    Создайте объект РеквизитФормы: Новый РеквизитФормы("Имя", ОписаниеТипов, "", "Заголовок")
  2. 2
    Соберите добавляемые реквизиты в массив, при необходимости подготовьте массив удаляемых путей
  3. 3
    Вызовите ИзменитьРеквизиты(МассивДобавляемых, МассивУдаляемых) на сервере
  4. 4
    Добавьте элемент формы и свяжите его с реквизитом через ПутьКДанным
  5. 5
    Проверьте результат: реквизит виден в отладчике, элемент отображается на форме

Ограничение: метод ИзменитьРеквизиты доступен только на сервере, и после его вызова форма полностью пересоздаётся на клиенте. Частые изменения состава реквизитов при интерактивной работе пользователя — признак неудачной архитектуры; лучше заранее создать реквизиты в конфигураторе и управлять только видимостью элементов.

Типичные ошибки при работе с данными формы

Типичные ошибки
01
Попытка вызвать метод объекта (например, Записать или Заполнить) у данных формы — возникает ошибка «Метод объекта не обнаружен», потому что ДанныеФормыСтруктура не является прикладным объектом
02
Изменение данных формы в процедуре &НаСервереБезКонтекста через параметр — без контекста формы доступа к реквизитам нет, нужно передавать данные параметрами или работать в контекстной процедуре
03
Многократные вызовы РеквизитФормыВЗначение в цикле — каждый вызов копирует все данные, форма начинает заметно тормозить
04
Обращение к реквизиту по неверному имени после ИзменитьРеквизиты — старый реквизит удалён, код падает с ошибкой «Поле объекта не обнаружено»
05
Ожидание, что изменение данных формы сразу сохранится в базе — данные формы живут только в сеансе, запись выполняется отдельной командой

Ещё одна частая проблема — путаница между Элементы.ИмяПоля.Значение и реквизитом формы. У большинства элементов управляемой формы нет свойства «Значение»: данные хранятся в реквизите, а элемент лишь отображает его через ПутьКДанным. Менять нужно реквизит, а не элемент.

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

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

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

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

Для основного реквизита объекта — ДанныеФормыСтруктура, для табличной части — ДанныеФормыКоллекция

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

Ожидался объект базы данных, но преобразование не выполнялось, либо тип Неопределено из-за неверного имени реквизита

Изменение поля в коде
Норма

Новое значение сразу видно на форме после выполнения процедуры

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

Значение изменено в объекте после РеквизитФормыВЗначение, но на форме старое — пропущен вызов ЗначениеВРеквизитФормы

Запись документа
Норма

После стандартной записи данные в базе совпадают с данными формы

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

В базе устаревшие значения — объект записывался отдельно от формы или изменения делались в копии

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

FAQ: частые вопросы о данных формы в 1С 8.3

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

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

Можно ли передать данные формы в другую форму?

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

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

Если серверная процедура объявлена с директивой &НаСервереБезКонтекста, она не имеет доступа к данным формы, и изменения внутри неё затрагивают только переданные копии. Перенесите логику в контекстную серверную процедуру или верните результат и примените его к реквизитам на клиенте.

Как скопировать данные одной строки табличной части в другую?

Получите строку-источник, добавьте новую строку коллекции и скопируйте значения полей — вручную по полям или через ЗаполнитьЗначенияСвойств(НоваяСтрока, СтрокаИсточник). Учтите, что служебные свойства элемента коллекции (например, идентификатор строки) копировать не нужно: ЗаполнитьЗначенияСвойств переносит только совпадающие по именам поля данных.

Что такое «основной реквизит формы» и как его определить?

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

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

Нет. Чтение полей через данные формы (Объект.Организация, Объект.Товары.Количество()) не требует преобразования и работает быстрее. РеквизитФормыВЗначение нужен только когда требуются объектные методы: Записать, Провести, экспортные процедуры модуля объекта.

Итог

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

Данные формы в 1С 8.3 — сериализуемое представление реквизитов формы, отделённое от объектов базы данных. Основной реквизит объекта имеет тип ДанныеФормыСтруктура, табличные части — ДанныеФормыКоллекция. Для вызова объектных методов используйте РеквизитФормыВЗначение и ЗначениеВРеквизитФормы, для обычного чтения и изменения полей преобразование не требуется. Запись в базу всегда выполняйте штатной командой формы, если нет веских причин для программной записи объекта.