Почему в 1С не работает поиск по значению "Нет" для булева реквизита в списке?

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

Часто пользователи и разработчики сталкиваются с неочевидным поведением системы 1С: в форме списка поиск по дополнительному реквизиту типа "Булево" отлично находит все записи со значением "Да", но полностью игнорирует попытки найти записи со значением "Нет". Может показаться, что это ошибка, но на самом деле это следствие особого механизма хранения данных в платформе. Давайте разберемся, почему так происходит и как с этим работать.

Проанализируем типичную ситуацию: в справочнике "Номенклатура" в конфигурации 1С:УНФ есть дополнительный реквизит, например, "Акционный товар", с типом "Булево". В списке номенклатуры мы видим колонку, где у некоторых товаров стоит "Да", а у остальных — "Нет". При вводе "Да" в строку поиска список корректно фильтруется. Но при вводе "Нет" список остается пустым, хотя визуально такие строки есть.

Выясним причину: как 1С хранит незаполненные значения

Ключ к пониманию проблемы кроется в оптимизации хранения данных. Когда вы создаете новый дополнительный реквизит (доп. реквизит) типа "Булево", система не создает автоматически для всех существующих элементов справочника запись в базе данных со значением Ложь ("Нет"). Это было бы избыточно и привело бы к значительному росту объема базы данных, особенно на больших справочниках.

Вместо этого, запись о значении доп. реквизита для конкретного элемента создается только тогда, когда пользователь впервые взаимодействует с этим реквизитом:

  1. Устанавливает флажок в положение "Да" (Истина) и сохраняет элемент. В базе данных появляется запись: {Элемент, Свойство, Значение = Истина}.
  2. Сначала устанавливает флажок, а затем снимает его и сохраняет. В этом случае в базе данных появится запись: {Элемент, Свойство, Значение = Ложь}.

Что же происходит с теми элементами, у которых этот флажок никогда не трогали? Для них в таблице значений дополнительных реквизитов просто отсутствует какая-либо запись. С точки зрения языка запросов 1С, при попытке получить значение этого реквизита мы получим не Ложь, а NULL.

Таким образом, у нас есть два разных состояния, которые визуально отображаются как "Нет":

Стандартный поиск в форме списка, когда вы вводите текст "Нет", ищет только записи, где значение явно равно Ложь. Он не умеет интерпретировать NULL как "Нет", поэтому и не находит те элементы, которые никогда не редактировались. Поиск по "Да" работает без проблем, так как он ищет явное значение Истина, которое всегда записывается в базу.

Решение 1: Корректная настройка отбора в пользовательском режиме

Самый правильный и простой способ найти все элементы, где флажок не установлен (и те, где он явно снят, и те, что не трогали), — это использовать стандартный механизм настройки списка. Этот способ подходит как обычным пользователям, так и администраторам.

Разберем по шагам, как настроить отбор:

  1. Откройте нужную форму списка (например, справочник "Номенклатура").
  2. В правом верхнем углу списка нажмите на кнопку "Еще" и выберите пункт "Настроить список...".
  3. В открывшемся окне перейдите на вкладку "Отбор".
  4. Нажмите на кнопку "Добавить новый элемент".
  5. В колонке "Поле" нажмите на кнопку выбора (...) и найдите ваш дополнительный реквизит (например, "Акционный товар").
  6. В колонке "Вид сравнения" установите значение "Не заполнено".
  7. Нажмите кнопку "Завершить редактирование".

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

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

Решение 2: Программная доработка для разработчиков

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

Для этого в языке запросов 1С существует специальная функция ЕСТЬNULL(). Она проверяет, является ли первое переданное ей значение NULL, и если да, то заменяет его вторым переданным значением.

Посмотрим на пример. Предположим, у вас есть запрос, который через ЛЕВОЕ СОЕДИНЕНИЕ получает значение дополнительного реквизита из регистра сведений.

Изначальный вариант запроса (некорректный для поиска по "Нет"):


ВЫБРАТЬ
    Номенклатура.Ссылка,
    ЗначенияСвойств.Значение КАК АкционныйТовар
ИЗ
    Справочник.Номенклатура КАК Номенклатура
        ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ЗначенияСвойствОбъектов КАК ЗначенияСвойств
        ПО Номенклатура.Ссылка = ЗначенияСвойств.Объект
            И ЗначенияСвойств.Свойство = &СвойствоАкционныйТовар

В этом случае поле АкционныйТовар будет содержать Истина, Ложь или NULL. Чтобы избавиться от NULL, нужно обернуть поле ЗначенияСвойств.Значение в функцию ЕСТЬNULL().

Исправленный вариант запроса:


ВЫБРАТЬ
    Номенклатура.Ссылка,
    ЕСТЬNULL(ЗначенияСвойств.Значение, ЛОЖЬ) КАК АкционныйТовар
ИЗ
    Справочник.Номенклатура КАК Номенклатура
        ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ЗначенияСвойствОбъектов КАК ЗначенияСвойств
        ПО Номенклатура.Ссылка = ЗначенияСвойств.Объект
            И ЗначенияСвойств.Свойство = &СвойствоАкционныйТовар

Теперь, если для какой-то номенклатуры не найдено записи в регистре ЗначенияСвойствОбъектов, запрос вернет не NULL, а значение ЛОЖЬ. Динамический список получит уже подготовленные, однородные данные, и стандартный поиск по строке "Нет" начнет корректно работать, находя все нужные элементы.

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

← На главную