В практике разработчика 1С часто возникает задача фильтрации документов не по простым реквизитам шапки, а по состоянию их табличных частей. Типичный пример: нужно найти все документы, в которых определенное поле в табличной части осталось пустым. Ситуация осложняется, если бизнес-логика требует исключить документ из выборки, если хотя бы в одной строке этот реквизит заполнен. Разберем подробно, как реализовать такие условия с помощью языка запросов 1С.
Проанализируем самый понятный и логичный способ. Его суть заключается в методе «от противного». Сначала мы выбираем все документы, у которых реквизит в табличной части заполнен (то есть те, которые нам НЕ нужны), а затем исключаем их из общего списка документов.
Рассмотрим пример, когда нам нужно найти документы Заявка, где в табличной части ЗапросыВБанк реквизит Отправлено (тип Булево) не установлен ни в одной строке:
ВЫБРАТЬ
Заявка.Ссылка КАК Ссылка,
Заявка.Ответственный КАК Ответственный
ИЗ
Документ.Заявка КАК Заявка
ГДЕ
НЕ Заявка.Ссылка В
(ВЫБРАТЬ РАЗЛИЧНЫЕ
ТЧ.Ссылка
ИЗ
Документ.Заявка.ЗапросыВБанк КАК ТЧ
ГДЕ
ТЧ.Отправлено = ИСТИНА)
Почему это работает: внутренний запрос формирует список ссылок на документы, которые имеют хотя бы одну «положительную» строку. Оператор НЕ В отсекает их, оставляя только те документы, где либо все строки имеют значение ЛОЖЬ, либо табличная часть вообще пуста. Это надежный способ для решения задачи, поставленной в сообщении 19.
Иногда использование вложенных запросов может негативно сказываться на производительности, если таблица документов огромна. Рассмотрим альтернативный подход с использованием группировки и условий на результат агрегатных функций. Выясним причину, по которой этот метод часто называют «математическим».
Посмотрим на пример из сообщения 10, адаптированный под общую задачу:
ВЫБРАТЬ
ТЧ.Ссылка КАК Ссылка
ИЗ
Документ.ОказаниеУслуги.ПереченьНоменклатуры КАК ТЧ
СГРУППИРОВАТЬ ПО
ТЧ.Ссылка
ИМЕЮЩИЕ
МАКСИМУМ(ВЫБОР
КОГДА ТЧ.Номенклатура <> ЗНАЧЕНИЕ(Справочник.Номенклатура.ПустаяСсылка)
ТОГДА 1
ИНАЧЕ 0
КОНЕЦ) = 0
Разберем по шагам логику этого запроса:
ИМЕЮЩИЕ МАКСИМУМ(...) = 0 гарантирует, что среди всех строк документа не нашлось ни одной, где значение стало бы равным 1. Если хотя бы в одной строке реквизит заполнен, МАКСИМУМ станет равен 1, и документ не попадет в выборку.Часто задача усложняется необходимостью проверять дополнительные реквизиты в шапке документа. Проанализируем ситуацию из сообщения 26, где проверка табличной части должна срабатывать только при условии, что в шапке не заполнены определенные поля.
В таких случаях важно правильно расставить скобки и логические операторы И / ИЛИ. Посмотрим на структуру такого запроса:
ВЫБРАТЬ
Заявка.Ссылка,
Заявка.Ответственный
ИЗ
Документ.Заявка КАК Заявка
ГДЕ
(Заявка.РеквизитШапки1 = &ПустоеЗначение ИЛИ Заявка.РеквизитШапки2 = &ПустоеЗначение)
И НЕ Заявка.Ссылка В
(ВЫБРАТЬ
ТЧ.Ссылка
ИЗ
Документ.Заявка.ЗапросыВБанк КАК ТЧ
ГДЕ
ТЧ.Отправлено = ИСТИНА)
Важный нюанс: при использовании типа Булево нужно помнить, что в 1С оно всегда имеет значение (Истина или Ложь). Понятие «не заполнено» для Булево обычно эквивалентно значению ЛОЖЬ. Если же реквизит имеет ссылочный тип (например, СправочникСсылка), обязательно используйте проверку на ПустаяСсылка или НЕОПРЕДЕЛЕНО (для составных типов).
Для высоконагруженных систем рекомендуется использовать ЛЕВОЕ СОЕДИНЕНИЕ с проверкой на NULL. Это позволяет СУБД эффективнее использовать индексы. Рассмотрим этот продвинутый метод:
ВЫБРАТЬ
Заявка.Ссылка
ИЗ
Документ.Заявка КАК Заявка
ЛЕВОЕ СОЕДИНЕНИЕ Документ.Заявка.ЗапросыВБанк КАК ТЧ
ПО Заявка.Ссылка = ТЧ.Ссылка
И ТЧ.Отправлено = ИСТИНА
ГДЕ
ТЧ.Ссылка ЕСТЬ NULL
В данном примере мы пытаемся присоединить к каждому документу только те строки табличной части, где условие «заполнености» выполняется. Если документ не содержит таких строк, то в результате соединения в полях таблицы ТЧ будет значение NULL. Фильтр ГДЕ ТЧ.Ссылка ЕСТЬ NULL эффективно отбирает именно такие документы.
Подведем итоги нашего анализа. Выбор метода зависит от конкретной ситуации:
ЗНАЧЕНИЕ(...ПустаяСсылка), для Булево — ИСТИНА/ЛОЖЬ.Используя эти подходы, вы сможете гибко настраивать выборку данных и решать задачи любой сложности, связанные с анализом табличных частей документов в 1С.