К статье
Практический материал

Разработка и Конфигурация · 9 мин

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

Как в 1С найти документы с пустой табличной частью: запрос с ЛЕВОЕ СОЕДИНЕНИЕ, ГДЕ ЕСТЬ NULL, подзапросом, обходом в коде и в консоли запросов.

Задача найти документы с пустой табличной частью возникает регулярно: при поиске ошибок ввода, подготовке к свёртке базы, проверке обменов или аудите данных. Документ может быть проведён, но не содержать ни одной строки в табличной части «Товары» или «Услуги» — и такие документы нужно отобрать для исправления или удаления.

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

Ниже разобраны три рабочих способа с готовыми текстами запросов, особенности левого соединения с табличной частью, типичные ошибки и способы проверить, что отбор действительно корректен.

Почему стандартный отбор списка не поможет

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

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

Способ 1. Запрос с левым соединением и условием ЕСТЬ NULL

Классический и самый быстрый способ — левое соединение таблицы документа с его табличной частью. Если у документа нет строк, поля табличной части будут содержать NULL, что и используется как условие отбора.

ВЫБРАТЬ

РеализацияТоваровУслуг.Ссылка КАК Документ,

РеализацияТоваровУслуг.Дата,

РеализацияТоваровУслуг.Номер,

РеализацияТоваровУслуг.Контрагент

ИЗ

Документ.РеализацияТоваровУслуг КАК РеализацияТоваровУслуг

ЛЕВОЕ СОЕДИНЕНИЕ Документ.РеализацияТоваровУслуг.Товары КАК Товары

ПО РеализацияТоваровУслуг.Ссылка = Товары.Ссылка

ГДЕ

Товары.Ссылка ЕСТЬ NULL

И РеализацияТоваровУслуг.Проведен

Обратите внимание на два момента. Во-первых, условие Товары.Ссылка ЕСТЬ NULL проверяет именно ссылку табличной части — она гарантированно заполнена в каждой реальной строке, поэтому NULL однозначно означает отсутствие строк. Во-вторых, условие по табличной части должно стоять в секции ГДЕ, а не в условии соединения ПО, иначе логика левого соединения нарушится.

Дополнительный фильтр РеализацияТоваровУслуг.Проведен отсекает помеченные на удаление и непроведённые документы — обычно интерес представляют именно проведённые. Если нужны все документы, уберите это условие.

Способ 2. Отбор через подзапрос с НЕ В

Альтернатива соединению — подзапрос, выбирающий все документы, у которых есть строки, и исключение их из результата через оператор НЕ В.

ВЫБРАТЬ

РеализацияТоваровУслуг.Ссылка КАК Документ

ИЗ

Документ.РеализацияТоваровУслуг КАК РеализацияТоваровУслуг

ГДЕ

НЕ РеализацияТоваровУслуг.Ссылка В

(ВЫБРАТЬ РАЗЛИЧНЫЕ

Товары.Ссылка

ИЗ

Документ.РеализацияТоваровУслуг.Товары КАК Товары)

Этот вариант проще читается, но на больших объёмах данных обычно работает медленнее левого соединения, особенно в файловых базах. На клиент-серверных базах с СУБД MS SQL или PostgreSQL оптимизатор часто преобразует оба варианта в похожий план, но соединение с ЕСТЬ NULL остаётся более предсказуемым.

Сравнение подходов

Левое соединение + ЕСТЬ NULL

Быстро и предсказуемо, подходит для больших таблиц. Требует аккуратности с условиями соединения.

Подзапрос с НЕ В

Проще для понимания, но медленнее на больших объёмах и чувствителен к NULL в подзапросе.

Обход в коде с Количество() = 0

Не требует знания языка запросов, но медленный: каждая табличная часть вычитывается отдельным обращением.

Способ 3. Программный обход документов в коде

Если запрос по какой-то причине недоступен (например, логика реализуется в обработке проведения или регламентном задании с дополнительными проверками), можно обойти документы выборкой и проверить количество строк у каждого.

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ

| РеализацияТоваровУслуг.Ссылка

|ИЗ

| Документ.РеализацияТоваровУслуг КАК РеализацияТоваровУслуг

|ГДЕ

| РеализацияТоваровУслуг.Проведен";

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

Пока Выборка.Следующий() Цикл

ДокументОбъект = Выборка.Ссылка.ПолучитьОбъект();

Если ДокументОбъект.Товары.Количество() = 0 Тогда

Сообщить("Пустая табличная часть: " + ДокументОбъект);

КонецЕсли;

КонецЦикла;

Главный недостаток подхода — производительность: каждый вызов ПолучитьОбъект() вычитывает документ целиком, включая все табличные части. На тысячах документов это заметно медленнее одного запроса. Используйте обход только когда нужно не просто найти, а сразу обработать документы объектными методами.

Проверка результата и частые ошибки

После выполнения запроса стоит убедиться, что отбор работает корректно. Откройте два-три найденных документа интерактивно и проверьте, что табличная часть действительно пуста. Затем возьмите документ, которого нет в результате, и убедитесь, что в нём строки есть.

Также полезно проверить обратным запросом: выбрать документы, у которых строки есть, и сравнить суммарное количество с общим числом документов. Сумма «с строками» и «без строк» должна равняться общему количеству документов за период.

Типичные ошибки
01
Условие Товары.Ссылка ЕСТЬ NULL помещено в секцию ПО соединения — в результате запрос возвращает все документы или пустой результат, потому что логика левого соединения нарушена.
02
Соединение по полю НомерСтроки вместо Ссылка — соединение становится некорректным, результат непредсказуем.
03
Проверка на NULL поля, которое может быть пустым в реальных строках (например, Номенклатура) — документы со строками ошибочно попадают в результат.
04
Забыт фильтр по пометке удаления — в выборку попадают давно удалённые документы, что искажает картину.
05
Проверяется не та табличная часть: у документа их несколько (Товары, Услуги, Оплата), и пустой может быть только одна из них.

Поиск через консоль запросов и готовые обработки

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

Для массовой обработки найденных документов подойдёт типовая обработка «Групповое изменение реквизитов» (в конфигурациях на Библиотеке стандартных подсистем) или «Универсальный подбор и обработка объектов»: в ней можно задать произвольный запрос отбора и выполнить над результатом действие — например, пометку на удаление. Действие применяйте только после проверки списка.

Порядок действий
  1. 1
    Определите, по какой табличной части и по какому виду документов нужен отбор.
  2. 2
    Выполните запрос с левым соединением и условием ЕСТЬ NULL в консоли запросов.
  3. 3
    Откройте несколько найденных документов и убедитесь, что табличная часть действительно пуста.
  4. 4
    Проверьте контрольную сумму: документы со строками + документы без строк = все документы.
  5. 5
    Только после проверки выполняйте массовые действия над найденными документами.

Особые случаи и ограничения

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

В управляемых формах с динамическим списком можно вывести результат запроса как отдельную форму-отчёт, но для разовых задач это избыточно. Также учтите, что виртуальные поля и итоги к табличным частям не применяются — соединение идёт напрямую с физической таблицей табличной части.

Итог

Что важно запомнить

Документы с пустой табличной частью отбираются запросом: левое соединение с табличной частью и условие ЕСТЬ NULL по её ссылке. Условие размещается в секции ГДЕ, фильтр по проведённым добавляется отдельно. Перед массовой обработкой результат обязательно проверяется вручную и контрольной суммой.

Частые вопросы

Можно ли найти документы, где табличная часть есть, но все количества равны нулю?

Да, но это другая задача. Нужно соединение с табличной частью и группировка: ВЫБРАТЬ Ссылку, СУММА(Количество) СГРУППИРОВАВ ПО Ссылке ИМЕЮЩИЕ СУММА(Количество) = 0. Условие ЕСТЬ NULL здесь не подходит, так как строки физически существуют.

Работает ли запрос с ЕСТЬ NULL в файловой базе?

Да, конструкция левого соединения с проверкой ЕСТЬ NULL полностью поддерживается платформой независимо от режима работы базы. Разница только в скорости выполнения на больших объёмах.

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

Добавьте по одному левому соединению на каждую табличную часть и в секции ГДЕ перечислите условия через И: Товары.Ссылка ЕСТЬ NULL И Услуги.Ссылка ЕСТЬ NULL. Так вы найдёте документы, где пусты обе табличные части. Если достаточно пустоты хотя бы одной, используйте ИЛИ.

Почему запрос возвращает один и тот же документ несколько раз?

Такое бывает, если в соединении ошибочно использовано поле, не являющееся уникальным, или если соединение выполнено с другой таблицей без корректного условия. При соединении документа с собственной табличной частью по Ссылке и условии ЕСТЬ NULL дублей быть не должно — у документа без строк будет ровно одна строка результата.

Можно ли увидеть пустые табличные части без программирования вообще?

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