Как настроить отбор по булевым дополнительным реквизитам в отчетах СКД, если значения Ложь не отображаются?

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

При работе с конфигурациями на базе БСП (Библиотека стандартных подсистем), такими как 1С:Комплексная автоматизация 2.4, 1С:ERP или 1С:Управление торговлей 11, разработчики и аналитики часто сталкиваются с проблемой фильтрации данных по дополнительным реквизитам. Особенно остро эта проблема проявляется для реквизитов с типом Булево. В отчетах, построенных на системе компоновки данных (СКД), значения «Да» (Истина) отображаются и фильтруются корректно, а вот значения «Нет» (Ложь) часто выглядят как пустые поля, и отбор по ним не срабатывает.

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

Почему отбор по значению Ложь не работает?

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

Когда система компоновки данных (СКД) строит отчет, она использует механизм Характеристик. В запросе это превращается в ЛЕВОЕ СОЕДИНЕНИЕ (LEFT JOIN) основной таблицы документа с таблицей дополнительных реквизитов. Рассмотрим, что происходит на уровне SQL-запроса:

  1. Если для документа установлен доп. реквизит «Да», соединение находит строку, и мы получаем значение Истина.
  2. Если для документа значение «Нет», строки в таблице реквизитов нет. Результатом левого соединения становится значение NULL.

Проблема заключается в том, что в стандартных настройках отбора пользователь выбирает Равно — Нет. Однако с точки зрения базы данных NULL не равен Ложь. Математически сравнение NULL = Ложь дает результат «Неизвестно» (Unknown), и такие строки отсекаются фильтром. Именно поэтому отчет по «ненапечатанным» документам или документам со значением «Нет» может выходить пустым.

Способ 1. Использование расширенных настроек отбора (для пользователей)

Самый простой способ, не требующий изменения кода конфигурации, — это использование встроенных возможностей интерфейса СКД. Рассмотрим, как это сделать по шагам:

  1. Откроем форму настроек отчета.
  2. Если в быстром доступе доступны только условия Равно и Не равно, необходимо перейти в расширенный режим. Для этого нажмем кнопку Еще — Прочее — Изменить вариант отчета.
  3. Перейдем на закладку Отбор.
  4. Добавим поле нашего дополнительного реквизита.
  5. В колонке «Вид сравнения» выберем Не заполнено.

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

Способ 2. Создание сложного отбора через группу ИЛИ

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

Для этого в настройках отбора выполним следующие действия:

  1. Нажмем «Сгруппировать условия» и выберем тип группы ИЛИ.
  2. Внутри группы добавим два условия:
    • ДопРеквизит Равно Ложь
    • ДопРеквизит Не заполнено

Такой подход гарантирует, что в выборку попадут все нужные документы вне зависимости от версии БСП и способа записи данных.

Способ 3. Использование вычисляемых полей в СКД (для разработчиков)

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

Выясним причину: нам нужно, чтобы СКД видела Ложь вместо NULL. Для этого:

  1. Откроем схему компоновки данных (отчет).
  2. Перейдем на закладку Вычисляемые поля.
  3. Добавим новое поле, например, Напечатано_ДляОтбора.
  4. В выражении пропишем функцию преобразования: ЕСТЬNULL(ДополнительныйРеквизит_Напечатано, Ложь)
  5. Теперь в настройках отчета пользователю следует предлагать именно это вычисляемое поле. Оно всегда будет иметь тип Булево и никогда не будет NULL.

Способ 4. Программное вмешательство в механизм Характеристик

Механизм характеристик в БСП и платформе работает автоматически. Платформа видит описание в метаданных или в тексте запроса через конструкцию ХАРАКТЕРИСТИКИ. Вмешаться в саму генерацию LEFT JOIN платформой напрямую сложно, но можно повлиять на описание характеристик.

В БСП за формирование описания характеристик отвечают общие модули, такие как УправлениеСвойствами и ОбщегоНазначенияБСП. В частности, стоит обратить внимание на функцию, которая возвращает текст запроса для получения значений свойств. Если изменить описание источника характеристик на вложенный запрос с ЕСТЬNULL, проблема исчезнет глобально для всех отчетов.

Пример программного изменения настроек компоновки перед выводом:


Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка)
    
    // Получаем текущие настройки отчета
    Настройки = КомпоновщикНастроек.ПолучитьНастройки();
    
    // Пройдемся по отборам и модифицируем условия по булевым доп. реквизитам
    Для Каждого ЭлементОтбора Из Настройки.Отбор.Элементы Цикл
        Если ТипЗнч(ЭлементОтбора) = Тип("ЭлементОтбораКомпоновкиДанных") Тогда
             // Логика поиска нужного поля и замены вида сравнения
             // на группу ИЛИ (Ложь + Не заполнено)
        КонецЕсли;
    КонецЦикла;
    
    // Устанавливаем измененные настройки обратно
    КомпоновщикНастроек.ЗагрузитьНастройки(Настройки);

КонецПроцедуры

Особенности типов Число и Строка

Проанализируем ситуацию с другими типами данных. Для типов Число и Строка проблема стоит не так остро. Как правило, БСП записывает 0 или Пустую строку в табличную часть, если пользователь явно взаимодействовал с полем в форме объекта. Однако, если запись была создана программно без заполнения этих реквизитов, в отчетах также возникнет NULL.

Важный совет: При разработке систем, активно использующих дополнительные реквизиты для бизнес-логики, старайтесь всегда проверять поля на Заполнено / Не заполнено в отчетах. Это самый надежный способ, учитывающий оптимизированное хранение данных в 1С.

Резюме

Мы выяснили, что отсутствие значений «Нет» в отчетах — это не ошибка, а следствие оптимизации хранения данных в БСП. Для решения задачи можно:

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

← На главную