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

Программист 1С v8.3 (Обычные формы)
← На главную

При разработке отчетов или механизмов анализа данных в 1С часто возникает задача: получить не просто список связанных документов (например, через механизм «Структура подчиненности»), а данные непосредственно из их табличных частей. Стандартный механизм критериев отбора позволяет быстро найти ссылки на документы, но попытка «достучаться» до строк табличной части через точку (например, СвязанныеДокументы.Ссылка.Товары) в запросе всегда приводит к ошибке. Это происходит потому, что поле Ссылка в критерии отбора имеет составной тип данных, и платформа не может заранее определить, к какой именно таблице обращаться.

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

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

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

Шаг 1: Получение списка ссылок во временную таблицу

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

Проанализируем базовый запрос для получения ссылок:


ВЫБРАТЬ
    СвязанныеДокументы.Ссылка КАК СвязДок
ПОМЕСТИТЬ ВТ_ВсеСвязанныеСсылки
ИЗ
    КритерийОтбора.СвязанныеДокументы(&РеестрДок) КАК СвязанныеДокументы
;

Здесь &РеестрДок — это ссылка на документ-основание, для которого мы ищем подчиненные объекты. Помещая результат во временную таблицу ВТ_ВсеСвязанныеСсылки, мы подготавливаем данные для дальнейшей обработки.

Шаг 2: Фильтрация по типу документа и получение табличной части

Обычно нас интересует не абстрактный список всех документов, а строки конкретных документов, например, «Перемещений товаров». Теперь мы должны соединить нашу временную таблицу с реальной таблицей строк (Товары) конкретного документа.

Рассмотрим, как это реализовать с помощью внутреннего соединения:


ВЫБРАТЬ
    ПеремещениеТоваровТовары.Номенклатура КАК Номенклатура,
    ПеремещениеТоваровТовары.Количество КАК Количество,
    ПеремещениеТоваровТовары.Ссылка КАК ДокументСсылка
ИЗ
    Документ.ПеремещениеТоваров.Товары КАК ПеремещениеТоваровТовары
ГДЕ
    ПеремещениеТоваровТовары.Ссылка В (ВЫБРАТЬ Ссылка ИЗ ВТ_ВсеСвязанныеСсылки)
    И ТИПЗНАЧЕНИЯ(ПеремещениеТоваровТовары.Ссылка) = ТИП(Документ.ПеремещениеТоваров)

В данном примере мы выбираем данные из таблицы Документ.ПеремещениеТоваров.Товары. Условие В (ВЫБРАТЬ Ссылка ИЗ ВТ_ВсеСвязанныеСсылки) гарантирует, что мы получим строки только тех документов, которые действительно связаны с нашим основанием.

Шаг 3: Объединение данных из разных типов документов

Что делать, если нужно собрать данные из табличных частей нескольких разных документов? Например, и из «Перемещений», и из «Реализаций». В этом случае мы используем конструкцию ОБЪЕДИНИТЬ ВСЕ. Это намного производительнее, чем строить сложные левые соединения.

Разберем пример консолидированного запроса:


// 1. Собираем все связи
ВЫБРАТЬ
    СвязанныеДокументы.Ссылка КАК СвязДок
ПОМЕСТИТЬ ВТ_Связи
ИЗ
    КритерийОтбора.СвязанныеДокументы(&РеестрДок) КАК СвязанныеДокументы
ИНДЕКСИРОВАТЬ ПО
    СвязДок
;

// 2. Выбираем товары из Перемещений
ВЫБРАТЬ
    "Перемещение" КАК ТипОперации,
    ТЧ.Номенклатура,
    ТЧ.Количество
ИЗ
    Документ.ПеремещениеТоваров.Товары КАК ТЧ
ГДЕ
    ТЧ.Ссылка В (ВЫБРАТЬ СвязДок ИЗ ВТ_Связи)

ОБЪЕДИНИТЬ ВСЕ

// 3. Выбираем товары из Реализаций
ВЫБРАТЬ
    "Реализация",
    ТЧ.Номенклатура,
    ТЧ.Количество
ИЗ
    Документ.РеализацияТоваровУслуг.Товары КАК ТЧ
ГДЕ
    ТЧ.Ссылка В (ВЫБРАТЬ СвязДок ИЗ ВТ_Связи)

Важные рекомендации по оптимизации

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

  1. Индексация временных таблиц: Всегда используйте ИНДЕКСИРОВАТЬ ПО для поля со ссылкой во временной таблице. Это критически важно для производительности при последующем соединении с табличными частями.
  2. Ограничение по типам: Старайтесь максимально сузить выборку. Если вы знаете, что вас интересуют только «Перемещения», добавьте фильтр по ТИПЗНАЧЕНИЯ или используйте обращение к конкретной физической таблице документа.
  3. Учет RLS: Помните, что критерий отбора учитывает права доступа (Row Level Security). Если у пользователя нет прав на просмотр определенного типа связанных документов, они не попадут в выборку, даже если физически существуют в базе.
  4. Использование ВЫРАЗИТЬ: Если вам нужны только реквизиты шапки связанных документов (а не строки ТЧ), можно обойтись без соединений, используя конструкцию ВЫРАЗИТЬ(СвязанныеДокументы.Ссылка КАК Документ.ПеремещениеТоваров).СкладОтправитель.

Альтернативный метод: Прямой запрос к ТЧ

В некоторых конфигурациях связь «Документ-основание -> Подчиненный документ» реализована через стандартный реквизит ДокументОснование в шапке подчиненного документа. В таком случае иногда проще и быстрее обратиться к табличной части напрямую, минуя критерий отбора:


ВЫБРАТЬ
    ТЧ.Номенклатура,
    ТЧ.Количество
ИЗ
    Документ.ПеремещениеТоваров.Товары КАК ТЧ
ГДЕ
    ТЧ.Ссылка.ДокументОснование = &РеестрДок

Однако помните: критерий отбора универсальнее. Он найдет связи, даже если они установлены через разные реквизиты (например, в одном документе это «Заказ», а в другом — «Сделка»), так как критерий отбора индексирует все указанные в его составе пути.

Таким образом, использование временных таблиц для хранения ссылок из критерия отбора с последующим соединением с табличными частями является наиболее гибким и правильным подходом для получения детальных данных о связанных объектах в системе 1С:Предприятие.

← На главную