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

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

При разработке печатных форм, отчетов и алгоритмов проведения документов в 1С разработчики часто сталкиваются со следующей задачей: в табличной части основного документа (например, ЗаданиеНаПеревозку) хранится ссылка на подчиненный документ (например, РеализацияТоваровУслуг), и необходимо в одном запросе получить строки табличной части этого подчиненного документа (товары, количество, единицы измерения). Разберем особенности платформы 1С при работе с такими связями и пошагово рассмотрим способы построения запросов.

Ограничение языка запросов при обращении к вложенным таблицам

В объектной модели 1С при работе в цикле мы можем получить данные через точку, обратившись к свойству ДокументОбъект.Товары. Однако язык запросов 1С накладывает строгое ограничение: нельзя разыменовывать поля через точку для получения табличных частей. Конструкция вида ЗаказКлиента.ТабличнаяЧасть.Номенклатура синтаксически не поддерживается.

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

Способ 1. Прямое соединение табличных частей

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

Посмотрим на пример запроса:


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

В данном примере мы выбираем строки табличной части Распоряжения документа ЗаданиеНаПеревозку и связываем их с табличной частью Товары документа РеализацияТоваровУслуг по условию совпадения ссылки на реализацию.

Способ 2. Использование временных таблиц и работа с составными типами

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

  1. Выбираем уникальные ссылки на подчиненные документы во временную таблицу и обязательно проверяем тип через оператор ССЫЛКА.
  2. Индексируем временную таблицу по ключевому полю Ссылка для ускорения последующего соединения СУБД.
  3. Выбираем строки из подчиненной табличной части, соединяясь с подготовленной временной таблицей.

Разберем готовый текст пакетного запроса:


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

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
    ТоварыРеализации.Ссылка КАК РеализацияСсылка,
    ТоварыРеализации.Номенклатура КАК Номенклатура,
    ТоварыРеализации.КоличествоУпаковок КАК КоличествоУпаковок,
    ТоварыРеализации.Количество КАК Количество
ИЗ
    Документ.РеализацияТоваровУслуг.Товары КАК ТоварыРеализации
    ВНУТРЕННЕЕ СОЕДИНЕНИЕ ВТ_Документы КАК ВТ_Документы
        ПО ТоварыРеализации.Ссылка = ВТ_Документы.ДокументСсылка

Типичные ошибки при выводе данных в печатные формы

Часто после получения выборки из запроса разработчики сталкиваются с тем, что параметры табличного документа не заполняются или возникает ошибка «Поле объекта не обнаружено». Выясним основные причины и методы их исправления:

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

Посмотрим на корректный пример обработки выборки запроса с использованием метода Заполнить():


Результат = Запрос.Выполнить();
Выборка = Результат.Выбрать();

Пока Выборка.Следующий() Цикл
    // Заполняем параметры области автоматически по именам полей выборки
    ОбластьСтрока.Параметры.Заполнить(Выборка);
    ТабличныйДокумент.Вывести(ОбластьСтрока);
КонецЦикла;

Использование метода Область.Параметры.Заполнить() позволяет избежать ручного перекладывания каждого реквизита и защищает от ошибок при опечатках в именах переменных.

← На главную