а если такое сочетание значений группировок существует, то запись накапливается :
Если в записи не заполнено какое-либо поле группировок, то запись не считается сформированной, не записывается и не участвует в накоплении значений.
Использование граф отбора может существенно убыстрить время формирования запроса, но для того, чтобы воспользоваться графами отбора, запрос должен удовлетворять следующим требованиям:
- в запросе должна быть объявлена переменная, пути которой включены в графу отбора;
- должно быть задано элементарное условие;
- условие должно быть со знаком сравнение "=".
Товар = Регистр.ИмяРегистра.Поле;
Условие(Товар = ВыбТовар); // (+)
Условие(Товар <> ВыбТовар); // (-) не знак =
Условие((Товар) = ВыбТовар); // (-) не элементарное
// условие
где ВыбТовар - внешняя переменная запроса.
У объекта метаданных типа "Запрос" существует метод ИспользоватьГрафуОтбора , который может управлять механизмом выборки данных с использованием графы отбора.
Параметр метода ИспользоватьГрафуОтбора может принимать следующие значения:
"*" - автоматический выбор графы отбора. Если в тексте запроса описаны элементарные условия со знаком "равно", то запрос просматривает переменную, фигурирующую в условии, и пытается найти для неё соответствующую графу отбора, и, если такая переменная найдена, то включается механизм выборки данных с использованием графы отбора. Когда в тексте запроса объявлены несколько условий, удовлетворяющих критериям включения механизма выборки данных с использованием графы отбора, перед запросом встает задача выбора одной единственной графы отбора из списка возможных. Запрос в своих оценках выбора графы отбора ориентируется на количество элементов справочников и перечислений. Для других типов оценка не производится, и, при желании, можно задать графу отбора вручную.
имя графы отбора . Графа отбора задаётся вручную. Если она задана неверно, то тогда при выполнении запроса выведется сообщение: "Нет переменной, удовлетворяющей заданной графе отбора".
" " - отказ от использования графы отбора.
Особенности использования запросов
Метод Выполнить может быть применен к объекту "Запрос" неограниченное количество раз. Приведем тому пример:
Процедура Сформировать()
Перем Запрос, ТекстЗапроса, Таб;
Запрос = СозадтьОбъект("Запрос");
ТекстЗапроса =
"//{{ЗАПРОС(ТекстЗапроса1)
|...
"//}}ЗАПРОС
;
Если Запрос.Выполнить(ТекстЗапроса) = 0 Тогда
Возврат;
КонецЕсли;
// Цикл обработки запроса
...
"//{{ЗАПРОС(ТекстЗапроса2)
|...
"//}}ЗАПРОС
;
Если Запрос.Выполнить(ТекстЗапроса) = 0 Тогда
Возврат;
КонецЕсли;
// Цикл обработки запроса
КонецПроцедуры
При повторном вызове метода Выполнить , объект Запрос инициализирует внутренние структуры, и доступ к переменным, объявленным в предыдущем запросе и выбранным данным становится, не возможен.
Особенности позиционирования >. После формирования выборки, запрос позиционируется на первую запись ("Итого") – в начало выборки, с которой начинается обход выбранных значений. Вернуться в начало выборки, можно двумя способами. В цикле обхода пройти всю выборку до конца;
// Формирование шапки отчета
Таблица.ВывестиСекцию("Шапка|Боковик");
Счётчик = 0;
Пока Запрос.Группировка("Товар") = 1 Цикл
Если Счётчик = 0 Тогда
Пока Запрос.Группировка("Скл") = 1 Цикл
Таблица.ПрисоединитьСекцию("Шапка|Склад");
Счётчик = Счётчик + 1;
КонецЦикла;
КонецЕсли;
КонецЦикла;
// Процесс формирования строки отчета
Пока Запрос.Группировка("Товар") = 1 Цикл
Если Запрос.ЭтоГруппа(1) = 1 Тогда
Таблица.ВывестиСекцию("Группа|Боковик");
Для i = 1 по Счётчик Цикл
КоличествоДляТаблицы = 0;
Таблица.ПрисоединитьСекцию("Группа|Склад");
КонецЦикла;
Иначе
Таблица.ВывестиСекцию("Товар|Боковик");
Пока Запрос.Группировка("Скл") = 1 Цикл
КоличествоДляТаблицы = Запрос.КО;
Таблица.ПрисоединитьСекцию("Товар|Склад");
КонецЦикла;
КонецЕсли;
КонецЦикла;
или воспользоваться методом "Запроса" - ВначалоВыборки:
Таблица.ВывестиСекцию("Шапка|Боковик");
Счётчик = 0;
Пока Запрос.Группировка("Товар") = 1 Цикл
Пока Запрос.Группировка("Скл") = 1 Цикл
Таблица.ПрисоединитьСекцию("Шапка|Склад");
Счётчик = Счётчик + 1;
КонецЦикла;
Если Счётчик > 0 Тогда
прервать;
КонецЕсли;
КонецЦикла;
Запрос.ВНачалоВыборки();
// Процесс формирования строки отчета
Пока Запрос.Группировка("Товар") = 1 Цикл
Если Запрос.ЭтоГруппа(1) = 1 Тогда
Таблица.ВывестиСекцию("Группа|Боковик");
Для i = 1 по Счётчик Цикл
КоличествоДляТаблицы = 0;
Таблица.ПрисоединитьСекцию("Группа|Склад");
КонецЦикла;
Иначе
Таблица.ВывестиСекцию("Товар|Боковик");
Пока Запрос.Группировка("Скл") = 1 Цикл
КоличествоДляТаблицы = Запрос.КО;
Таблица.ПрисоединитьСекцию("Товар|Склад");
КонецЦикла;
КонецЕсли;
КонецЦикла;
Метод ВначалоВыборки можно вызывать на любом уровне вложенности циклов обработки выборки, для перехода в ее начало. Количество обходов выборки ничем не ограничено.
Общие положения написания запросов
Примером неправильной работы с данными в 1С:Предприятиии, есть и остается избыточное обращение к базе данных, вне зависимости от того, в каком формате она хранится.
Как избежать лишних обращений к ИБ, и тем самым существенно уменьшить время формирования отчета проиллюстрируем на примере "Оптимизация Отчета".
Закладка 100%
ТекстЗапроса =
"//{{ЗАПРОС(Сформировать100)
|Период с ВыбНачПериода по ВыбКонПериода;
|Товар = Документ.РасхНакл.Товар;
|Количество = Документ.РасхНакл.Количество;
|Функция КоличествоСумма = Сумма(Количество);
|Группировка Товар;
|Условие(Товар в ВыбТовар);
|Условие(Товар.ВидТовара = ВыбВидТовара);
|"//}}ЗАПРОС
;
При написании текста запроса необходимо учитывать, что Запрос при формировании выборки сам отрабатывает только элементарные условия , не запуская при этом исполнительную среду встроенного языка, что значительно экономит время. Если есть возможность привести условие к элементарному - это необходимо сделать.
"//{{ЗАПРОС(Сформировать15)
|Период с ВыбНачПериода по ВыбКонПериода;
|Товар = Документ.РасхНакл.Товар;
|ВидТовара = Документ.РасхНакл.Товар.ВидТовара;
|Количество = Документ.РасхНакл.Количество;
|Функция КоличествоСумма = Сумма(Количество);
|Группировка Товар;
|Условие(Товар в ВыбТовар);
|Условие(ВидТовара=ВыбВидТовара);
|"//}}ЗАПРОС
;
Так как выборка формируется на компьютере пользователя, то все данные, которые необходимы пользователю для построения отчета, должны быть, по возможности, получены посредством запроса. В таблице выводится значение кода товара – для этого в запросе необходимо ввести переменную КодТовара . Тогда для формирования отчета, отпадет необходимость, каждый раз обращаться к ИБ. Следует не забывать про методы Запроса - ЗначениеУпорядочивания и ЭтоГруппа , которые опять же извлекают данные из выборки, минуя ИБ, что заметно уменьшает время формирования запроса.
"//{{ЗАПРОС(Сформировать3)
|Период с ВыбНачПериода по ВыбКонПериода;
|Товар = Документ.РасхНакл.Товар;
|ВидТовара = Документ.РасхНакл.Товар.ВидТовара;
|КодТовара = Документ.РасхНакл.Товар.Код;
|Количество = Документ.РасхНакл.Количество;
|Функция КоличествоСумма = Сумма(Количество);
|Группировка Товар;
|Условие(Товар в ВыбТовар);
|Условие(ВидТовара=ВыбВидТовара);
|"//}}ЗАПРОС
;
В отчете "Оптимизация Отчета" время выполнение самой медленной версии взято за 100%, остальные версии берутся как процент от нее. Следование правилам, дало возможность уменьшить время выполнения запроса почти на 2 порядка!
Особенности использования запросов для получения информации из справочников
В случае применения объекта "Запрос" для выборки информации из справочников 1С:Предприятия необходимо учитывать следующую особенность. При обработке справочника объект "Запрос" не обрабатывает группы справочника. То есть он не использует их в качестве исходных данных для получения первичной выборки. При обработке уже полученных записей запрос добавляет группы для выбранных записей - элементов, если существует группировка по переменной запроса типа "Справочник". Такой способ обработки является стандартным, и Запрос выполняет ее так же, как он это делает, например, для реквизитов документа имеющих тип "Справочник". То есть, если в запросе по документам использовать группировку по реквизиту "Товар" документа "Счет", то в полученном отчете можно получить записи и по группам товаров, вошедших в запрос. Аналогично, если в запросе по справочнику получать в качестве группировки текущий элемент, то в полученный отчет будут включены записи, соответствующие группам отобранных запросом элементов. Однако так как сами группы не обрабатываются запросом при заполнении таблицы выборки, то в отчет не попадут те группы, которые не имеют элементов, или группы, элементы которых не попали в выборку. Соответственно объект "Запрос" не может применяться в тех случаях, когда нужно обрабатывать собственно группы, или получать все элементы, включая группы. С другой стороны, так как в большинстве случаев должны выбираться непосредственно элементы, запрос может быть успешно применен для обработки справочника. В том числе, Запрос позволяет существенно ускорить выборку элементов по условию, при работе с базой данных в формате SQL.
При обработке с помощью запроса справочников, имеющих периодические реквизиты, следует учитывать, что значения периодических реквизитов выбираются только на конечную границу периода запроса. То есть, с помощью запроса нет возможности получить историю периодических реквизитов, а можно получить только срез значений на определенный момент.