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