Прямые запросы в 1С++ — это отличный способ в тысячи раз ускорить выборки данных по сравнению со стандартными запросами 1С 7.7. Особенно полезно для крупных баз, свыше 100Гб, где требуется оптимизация. Группировка индексной таблицей — это дополнительные затраты серверного ресурса, и порой долгие минуты ожидания для пользователя. Запросы с использованием ROLLUP позволят получать данные с итогами по группировкам уже в самом запросе.
К примеру, получим остатки.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
ТекстЗапроса = "SELECT |тмц [ТМЦ $Справочник.ТМЦ] |,Партия [Партия $Справочник.Партии] |,GROUPING(ТМЦ) AS ИтогПоТоварам |,GROUPING(Партия) AS ИтогПоПартиям |,MAX(Склад) [Склад $Справочник.Склады] |,MAX($спрТМЦ.БазЕдиница) [БазЕдиница $Перечисление.Единицы] |,sum(КвоОстаток) as количество |FROM |$РегистрОстатки.Остатки(:ДатаПо~ |, |,ВидУчета = :выбВидУчета |,(ТМЦ,Партия,Склад)) AS ОстаткиТМЦ |LEFT JOIN $Справочник.ТМЦ AS спрТМЦ |ON ОстаткиТМЦ.ТМЦ = спрТМЦ.ID |group BY ТМЦ,Партия WITH ROLLUP |HAVING SUM(КвоОстаток) > 0 |ORDER BY ТМЦ,Партия,MAX(Склад), SUM(КвоОстаток) DESC"; |
Как видно из запроса, мы создаем две группы: ТМЦ и Партия.
Теперь поля приобртают значение в зависимости от уровня группировки: ИтогПоТоварам =1 и ИтогПоПартиям = 1 , — это общий итог.
ИтогПоТоварам =0 и ИтогПоПартиям = 1 , когда попадаем на строку с итогом по товару, куда «всуммировались» и итоги по каждой партии отдельно
ИтогПоТоварам =0 и ИтогПоПартиям = 0 , когда попадаем на строку с итогом по партии, который в свою очередь находится внутри итога по товару. Они же детальные строки.
Как можно использовать это?
Смотрим пример обхода результата выборки.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
Запрос.УстановитьТекстовыйПараметр("ДатаПо",ДатаПо); Запрос.УстановитьТекстовыйПараметр("выбВидУчета",выбВидУчета); тз = Запрос.ВыполнитьИнструкцию(ТекстЗапроса); //тз.выбратьСтроку(); ТабДок = СоздатьОбъект("Таблица"); КолВоСтрок = тз.КоличествоСтрок(); табДок = СоздатьОбъект("таблица") ; табДок.ИсходнаяТаблица("таблица"); ..... тз.ВыбратьСтроки(); нппТовар = 1; нппПартия=1; Пока тз.ПолучитьСтроку()=1 Цикл Если (тз.ИтогПоТоварам=1) И (тз.ИтогПоПартиям=1) Тогда Количество = тз.Количество; ТабДок.ВывестиСекцию ("Итого"); нппПартия=1; ИначеЕсли (тз.ИтогПоТоварам=0) И (тз.ИтогПоПартиям=1) Тогда ТМЦ = тз.ТМЦ; Количество = тз.Количество; ТабДок.ВывестиСекцию ("СтрокаТовара"); нппТовар=нппТовар+1; нппПартия=1; ИначеЕсли тз.ИтогПоПартиям=0 тогда Партия = тз.Партия; Количество = тз.Количество; Склад = ТЗ.Склад; БазЕдиница = ТЗ.БазЕдиница; ТабДок.ВывестиСекцию ("СтрокаПартии"); нппПартия=нппПартия+1; КонецЕсли; нпп=нпп+1; проц = Окр(нпп/КолВоСтрок*100,1,1); Состояние ("Вывод отчета "+Строка(проц)+"%"); КонецЦикла; |
Ну и результат, привычно для отчетов, которые любят в 1С 8.х — когда итоги размещаются сверху групп, их не надо суммировать в переменные, или группировать в индексированной таблице. Всё выводится очень быстро и естественно.
Желаю удачи!