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

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

ДанныеФормыСтруктура в 1С: как получить данные формы в виде структуры

Как в 1С получить ДанныеФормыСтруктура: методы ФормаДанныхВЗначение, РеквизитФормыВЗначение, чтение реквизитов формы. Примеры кода, ошибки и FAQ.

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

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

Материал ориентирован на управляемые формы (режим «Такси» и обычные управляемые формы), код приведён на встроенном языке 1С и применим в типовых и самописных конфигурациях.

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

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

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

Как обратиться к полям ДанныеФормыСтруктура напрямую

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

// В модуле формы, основной реквизит называется "Объект"

ЗначениеПоля = Объект.Наименование;

ДатаДокумента = Объект.Дата;

Если данные нужно собрать в обычную структуру 1С для передачи на сервер или в другую процедуру, поля перечисляют явно:

Функция ПолучитьДанныеВСтруктуру()

Результат = Новый Структура;

Результат.Вставить("Наименование", Объект.Наименование);

Результат.Вставить("Дата", Объект.Дата);

Результат.Вставить("Контрагент", Объект.Контрагент);

Возврат Результат;

КонецФункции

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

1c
Результат = Новый Структура;
Результат.Вставить("Наименование", Объект.Наименование);
Результат.Вставить("Дата", Объект.Дата);
Возврат Результат;

Как получить структуру через список реквизитов формы

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

Функция СобратьДанныеФормы()

Результат = Новый Структура;

РеквизитыФормы = ПолучитьРеквизиты("Объект");

Для Каждого Реквизит Из РеквизитыФормы Цикл

Результат.Вставить(Реквизит.Имя, Объект[Реквизит.Имя]);

КонецЦикла;

Возврат Результат;

КонецФункции

Обратите внимание на два момента. Во-первых, параметр метода — путь к родительскому реквизиту: ПолучитьРеквизиты("Объект") вернёт поля основного реквизита, а вызов без параметра — реквизиты верхнего уровня самой формы. Во-вторых, обращение Объект[Реквизит.Имя] через квадратные скобки работает, потому что ДанныеФормыСтруктура поддерживает доступ к полям по строковому имени.

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

Как получить данные формы в структуру
  1. 1
    Определите имя основного реквизита формы (обычно Объект) в дереве реквизитов конфигуратора
  2. 2
    Вызовите ПолучитьРеквизиты с путём к этому реквизиту
  3. 3
    Пройдите циклом по массиву реквизитов и читайте значения через Объект[Имя]
  4. 4
    Сложите значения в Новый Структура и верните из функции
  5. 5
    Проверьте результат в отладчике: состав ключей структуры должен совпадать с полями формы

Преобразование через РеквизитФормыВЗначение и ФормаДанныхВЗначение

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

&НаСервере

Процедура СохранитьДанные()

ОбъектДанных = РеквизитФормыВЗначение("Объект");

ОбъектДанных.Записать();

ЗначениеВРеквизитФормы(ОбъектДанных, "Объект");

КонецПроцедуры

Важное ограничение: РеквизитФормыВЗначение доступен только в серверном контексте (директива &НаСервере), потому что создаёт полноценный объект базы данных. Вызов на клиенте приведёт к ошибке компиляции или выполнения. Для чистой ДанныеФормыСтруктура без привязки к объекту метаданных метод может вернуть структуру или потребовать указания типа — поведение зависит от того, как объявлен реквизит.

Как передать данные формы между клиентом и сервером

Частая задача — собрать данные на клиенте и обработать на сервере. Напрямую передать объект ДанныеФормыСтруктура в серверную процедуру нельзя: объекты формы не сериализуются. Решение — упаковать нужные поля в структуру на клиенте и передать её параметром:

&НаКлиенте

Процедура ОтправитьДанные(Команда)

Пакет = Новый Структура;

Пакет.Вставить("Контрагент", Объект.Контрагент);

Пакет.Вставить("Сумма", Объект.Сумма);

ОбработатьНаСервере(Пакет);

КонецПроцедуры

&НаСервере

Процедура ОбработатьНаСервере(Пакет)

// работа с Пакет.Контрагент и Пакет.Сумма

КонецПроцедуры

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

Сравнение способов получения данных

Прямое чтение полей Объект.Поле

Подходит всегда, работает на клиенте и сервере; ограничение — имена полей нужно знать заранее

Цикл по ПолучитьРеквизиты()

Подходит для универсального сбора всех полей; чуть медленнее и требует аккуратности с путями

РеквизитФормыВЗначение

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

Упаковка в Структуру для передачи

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

Типичные ошибки и ограничения

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

Вторая типичная ситуация — обращение к несуществующему полю. При чтении Объект.ПолеКоторогоНет платформа выбрасывает исключение, а не возвращает Неопределено, как это делает обычная структура. Перед обращением к необязательным полям проверяйте их наличие через ПолучитьРеквизиты или оборачивайте код в попытку.

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

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

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

После сборки структуры убедитесь, что данные получены корректно. В отладчике остановитесь на строке возврата и раскройте переменную: все ожидаемые ключи должны присутствовать, а значения — иметь правильные типы (ссылки для объектов, даты для дат, а не строковые представления).

Для быстрой проверки без отладчика можно вывести состав структуры в сообщение или журнал регистрации, пройдя по ней циклом. Если какого-то ключа нет — проверьте путь, переданный в ПолучитьРеквизиты, и имя основного реквизита формы в конфигураторе.

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

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

Состав ключей структуры
Норма

Все поля формы присутствуют

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

Части ключей нет — неверный путь в ПолучитьРеквизиты

Типы значений
Норма

Ссылки, даты, числа в родных типах

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

Всё строки — данные прочитаны из элементов формы, а не реквизитов

Работа на клиенте и сервере
Норма

Код выполняется в обоих контекстах

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

Ошибка на клиенте — использован серверный метод

FAQ

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

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

Почему РеквизитФормыВЗначение возвращает ошибку для моей формы?

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

Как получить данные табличной части из формы?

Табличная часть представлена типом ДанныеФормыКоллекция. Её можно обойти циклом Для Каждого по строкам, а значения колонок читать по именам через точку или квадратные скобки. Для выгрузки в таблицу значений есть метод Выгрузить() у реквизита на сервере.

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

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

Чем ПолучитьРеквизиты() без параметра отличается от вызова с путём?

Без параметра возвращаются реквизиты верхнего уровня самой формы. С путём, например "Объект", — поля вложенного реквизита. Для сбора данных основного реквизита почти всегда нужен второй вариант.

Итог

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

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