Как получить результаты всех запросов из пакета в 1С и в чем смысл такого подхода?

Программист 1С v8.3 (Управляемые формы) Бухгалтерский учет IT и автоматизация бизнеса
← На главную

При написании программного кода на платформе 1С разработчики нередко сталкиваются с ситуацией, когда в одном тексте запроса через точку с запятой объединяются несколько независимых инструкций ВЫБРАТЬ без создания временных таблиц. У начинающих специалистов возникает закономерный вопрос: зачем формировать такой пакет, если при обычном вызове возвращаются данные только последнего запроса? Разберем эту тему подробно, выясним особенности платформы и рассмотрим правильные методы работы с результатами пакетов запросов.

Причина заблуждения: отличие методов Выполнить и ВыполнитьПакет

Проанализируем стандартное поведение платформы при вызове метода Выполнить() у объекта Запрос. Когда выполняется пакетный запрос, метод Выполнить() действительно возвращает объект РезультатЗапроса, содержащий выборку только последнего запроса из пакета. Из-за этого может сложиться ошибочное впечатление, что все предыдущие конструкции ВЫБРАТЬ бессмысленны, если они не помещают данные во временные таблицы с помощью конструкции ПОМЕСТИТЬ.

Однако встроенный язык 1С предоставляет специальный метод для обработки таких сценариев — ВыполнитьПакет(). Посмотрим на различия в обработке:

  1. Метод Выполнить(): исполняет весь пакет на сервере СУБД, но возвращает разработчику только последний результат.
  2. Метод ВыполнитьПакет(): исполняет весь пакет и возвращает Массив объектов РезультатЗапроса. Каждый элемент массива строго соответствует очередному запросу в тексте пакета, начиная с индекса 0.
  3. Метод ВыполнитьПакетСПромежуточнымиДанными(): возвращает результаты абсолютно всех запросов пакета, включая создание и наполнение временных таблиц, что особенно удобно при отладке.

Практический пример работы с методом ВыполнитьПакет()

Рассмотрим конкретный пример запроса, в котором требуется за одно обращение получить остатки по двум разным счетам плана счетов:


Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |	ХозрасчетныйОстатки.СуммаОстатокКт КАК СуммаОстатокКт
    |ИЗ
    |	РегистрБухгалтерии.Хозрасчетный.Остатки(&НаДату, Счет = ЗНАЧЕНИЕ(ПланСчетов.Хозрасчетный.Нач), , Фирма = &Фирма) КАК ХозрасчетныйОстатки
    |;
    |////////////////////////////////////////////////////////////////////////////////
    |ВЫБРАТЬ
    |	ХозрасчетныйОстатки.СуммаОстатокКт КАК СуммаОстатокКт
    |ИЗ
    |	РегистрБухгалтерии.Хозрасчетный.Остатки(&НаДату, Счет = ЗНАЧЕНИЕ(ПланСчетов.Хозрасчетный.ПредстоящиеОбязательсваПоМедстраху), , Фирма = &Фирма) КАК ХозрасчетныйОстатки";

Запрос.УстановитьПараметр("НаДату", Период);
Запрос.УстановитьПараметр("Фирма", Организация);

// Получаем массив результатов
МассивРезультатов = Запрос.ВыполнитьПакет();

// Обрабатываем выборку первого запроса (индекс 0)
ВыборкаПервая = МассивРезультатов[0].Выбрать();
Если ВыборкаПервая.Следующий() Тогда
    СуммаНач = ВыборкаПервая.СуммаОстатокКт;
КонецЕсли;

// Обрабатываем выборку второго запроса (индекс 1)
ВыборкаВторая = МассивРезультатов[1].Выбрать();
Если ВыборкаВторая.Следующий() Тогда
    СуммаМедстрах = ВыборкаВторая.СуммаОстатокКт;
КонецЕсли;

Как видим из примера, мы получаем доступ ко всем выборкам в пакете по их индексам и можем обрабатывать каждую независимо.

Преимущества использования пакетов запросов

Разберем, почему объединение нескольких запросов в один пакет является хорошей практикой:

  1. Сокращение сетевых задержек (Round-trip): отправка единого пакета запросов выполняет одно обращение между сервером 1С и СУБД, вместо выполнения нескольких последовательных запросов по отдельности. Это существенно повышает общую производительность системы при частых операциях.
  2. Единый контекст и транзакционность: запросы пакета обрабатываются СУБД в рамках единого сеанса взаимодействия, что исключает рассинхронизацию данных между вызовами.
  3. Компактность кода: параметры запроса (например, &НаДату и &Фирма) устанавливаются один раз для всего объекта Запрос, а не дублируются для нескольких экземпляров.

Альтернативные способы получения аналогичных данных

Если бизнес-логика не требует разделения данных на две независимые таблицы, аналогичные остатки можно получить и другими путями:

  1. Запрос с отбором по списку счетов: передать несколько счетов через условие Счет В (&СписокСчетов) и сгруппировать результат по полю Счет.
  2. Объединение выборок: использовать оператор ОБЪЕДИНИТЬ ВСЕ, если структуры колонок идентичны, добавив текстовое поле-признак для различения строк.

Таким образом, пакет запросов с несколькими инструкциями ВЫБРАТЬ является мощным и эффективным инструментом, если для его выполнения используется метод ВыполнитьПакет().

← На главную