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