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

Программист 1С v8.3 (Управляемые формы) 1C:Бухгалтерия IT и автоматизация бизнеса
← На главную

Особенность хранения табличных частей в базе данных 1С

Прежде чем перейти к составлению запроса, разберем причину, по которой нельзя проверить заполненность табличной части простым сравнением с НЕОПРЕДЕЛЕНО или NULL. В платформе 1С табличная часть документа не является ссылочным реквизитом шапки. В СУБД она хранится в виде отдельной физической таблицы, связанной с шапкой документа через поле Ссылка. По этой причине обращение вида ПлатежноеПоручение.ДокументыПоступления = НЕОПРЕДЕЛЕНО является ошибочным.

Способ 1. Использование временной таблицы и левого соединения

Проанализируем классический подход к решению задачи. Суть метода заключается в предварительном выборе всех ссылок документов, присутствующих в табличной части, с помощью ключевого слова РАЗЛИЧНЫЕ, помещении их во временную таблицу и последующем левом соединении с базовой таблицей документов.

Рассмотрим пример запроса для поиска документов с пустой табличной частью:


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

ВЫБРАТЬ
    ПлатежноеПоручение.Ссылка КАК ПлатежныйДокумент
ИЗ
    Документ.ПлатежноеПоручениеИсходящее КАК ПлатежноеПоручение
    ЛЕВОЕ СОЕДИНЕНИЕ ВТ_ЗаполненныеДокументы КАК ВТ
    ПО ПлатежноеПоручение.Ссылка = ВТ.Ссылка
ГДЕ
    ВТ.Ссылка ЕСТЬ NULL

Для отбора документов, в которых табличная часть, наоборот, заполнена, измените условие в секции ГДЕ на НЕ ВТ.Ссылка ЕСТЬ NULL (или ВТ.Ссылка ЕСТЬ НЕ NULL).

Важное условие производительности: При помещении данных во временную таблицу обязательно используйте инструкцию ИНДЕКСИРОВАТЬ ПО Ссылка. На больших объемах данных это существенно ускоряет операцию левого соединения.

Способ 2. Левое соединение с проверкой первого номера строки

Рассмотрим более компактный способ без создания временных таблиц. Выполним ЛЕВОЕ СОЕДИНЕНИЕ таблицы документов напрямую с ее табличной частью, ограничив выборку первой строкой с помощью условия И ТЧ.НомерСтроки = 1.

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


ВЫБРАТЬ
    ПлатежноеПоручение.Ссылка КАК ПлатежныйДокумент
ИЗ
    Документ.ПлатежноеПоручениеИсходящее КАК ПлатежноеПоручение
    ЛЕВОЕ СОЕДИНЕНИЕ Документ.ПлатежноеПоручениеИсходящее.ДокументыПоступления КАК ТЧ
    ПО ПлатежноеПоручение.Ссылка = ТЧ.Ссылка
    И ТЧ.НомерСтроки = 1
ГДЕ
    ТЧ.НомерСтроки ЕСТЬ NULL

Плюсы данного метода:

  1. Условие ТЧ.НомерСтроки = 1 исключает дублирование строк шапки в результате запроса, так как выбирается ровно одна строка из табличной части.
  2. Запрос выполняется за один проход без привлечения временных таблиц и оператора РАЗЛИЧНЫЕ.
  3. Для отбора заполненных табличных частей достаточно изменить условие на ГДЕ ТЧ.НомерСтроки ЕСТЬ НЕ NULL.

Способ 3. Условие с подзапросом (операторы В / НЕ В)

Выясним, как написать лаконичный запрос с использованием вложенного запроса в секции ГДЕ.

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


ВЫБРАТЬ
    ПлатежноеПоручение.Ссылка КАК ПлатежныйДокумент
ИЗ
    Документ.ПлатежноеПоручениеИсходящее КАК ПлатежноеПоручение
ГДЕ
    ПлатежноеПоручение.Ссылка В
        (ВЫБРАТЬ РАЗЛИЧНЫЕ
            ТЧ.Ссылка
        ИЗ
            Документ.ПлатежноеПоручениеИсходящее.ДокументыПоступления КАК ТЧ)

Если требуется отобрать документы с пустой табличной частью, используем оператор НЕ В:


ВЫБРАТЬ
    ПлатежноеПоручение.Ссылка КАК ПлатежныйДокумент
ИЗ
    Документ.ПлатежноеПоручениеИсходящее КАК ПлатежноеПоручение
ГДЕ
    НЕ ПлатежноеПоручение.Ссылка В
        (ВЫБРАТЬ РАЗЛИЧНЫЕ
            ТЧ.Ссылка
        ИЗ
            Документ.ПлатежноеПоручениеИсходящее.ДокументыПоступления КАК ТЧ)

Проверка заполненности во встроенном языке 1С

Если проверка выполняется в коде программного модуля на сервере над объектом документа (например, ДокументОбъект), выполнять запрос не обязательно. Достаточно проверить количество строк коллекции:


Если ДокументОбъект.ДокументыПоступления.Количество() = 0 Тогда
    // Табличная часть не заполнена
КонецЕсли;

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

← На главную