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