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