Как вывести все строки табличной части, если условию по дате соответствует хотя бы одна из них?

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

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

Метод 1. Использование временных таблиц (классический подход в запросах)

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

Шаг 1. Отбор ссылок на документы. Мы создаем запрос к табличной части, где применяем фильтр по периоду. Важно использовать ключевое слово РАЗЛИЧНЫЕ, чтобы не дублировать ссылки на документы, если в них несколько строк попали в период.


ВЫБРАТЬ РАЗЛИЧНЫЕ
    ЗаказТовары.Ссылка КАК Ссылка
ПОМЕСТИТЬ ВТ_ПодходящиеЗаказы
ИЗ
    Документ.ЗаказКлиента.Товары КАК ЗаказТовары
ГДЕ
    ЗаказТовары.ДатаОтгрузки МЕЖДУ &ДатаНачала И &ДатаОкончания
    И ЗаказТовары.Ссылка.Проведен = ИСТИНА;

Шаг 2. Получение всех строк табличной части. Теперь мы выбираем данные из той же табличной части, но в качестве фильтра используем массив ссылок из нашей временной таблицы ВТ_ПодходящиеЗаказы.


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

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

Метод 2. Применение оператора СУЩЕСТВУЕТ (EXISTS)

Иногда удобнее обойтись без временных таблиц, используя один запрос. Оператор СУЩЕСТВУЕТ (или EXISTS в терминах SQL) работает крайне эффективно, так как поиск прекращается сразу после нахождения первой подходящей строки. Посмотрим на пример реализации:


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

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

Метод 3. Реализация через «Связи наборов данных» в СКД

Система компоновки данных предоставляет встроенный механизм для решения подобных задач без написания сложных вложенных запросов. Рассмотрим алгоритм настройки в схеме компоновки:

  1. Создадим НаборДанных1 (запрос). В нем выберем только Ссылка из ТЧ Товары с условием ГДЕ ДатаОтгрузки МЕЖДУ &ДатаНачала И &ДатаОкончания. Используем РАЗЛИЧНЫЕ.
  2. Создадим НаборДанных2 (запрос). Выберем все нужные поля (Номенклатура, Количество и т.д.) из ТЧ Товары без каких-либо условий по дате.
  3. Перейдем на закладку «Связи наборов данных».
  4. Добавим связь: Источник связи — НаборДанных1, Приемник связи — НаборДанных2.
  5. В колонке Условие связи укажем поле Ссылка.

Выясним причину, почему это удобно: СКД сначала выполнит первый запрос, получит список подходящих заказов, а затем для каждого заказа выберет все его строки. Это позволяет разделить логику отбора и логику отображения данных.

Важные нюансы и оптимизация в 1С:КА 2 и ERP

При работе в современных конфигурациях, таких как «Комплексная автоматизация 2» или «ERP Управление предприятием», стоит учитывать несколько технических моментов:

1. Использование регистров сведений. Как отмечалось в обсуждении, данные об отгрузке часто лучше брать не напрямую из документа, а из регистра РаспределениеЗапасов. Это связано с тем, что в ТЧ документа может быть указана одна дата, а по факту обеспечения (резерв, к отгрузке) данные могут отличаться. Однако принцип «выбрать ссылку по условию -> выбрать все данные по ссылке» остается неизменным.

2. Обработка пустых дат. В логике 1С пустая дата часто трактуется как «дата не определена». Если в условии МЕЖДУ одна из дат в ТЧ пустая, эта строка не попадет в фильтр. Если вам нужно учитывать документы, где дата не установлена, добавьте проверку ИЛИ ДатаОтгрузки = ДАТАВРЕМЯ(1,1,1) в первом этапе отбора.

3. Работа со временем. Для корректного попадания данных в период (особенно если &ДатаОкончания выбрана пользователем как дата без времени), обязательно используйте функции СКД или языка запросов для приведения параметров к началу или концу дня:


ГДЕ
    ДатаОтгрузки >= &ДатаНачала
    И ДатаОтгрузки <= КОНЕЦПЕРИОДА(&ДатаОкончания, "ДЕНЬ")

4. Индексация. При использовании временных таблиц (Метод 1) крайне рекомендуем добавлять инструкцию ИНДЕКСИРОВАТЬ ПО Ссылка. Это предотвратит «сканирование таблицы» (Table Scan) при выполнении соединения во втором запросе, что критично для скорости работы отчета.

Подводя итог, мы проанализировали три различных подхода к решению задачи. Выбор конкретного метода зависит от ваших предпочтений и сложности остальной части отчета. Метод с временными таблицами является самым прозрачным для отладки, в то время как связи наборов данных в СКД позволяют максимально использовать мощь визуального конструктора 1С.

← На главную