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

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

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

Почему критерий отбора не подходит для запроса за период

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


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

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

Шаг 1. Поиск реквизита связи в конфигураторе

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

  1. Откроем конфигуратор и найдем документ РеализацияТоваровУслуг.
  2. Проверим не только Реквизиты (шапку), но и реквизиты всех Табличных частей (например, «Товары» или «Услуги»). В сложных конфигурациях, таких как «Комплексная автоматизация 1.0» или «УПП», связь часто указывается в каждой строке товара, чтобы одной реализацией можно было закрыть несколько заказов.
  3. Если визуальный поиск не помогает, используем функцию «Поиск ссылок на объект» для документа Заявка. Система покажет все места в метаданных, где может храниться ссылка на этот тип документа.

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

Шаг 2. Написание запроса к табличным частям

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


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

Разберем важные моменты в этом запросе:

Шаг 3. Использование регистров для оптимизации

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


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

Этот способ является наиболее «профессиональным», так как регистры специально оптимизированы для подобных выборок. Мы используем виртуальную таблицу Обороты с периодичностью Регистратор, что позволяет нам напрямую увидеть, какой документ (Реализация) сделал движение по какому Заказу (Заявке).

Резюме и рекомендации

Подводя итог, отметим: критерии отбора — это инструмент интерфейса для быстрой навигации пользователя, а не инструмент для построения отчетов. Для получения связанных данных за период следует использовать либо прямые запросы к таблицам документов (если связь в реквизитах), либо запросы к регистрам накопления.

При работе с реквизитами в табличных частях всегда помните про индексацию. В конфигураторе проверьте свойство «Индексировать» у реквизита ЗаявкаПокупателя. Если индекс отсутствует, запрос будет выполнять полное сканирование таблицы (Full Scan), что приведет к блокировкам базы данных при одновременной работе многих пользователей.

← На главную