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

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

При работе с регистром бухгалтерии и планами счетов разработчики часто сталкиваются с задачей отбора движений или итогов с незаполненными субконто. Поле субконто имеет составной тип данных (на основе плана видов характеристик), что создает определенные сложности: незаполненное значение может быть представлено как Неопределено, NULL или пустая ссылка конкретного типа метаданных (например, пустая ссылка справочника Контрагенты).

Попытка написать условие вида Субконто1 = ЗНАЧЕНИЕ(ПланыВидовХарактеристик.ВидыСубконтоХозрасчетные.ПустаяСсылка) является синтаксически ошибочной, так как само субконто хранит значение характеристики, а не ссылку на элемент плана видов характеристик. Разберем по шагам правильные и эффективные варианты решения этой задачи.

Вариант 1. Проверка на Неопределено и NULL (рекомендуемый для типовых конфигураций)

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

Рассмотрим пример условия в тексте запроса:


ГДЕ
    ХозрасчетныйДвиженияССубконто.Субконто1 = НЕОПРЕДЕЛЕНО
    ИЛИ ХозрасчетныйДвиженияССубконто.Субконто1 ЕСТЬ NULL

Этот способ является самым быстрым с точки зрения СУБД, так как не создает лишних соединений с таблицами метаданных и эффективно использует индексы таблицы регистра.

Вариант 2. Передача списка всех возможных пустых значений через параметр

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

Посмотрим на пример функции, которая обходит типы плана видов характеристик и собирает все пустые значения:


Функция ПолучитьМассивПустыхСубконто(ВидыСубконто) Экспорт
    
    МассивПустых = Новый Массив;
    МассивПустых.Добавить(Неопределено);
    МассивПустых.Добавить(Null);
    
    Выборка = ВидыСубконто.Выбрать();
    Пока Выборка.Следующий() Цикл
        Для Каждого ТекТип Из Выборка.ТипЗначения.Типы() Цикл
            Если ТекТип = Тип("Строка") Тогда
                МассивПустых.Добавить("");
            ИначеЕсли ТекТип = Тип("Число") Тогда
                МассивПустых.Добавить(0);
            ИначеЕсли ТекТип = Тип("Дата") Тогда
                МассивПустых.Добавить('00010101');
            ИначеЕсли ТекТип = Тип("Булево") Тогда
                Продолжить;
            Иначе
                // Создаем пустую ссылку для ссылочных типов
                МассивПустых.Добавить(Новый(ТекТип));
            КонецЕсли;
        КонецЦикла;
    КонецЦикла;
    
    Возврат МассивПустых;
    
КонецФункции

Передадим сформированный массив в параметр запроса:


Запрос.УстановитьПараметр("ПустыеСубконто", ПолучитьМассивПустыхСубконто(ПланыВидовХарактеристик.ВидыСубконтоХозрасчетные));

В тексте запроса используем оператор В:


ГДЕ
    ХозрасчетныйДвиженияССубконто.Субконто1 В (&ПустыеСубконто)

Вариант 3. Использование конструкции ВЫРАЗИТЬ (когда известен счет или вид субконто)

Если выборка строится с ограничением по конкретному счету или виду субконто, оптимально явно типизировать поле с помощью конструкции ВЫРАЗИТЬ. Это позволяет избежать неявных соединений и дает СУБД возможность построить оптимальный план выполнения.

Рассмотрим пример запроса:


ГДЕ
    ВЫРАЗИТЬ(ХозрасчетныйДвиженияССубконто.Субконто1 КАК Справочник.Контрагенты) = ЗНАЧЕНИЕ(Справочник.Контрагенты.ПустаяСсылка)
    ИЛИ ХозрасчетныйДвиженияССубконто.Субконто1 = НЕОПРЕДЕЛЕНО
    ИЛИ ХозрасчетныйДвиженияССубконто.Субконто1 ЕСТЬ NULL

Вариант 4. Проверка через разыменование поля и оценка производительности

Иногда на практике применяют условие разыменования ссылочного поля:


ГДЕ
    ХозрасчетныйДвиженияССубконто.Субконто1.Ссылка ЕСТЬ NULL

Проанализируем, как работает данный механизм. Так как поле Субконто1 имеет составной тип, при обращении через точку к реквизиту Ссылка платформа 1С на уровне СУБД генерирует левые соединения (LEFT JOIN) со всеми таблицами, входящими в составной тип. Для пустых ссылок, значений Неопределено, NULL и «битых» ссылок соединение вернет NULL.

Важно: Данный подход крайне не рекомендуется использовать на больших объемах данных, так как соединение с десятками таблиц метаданных вызывает серьезные проблемы с производительностью и приводит к полному сканированию таблиц (Table Scan).

Особенности использования в Системе компоновки данных (СКД)

Если отчет разрабатывается на СКД, писать сложные условия в запросе нет необходимости. В настройках отбора компоновщика данных достаточно выбрать поле субконто и установить стандартный вид сравнения Не заполнено. СКД самостоятельно сформирует корректный SQL-запрос с учетом всех типов, входящих в характеристику.

  1. Для типовых и оптимизированных конфигураций используем проверку Субконто1 = НЕОПРЕДЕЛЕНО ИЛИ Субконто1 ЕСТЬ NULL.
  2. Для поиска битых или некорректно заполненных пустых ссылок передаем список пустых значений в параметре запроса.
  3. При известном типе субконто всегда применяем конструкцию ВЫРАЗИТЬ.
  4. Избегаем конструкции Субконто1.Ссылка ЕСТЬ NULL на высоконагруженных регистрах.
← На главную