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

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

При работе с динамическими списками в управляемых формах 1С:Предприятие разработчики часто сталкиваются с ситуацией, когда стандартный поиск по текущему значению (горячие клавиши Ctrl+Alt+F) или обычная фильтрация работают с ошибками. В частности, при попытке отфильтровать список по вычисляемому реквизиту со значением «Нет» фильтрация либо не срабатывает, либо визуально подменяет значения в остальных строках таблицы.

Рассмотрим подробно причины возникновения такой проблемы, проанализируем механизм работы платформы при выполнении быстрых отборов и разберем проверенные способы решения данной задачи.

Суть проблемы и причины сбоя

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

ЕСТЬNULL(ЗаказДоговорНапечатан.ДоговорНапечатан, ЛОЖЬ) КАК ДоговорНапечатан

Внешне динамический список отображает данные корректно: для одних строк выводится «Да» (ИСТИНА), для других — «Нет» (ЛОЖЬ). Однако при активации быстрого поиска по ячейке со значением «Нет» список ведет себя непредсказуемо: выводятся все строки, но значение «Да» в нерелевантных строках визуально подменяется на «Нет».

Выясним причину такого поведения платформы. Здесь действуют два ключевых фактора:

  1. Неопределенность типов в системе компоновки данных (СКД): Если поле формируется через ЛЕВОЕ СОЕДИНЕНИЕ, СКД может определить составной тип данных для виртуального поля — Булево и NULL. При наложении отбора «по текущему значению» платформа на клиенте пытается принудительно привести отображение строки к значению фильтра, из-за чего происходит сбой клиентского кэша.
  2. Особенности трехзначной логики SQL: При формировании быстрого отбора платформа генерирует SQL-запрос. Если фильтрация накладывается непосредственно на присоединяемую таблицу без специальных указаний для СКД, условие вида Таблица.Поле = ЛОЖЬ при наличии значений NULL возвращает результат UNKNOWN. В итоге строки с отсутствующими записями полностью отсекаются, а сам отбор отрабатывает неверно.

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

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

  1. Откроем конструктор запроса динамического списка.
  2. Перейдем на закладку Компоновка данных, затем на вкладку Поля.
  3. Для вычисляемого поля укажем синтаксис компоновки данных в поле текста запроса, выделив правильную конструкцию отбора в фигурных скобках.

Текст запроса динамического списка должен иметь следующий вид:


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

В данном случае секция {ГДЕ ...} явно указывает системе компоновки данных, какое именно выражение необходимо использовать при наложении быстрых и пользовательских отборов.

Способ 2. Замена конструкции ЕСТЬNULL на явный оператор ВЫБОР КОГДА

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

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


ВЫБОР
    КОГДА ЗаказДоговорНапечатан.ДоговорНапечатан ИСТИНА
        ТОГДА ИСТИНА
    ИНАЧЕ ЛОЖЬ
КОНЕЦ КАК ДоговорНапечатан

Поскольку выражение возвращает либо ИСТИНА, либо ЛОЖЬ, система компоновки данных однозначно определяет тип поля как Булево. При использовании быстрого поиска Ctrl+Alt+F платформа корректно накладывает отборы и не искажает данные в клиентском интерфейсе.

Способ 3. Явное ограничение типа поля в настройках СКД

Посмотрим на альтернативный вариант настройки типа поля без изменения текста самого SQL-запроса:

  1. Откроем настройки динамического списка в конфигураторе 1С.
  2. В конструкторе запроса перейдем на закладку Компоновка данных → Поля.
  3. В строке с полем ДоговорНапечатан откроем колонку Тип и снимем флаг с типа NULL, оставив только Булево.

Это действие запрещает платформе трактовать поле как составное, что устраняет визуальные сбои при кешировании данных на форме.

Альтернативные варианты отображения и фильтрации

В некоторых сложных архитектурных решениях динамического списка оптимальнее вынести визуальную логику за пределы SQL-запроса:

  1. Условное оформление формы: В запрос динамического списка выводится исходный реквизит присоединенной таблицы без применения ЕСТЬNULL. На форме создается условное оформление, которое при отсутствии значения или значении ЛОЖЬ подставляет нужный текст или скрывает флажок.
  2. Перевод соединения во ВНУТРЕННЕЕ СОЕДИНЕНИЕ: Если данные в присоединенной таблице обязаны присутствовать для каждого документа, замените ЛЕВОЕ СОЕДИНЕНИЕ на ВНУТРЕННЕЕ СОЕДИНЕНИЕ. Это исключит появление значений NULL на уровне базовой таблицы.
  3. Использование явных элементов отбора на форме: Если стандартный быстрый поиск нестабилен на конкретной версии платформы, установите для колонки свойство ВключитьСочетанияКлавишПоиска = Ложь и вынесите на форму отдельный флаг или переключатель, управляющий коллекцией Список.Отбор.Элементы программно.
← На главную