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