Примеры работы с пакетными запросами

Примеры работы с пакетными запросами на языке программирования 1С:Предприятие. Примеры позволяют быстро разобраться в вопросе и использовать код в своих разработках

Базовый пакетный запрос с параметрами

// Пакетный запрос: выполнение нескольких запросов в одном пакете
Процедура ВыполнитьПакетныйЗапрос()

    Пакет = Новый ПакетЗапросов;
    
    // Добавляем первый запрос
    Запрос1 = Пакет.Добавить("ВЫБРАТЬ КОЛИЧЕСТВО(*) КАК КолИЗ Справочник.Номенклатура");
    
    // Добавляем второй запрос
    Запрос2 = Пакет.Добавить("ВЫБРАТЬ КОЛИЧЕСТВО(*) КАК КолИЗ Справочник.Контрагенты");
    
    // Добавляем третий запрос
    Запрос3 = Пакет.Добавить("ВЫБРАТЬ СУММА(Сумма) КАК ОбщаяСумма ИЗ Документ.РеализацияТоваров");
    
    // Выполняем пакет
    Результаты = Пакет.Выполнить();
    
    // Получаем результаты
    Выборка1 = Результаты[0].Выбрать();
    Выборка1.Следующий();
    Сообщить("Количество номенклатуры: " + Выборка1.Кол);
    
    Выборка2 = Результаты[1].Выбрать();
    Выборка2.Следующий();
    Сообщить("Количество контрагентов: " + Выборка2.Кол);
    
    Выборка3 = Результаты[2].Выбрать();
    Выборка3.Следующий();
    Сообщить("Общая сумма реализации: " + Выборка3.ОбщаяСумма);
    
КонецПроцедуры

Пакетный запрос с использованием временных таблиц

// Пакетные запросы с обменом данными через временные таблицы
Процедура ПакетныйЗапросСВременнымиТаблицами()

    Пакет = Новый ПакетЗапросов;
    Пакет.МенеджерВременныхТаблиц = Новый МенеджерВременныхТаблиц;
    
    // Запрос 1: создаем временную таблицу дорогих товаров
    Пакет.Добавить("
    |ВЫБРАТЬ
    |   Номенклатура.Ссылка КАК Товар,
    |   Номенклатура.Наименование КАК Наименование,
    |   Номенклатура.Цена КАК Цена
    |ПОМЕСТИТЬ ВТ_ДорогиеТовары
    |ИЗ
    |   Справочник.Номенклатура КАК Номенклатура
    |ГДЕ
    |   Номенклатура.Цена > 10000");
    
    // Запрос 2: используем временную таблицу для анализа продаж
    Пакет.Добавить("
    |ВЫБРАТЬ
    |   ВТ_ДорогиеТовары.Наименование,
    |   ВТ_ДорогиеТовары.Цена,
    |   СУММА(Продажи.Сумма) КАК СуммаПродаж
    |ИЗ
    |   ВТ_ДорогиеТовары КАК ВТ_ДорогиеТовары
    |       ЛЕВОЕ СОЕДИНЕНИЕ Документ.РеализацияТоваров.Товары КАК Продажи
    |       ПО ВТ_ДорогиеТовары.Товар = Продажи.Номенклатура
    |СГРУППИРОВАТЬ ПО
    |   ВТ_ДорогиеТовары.Наименование,
    |   ВТ_ДорогиеТовары.Цена");
    
    // Запрос 3: итоговый отчет
    Пакет.Добавить("
    |ВЫБРАТЬ
    |   СУММА(СуммаПродаж) КАК ИтоговаяСумма,
    |   КОЛИЧЕСТВО(*) КАК КоличествоТоваров
    |ИЗ
    |   ВТ_ДорогиеТовары");
    
    Результаты = Пакет.Выполнить();
    
    // Выводим результат второго запроса
    Выборка2 = Результаты[1].Выбрать();
    Сообщить("Продажи дорогих товаров:");
    Пока Выборка2.Следующий() Цикл
        Сообщить(Выборка2.Наименование + " (цена " + Выборка2.Цена + "): продано на " + Выборка2.СуммаПродаж);
    КонецЦикла;
    
    // Выводим итог
    Выборка3 = Результаты[2].Выбрать();
    Выборка3.Следующий();
    Сообщить("Итого по дорогим товарам: " + Выборка3.КоличествоТоваров + 
             " товаров на сумму " + Выборка3.ИтоговаяСумма);
    
КонецПроцедуры

Динамическое построение пакетного запроса

// Построение пакетного запроса на основе массива условий
Функция ПостроитьПакетныйЗапросПоМассиву(МассивНоменклатуры)

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

// Пример использования
Процедура ПолучитьОстаткиПоСпискуТоваров()

    // Подготавливаем массив товаров
    МассивТоваров = Новый Массив;
    МассивТоваров.Добавить(Справочники.Номенклатура.НайтиПоНаименованию("Ноутбук"));
    МассивТоваров.Добавить(Справочники.Номенклатура.НайтиПоНаименованию("Монитор"));
    МассивТоваров.Добавить(Справочники.Номенклатура.НайтиПоНаименованию("Клавиатура"));
    
    // Создаем и выполняем пакет
    Пакет = ПостроитьПакетныйЗапросПоМассиву(МассивТоваров);
    
    // Устанавливаем общие параметры для всех запросов пакета
    Пакет.УстановитьПараметр("ДатаОтчета", ТекущаяДата());
    
    Результаты = Пакет.Выполнить();
    
    // Обрабатываем результаты
    Для Инд = 0 По Результаты.Количество() - 1 Цикл
        Выборка = Результаты[Инд].Выбрать();
        Пока Выборка.Следующий() Цикл
            Сообщить("Товар: " + Выборка.Товар + ", остаток: " + Выборка.Остаток);
        КонецЦикла;
    КонецЦикла;
    
КонецПроцедуры

Пакетный запрос с условным выполнением

// Выполнение разных запросов в пакете в зависимости от условий
Процедура ПакетныйЗапросСУсловиями()

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

Пакетный запрос с обработкой ошибок

// Выполнение пакетного запроса с изоляцией ошибок
Функция ВыполнитьПакетныйЗапросБезопасно(Пакет)

    Результаты = Новый Массив;
    Ошибки = Новый Массив;
    
    Для Инд = 0 По Пакет.Количество() - 1 Цикл
        
        // Создаем отдельный пакет для каждого запроса
        ВременныйПакет = Новый ПакетЗапросов;
        Запрос = Пакет.Получить(Инд);
        
        // Копируем менеджер временных таблиц, если есть
        Если Пакет.МенеджерВременныхТаблиц <> Неопределено Тогда
            ВременныйПакет.МенеджерВременныхТаблиц = Пакет.МенеджерВременныхТаблиц;
        КонецЕсли;
        
        // Копируем текст запроса и параметры
        ДобавленныйЗапрос = ВременныйПакет.Добавить(Запрос.Текст);
        Для Каждого Парам Из Запрос.Параметры Цикл
            ДобавленныйЗапрос.УстановитьПараметр(Парам.Ключ, Парам.Значение);
        КонецЦикла;
        
        Попытка
            Результат = ВременныйПакет.Выполнить();
            Результаты.Добавить(Результат[0]);
            Ошибки.Добавить(Неопределено);
        Исключение
            Результаты.Добавить(Неопределено);
            Ошибки.Добавить(ОписаниеОшибки());
        КонецПопытки;
        
    КонецЦикла;
    
    // Формируем результат
    СтруктураРезультата = Новый Структура;
    СтруктураРезультата.Вставить("Результаты", Результаты);
    СтруктураРезультата.Вставить("Ошибки", Ошибки);
    СтруктураРезультата.Вставить("УспешноВыполнено", 
        Результаты.Найти(Неопределено) = Неопределено ? Результаты.Количество() : 
        Массив.Количество(Результаты, Неопределено, Истина));
    
    Возврат СтруктураРезультата;
    
КонецФункции

// Пример использования
Процедура ТестБезопасногоПакета()

    Пакет = Новый ПакетЗапросов;
    
    // Корректный запрос
    Пакет.Добавить("ВЫБРАТЬ ПЕРВЫЕ 5 * ИЗ Справочник.Номенклатура");
    
    // Ошибочный запрос (несуществующая таблица)
    Пакет.Добавить("ВЫБРАТЬ * ИЗ НесуществующийСправочник");
    
    // Корректный запрос
    Пакет.Добавить("ВЫБРАТЬ КОЛИЧЕСТВО(*) КАК КолИЗ Справочник.Контрагенты");
    
    Результат = ВыполнитьПакетныйЗапросБезопасно(Пакет);
    
    Сообщить("Успешно выполнено: " + Результат.УспешноВыполнено + 
             " из " + Строка(Пакет.Количество()));
    
    Для Инд = 0 По Результат.Результаты.Количество() - 1 Цикл
        Если Результат.Ошибки[Инд] <> Неопределено Тогда
            Сообщить("Ошибка в запросе " + Строка(Инд) + ": " + Результат.Ошибки[Инд]);
        Иначе
            Сообщить("Запрос " + Строка(Инд) + " выполнен успешно");
        КонецЕсли;
    КонецЦикла;
    
КонецПроцедуры

Пакетный запрос с итоговыми агрегациями

// Использование пакетных запросов для многоуровневой агрегации
Процедура МногоуровневаяАгрегация()

    Пакет = Новый ПакетЗапросов;
    Пакет.МенеджерВременныхТаблиц = Новый МенеджерВременныхТаблиц;
    
    // Уровень 1: продажи по дням
    Пакет.Добавить("
    |ВЫБРАТЬ
    |   ВЫРАЗИТЬ(Продажи.Период КАК ДАТА) КАК Дата,
    |   СУММА(Продажи.Сумма) КАК СуммаДня
    |ПОМЕСТИТЬ ВТ_ПродажиПоДням
    |ИЗ
    |   Документ.РеализацияТоваров КАК Продажи
    |ГДЕ
    |   Продажи.Период МЕЖДУ &ДатаНачала И &ДатаОкончания
    |СГРУППИРОВАТЬ ПО
    |   ВЫРАЗИТЬ(Продажи.Период КАК ДАТА)");
    
    // Уровень 2: продажи по неделям
    Пакет.Добавить("
    |ВЫБРАТЬ
    |   НАЧАЛОНЕДЕЛИ(ПродажиПоДням.Дата) КАК Неделя,
    |   СУММА(ПродажиПоДням.СуммаДня) КАК СуммаНедели
    |ПОМЕСТИТЬ ВТ_ПродажиПоНеделям
    |ИЗ
    |   ВТ_ПродажиПоДням КАК ПродажиПоДням
    |СГРУППИРОВАТЬ ПО
    |   НАЧАЛОНЕДЕЛИ(ПродажиПоДням.Дата)");
    
    // Уровень 3: продажи по месяцам
    Пакет.Добавить("
    |ВЫБРАТЬ
    |   НАЧАЛОМЕСЯЦА(ПродажиПоНеделям.Неделя) КАК Месяц,
    |   СУММА(ПродажиПоНеделям.СуммаНедели) КАК СуммаМесяца
    |ПОМЕСТИТЬ ВТ_ПродажиПоМесяцам
    |ИЗ
    |   ВТ_ПродажиПоНеделям КАК ПродажиПоНеделям
    |СГРУППИРОВАТЬ ПО
    |   НАЧАЛОМЕСЯЦА(ПродажиПоНеделям.Неделя)");
    
    // Финальный запрос: все уровни вместе
    Пакет.Добавить("
    |ВЫБРАТЬ
    |   ПоДням.Дата,
    |   ПоДням.СуммаДня,
    |   ПоНеделям.Неделя,
    |   ПоНеделям.СуммаНедели,
    |   ПоМесяцам.Месяц,
    |   ПоМесяцам.СуммаМесяца
    |ИЗ
    |   ВТ_ПродажиПоДням КАК ПоДням
    |       ЛЕВОЕ СОЕДИНЕНИЕ ВТ_ПродажиПоНеделям КАК ПоНеделям
    |       ПО НАЧАЛОНЕДЕЛИ(ПоДням.Дата) = ПоНеделям.Неделя
    |       ЛЕВОЕ СОЕДИНЕНИЕ ВТ_ПродажиПоМесяцам КАК ПоМесяцам
    |       ПО НАЧАЛОМЕСЯЦА(ПоДням.Дата) = ПоМесяцам.Месяц
    |УПОРЯДОЧИТЬ ПО
    |   ПоДням.Дата");
    
    Пакет.УстановитьПараметр("ДатаНачала", НачалоМесяца(ТекущаяДата())-45);
    Пакет.УстановитьПараметр("ДатаОкончания", ТекущаяДата());
    
    Результаты = Пакет.Выполнить();
    Выборка = Результаты[3].Выбрать(); // Финальный результат
    
    Сообщить("Агрегированные продажи:");
    Пока Выборка.Следующий() Цикл
        Сообщить(Выборка.Дата + " | День: " + Выборка.СуммаДня +
                 " | Неделя: " + Выборка.СуммаНедели +
                 " | Месяц: " + Выборка.СуммаМесяца);
    КонецЦикла;
    
КонецПроцедуры

Пакетный запрос с динамическими параметрами

// Пакетный запрос с установкой параметров из внешнего источника
Процедура ПакетныйЗапросСДинамическимиПараметрами()

    // Источник параметров (например, таблица значений)
    ПараметрыОтчета = Новый ТаблицаЗначений;
    ПараметрыОтчета.Колонки.Добавить("НаименованиеПараметра");
    ПараметрыОтчета.Колонки.Добавить("Значение");
    
    ПараметрыОтчета.Добавить().НаименованиеПараметра = "ДатаНачала";
    ПараметрыОтчета[0].Значение = НачалоГода(ТекущаяДата());
    
    ПараметрыОтчета.Добавить().НаименованиеПараметра = "ДатаОкончания";
    ПараметрыОтчета[1].Значение = КонецГода(ТекущаяДата());
    
    ПараметрыОтчета.Добавить().НаименованиеПараметра = "Склад";
    ПараметрыОтчета[2].Значение = Справочники.Склады.НайтиПоНаименованию("Основной склад");
    
    ПараметрыОтчета.Добавить().НаименованиеПараметра = "МинимальнаяСумма";
    ПараметрыОтчета[3].Значение = 10000;
    
    // Формируем пакетный запрос
    Пакет = Новый ПакетЗапросов;
    Пакет.МенеджерВременныхТаблиц = Новый МенеджерВременныхТаблиц;
    
    Пакет.Добавить("
    |ВЫБРАТЬ
    |   Реализация.Контрагент,
    |   СУММА(Реализация.Сумма) КАК ОбщаяСумма
    |ПОМЕСТИТЬ ВТ_ПродажиПоКонтрагентам
    |ИЗ
    |   Документ.РеализацияТоваров КАК Реализация
    |ГДЕ
    |   Реализация.Период МЕЖДУ &ДатаНачала И &ДатаОкончания
    |   И Реализация.Склад = &Склад
    |СГРУППИРОВАТЬ ПО
    |   Реализация.Контрагент");
    
    Пакет.Добавить("
    |ВЫБРАТЬ
    |   ВТ_ПродажиПоКонтрагентам.Контрагент,
    |   ВТ_ПродажиПоКонтрагентам.ОбщаяСумма
    |ИЗ
    |   ВТ_ПродажиПоКонтрагентам КАК ВТ_ПродажиПоКонтрагентам
    |ГДЕ
    |   ВТ_ПродажиПоКонтрагентам.ОбщаяСумма >= &МинимальнаяСумма
    |УПОРЯДОЧИТЬ ПО
    |   ОбщаяСумма УБЫВ");
    
    // Устанавливаем параметры из таблицы
    Для Каждого СтрокаПараметра Из ПараметрыОтчета Цикл
        Пакет.УстановитьПараметр(СтрокаПараметра.НаименованиеПараметра, СтрокаПараметра.Значение);
    КонецЦикла;
    
    // Дополнительная проверка перед выполнением
    Попытка
        Результаты = Пакет.Выполнить();
        
        Выборка = Результаты[1].Выбрать();
        Сообщико("Контрагенты с суммой продаж более " + 
                 Строка(ПараметрыОтчета[3].Значение) + ":");
        
        Пока Выборка.Следующий() Цикл
            Сообщить(Выборка.Контрагент + " - " + Выборка.ОбщаяСумма);
        КонецЦикла;
        
    Исключение
        Сообщить("Ошибка выполнения пакетного запроса: " + ОписаниеОшибки());
    КонецПопытки;
    
КонецПроцедуры

Пакетный запрос с INSERT и UPDATE

// Пакетное выполнение модифицирующих запросов
Процедура ПакетныйЗапросСМодификациейДанных()

    Пакет = Новый ПакетЗапросов;
    
    // Запрос 1: создаем временную таблицу
    Пакет.Добавить("
    |ВЫБРАТЬ
    |   Номенклатура.Ссылка КАК Товар,
    |   Номенклатура.Цена * 1.1 КАК НоваяЦена
    |ПОМЕСТИТЬ ВТ_НовыеЦены
    |ИЗ
    |   Справочник.Номенклатура КАК Номенклатура
    |ГДЕ
    |   Номенклатура.ЭтоГруппа = ЛОЖЬ
    |   И Номенклатура.Цена > 0");
    
    // Запрос 2: обновляем цены (имитация через запрос, если поддерживается)
    // В некоторых конфигурациях можно использовать конструкцию ВЫБРАТЬ ... ПОМЕСТИТЬ ... ВРЕМЕННУЮ
    Пакет.Добавить("
    |// Обновление цен товаров на 10%
    |ВЫБРАТЬ
    |   ВТ_НовыеЦены.Товар,
    |   ВТ_НовыеЦены.НоваяЦена
    |ИЗ
    |   ВТ_НовыеЦены КАК ВТ_НовыеЦены");
    
    // Запрос 3: выборка для проверки
    Пакет.Добавить("
    |ВЫБРАТЬ
    |   Номенклатура.Наименование,
    |   Номенклатура.Цена КАК СтараяЦена,
    |   ВТ_НовыеЦены.НоваяЦена
    |ИЗ
    |   Справочник.Номенклатура КАК Номенклатура
    |       ВНУТРЕННЕЕ СОЕДИНЕНИЕ ВТ_НовыеЦены КАК ВТ_НовыеЦены
    |       ПО Номенклатура.Ссылка = ВТ_НовыеЦены.Товар");
    
    Пакет.МенеджерВременныхТаблиц = Новый МенеджерВременныхТаблиц;
    
    Попытка
        НачатьТранзакцию();
        
        Результаты = Пакет.Выполнить();
        
        // Выводим изменения
        Выборка = Результаты[2].Выбрать();
        Сообщить("Изменение цен:");
        Пока Выборка.Следующий() Цикл
            Сообщить(Выборка.Наименование + ": " + Выборка.СтараяЦена + 
                     " -> " + Выборка.НоваяЦена);
        КонецЦикла;
        
        // Здесь должен быть код реального обновления данных
        // (например, через Справочник.Номенклатура.ОбновитьЦены(ВТ_НовыеЦены))
        
        ЗафиксироватьТранзакцию();
        
    Исключение
        ОтменитьТранзакцию();
        Сообщить("Ошибка: " + ОписаниеОшибки());
    КонецПопытки;
    
КонецПроцедуры

Пакетный запрос для разбиения данных на порции

// Разбиение большого запроса на пакетные порции для оптимизации
Функция ВыполнитьЗапросПорциями(ТекстЗапроса, РазмерПорции = 1000)

    // Получаем общее количество записей
    ЗапросСчетчик = Новый Запрос;
    ЗапросСчетчик.Текст = СтрЗаменить(ТекстЗапроса, "ВЫБРАТЬ", "ВЫБРАТЬ КОЛИЧЕСТВО(*) КАК Всего");
    
    РезультатСчетчик = ЗапросСчетчик.Выполнить();
    Если РезультатСчетчик.Пустой() Тогда
        Возврат Новый ТаблицаЗначений;
    КонецЕсли;
    
    ВыборкаСчетчик = РезультатСчетчик.Выбрать();
    ВыборкаСчетчик.Следующий();
    ВсегоЗаписей = ВыборкаСчетчик.Всего;
    
    КоличествоПорций = Цел(ВсегоЗаписей / РазмерПорции) + 
                        ?(ВсегоЗаписей % РазмерПорции > 0, 1, 0);
    
    // Создаем пакет запросов
    Пакет = Новый ПакетЗапросов;
    
    Для НомерПорции = 1 По КоличествоПорций Цикл
        Смещение = (НомерПорции - 1) * РазмерПорции;
        
        // Добавляем запрос с ограничением
        ТекстПорции = ТекстЗапроса + 
                      " ПРОПУСТИТЬ " + Строка(Смещение) + 
                      " ПЕРВЫЕ " + Строка(РазмерПорции);
        
        Пакет.Добавить(ТекстПорции);
    КонецЦикла;
    
    // Выполняем пакет
    Результаты = Пакет.Выполнить();
    
    // Объединяем все порции
    ИтоговаяТаблица = Новый ТаблицаЗначений;
    
    Для НомерПорции = 0 По Результаты.Количество() - 1 Цикл
        ТаблицаПорции = Результаты[НомерПорции].Выгрузить();
        
        Если ИтоговаяТаблица.Колонки.Количество() = 0 И ТаблицаПорции.Колонки.Количество() > 0 Тогда
            // Копируем структуру из первой непустой порции
            Для Каждого Колонка Из ТаблицаПорции.Колонки Цикл
                ИтоговаяТаблица.Колонки.Добавить(Колонка.Имя, Колонка.ТипЗначения);
            КонецЦикла;
        КонецЕсли;
        
        ИтоговаяТаблица.Объединить(ТаблицаПорции);
    КонецЦикла;
    
    Возврат ИтоговаяТаблица;
    
КонецФункции

// Пример использования
Процедура ОбработатьБольшойОбъемДанных()

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

Примечания

// Важные особенности работы с пакетными запросами:
// 1. Пакет запросов позволяет выполнить несколько запросов за одно обращение к СУБД
// 2. Все запросы в пакете выполняются в одной транзакции (если не настроено иное)
// 3. Временные таблицы доступны всем запросам пакета через общий МенеджерВременныхТаблиц
// 4. Параметры можно устанавливать как для всего пакета, так и для отдельных запросов
// 5. Результаты возвращаются в виде массива результатов запросов
// 6. При ошибке в одном запросе выполнение пакета прерывается
// 7. Для обработки ошибок изолированно используйте отдельные пакеты для каждого запроса
// 8. Пакетные запросы эффективны для ETL-операций и сложных отчетов
// 9. Количество запросов в пакете ограничено настройками СУБД (обычно достаточно 100-200)
// 10. При работе с большими объемами используйте порционную обработку через ПРОПУСТИТЬ и ПЕРВЫЕ

Поделиться с друзьями
Smirnov code
Добавить комментарий