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