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

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

При разработке отчетов или обработок в 1С часто возникает задача получить перечень всех документов, которые связаны с текущим списком объектов (например, «Заказы клиентов»). Начинающие разработчики часто пытаются использовать КритерийОтбора, передавая в него список значений, однако сталкиваются с ошибкой платформы. Давайте подробно разберем, почему это происходит и как правильно решить данную задачу.

Почему нельзя передать список в Критерий Отбора?

Важно понимать, что КритерийОтбора в системе 1С — это не физическая таблица, а вспомогательный индекс, оптимизирующий поиск по конкретному значению. Виртуальная таблица критерия отбора спроектирована так, что ожидает на вход ровно одно значение (один Тип и одну Ссылку). Передача массива или СписокЗначений в качестве параметра платформой не поддерживается, так как это противоречит логике работы индексированных поисковых структур.

Вариант 1: Программная генерация текста запроса с ОБЪЕДИНИТЬ ВСЕ

Самый простой и понятный путь — формировать текст запроса динамически. Мы обходим список исходных документов в цикле и для каждого из них добавляем отдельный блок ВЫБРАТЬ с ОБЪЕДИНИТЬ ВСЕ.

Рассмотрим пример реализации на 1С:


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

Этот подход позволяет получить все связанные документы в одном наборе данных, с которым дальше можно работать как с единой таблицей результатов.

Вариант 2: Использование типовых функций конфигурации

В типовых конфигурациях, таких как 1С:Управление торговлей или 1С:Бухгалтерия, часто реализованы функции-обертки для работы с критериями отбора. Рассмотрим, как это выглядит в коде:


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

Хотя эта функция работает только для одного значения, мы можем вызывать её в цикле для списка, либо использовать её логику для доработки генератора запросов, описанного в первом пункте.

Вариант 3: Использование временных таблиц

Если документов очень много, множественные ОБЪЕДИНИТЬ ВСЕ могут замедлить выполнение запроса. В таких случаях рекомендуем использовать ВременныеТаблицы. Сначала мы программно собираем пары «Документ-СвязанныйДокумент» в таблицу значений, загружаем её в запрос через Запрос.УстановитьПараметр("ТаблицаСвязей", ТЗ) и уже после этого делаем ЛЕВОЕ СОЕДИНЕНИЕ с нужными данными.

Вариант 4: Создание собственного регистра сведений

Если производительность системы критична, а критерии отбора работают медленно из-за огромного объема данных, профессиональный подход заключается в создании собственного непериодического РегистрСведений. В этом регистре при записи документа вы можете хранить физические связи. Это позволит вам:

  1. Передавать массив документов прямо в условие ГДЕ или ВНУТРЕННЕЕ СОЕДИНЕНИЕ.
  2. Использовать полнофункциональный язык запросов без ограничений критериев отбора.
  3. Получить максимальную скорость выборки за счет индексации измерений регистра.

Советы по фильтрации результатов

Если вам нужно не просто получить связанные документы, а отфильтровать основной список (например, оставить только те документы, у которых есть Реализация), используйте ВНУТРЕННЕЕ СОЕДИНЕНИЕ с таблицей связанных документов. Если же необходимо получить полный список, но с признаком наличия связи, используйте ЛЕВОЕ СОЕДИНЕНИЕ и проверку ЕСТЬ NULL.

Разбирая подобные задачи, всегда анализируйте количество исходных данных. Для небольших объемов — ОБЪЕДИНИТЬ ВСЕ вполне достаточно, для крупных — только временные таблицы или собственные регистры.

← На главную