При работе с динамическими списками в управляемых формах 1С:Предприятие разработчики часто сталкиваются с ситуацией, когда стандартный поиск по текущему значению (горячие клавиши Ctrl+Alt+F) или обычная фильтрация работают с ошибками. В частности, при попытке отфильтровать список по вычисляемому реквизиту со значением «Нет» фильтрация либо не срабатывает, либо визуально подменяет значения в остальных строках таблицы.
Рассмотрим подробно причины возникновения такой проблемы, проанализируем механизм работы платформы при выполнении быстрых отборов и разберем проверенные способы решения данной задачи.
Проанализируем типичный сценарий. В динамический список выводится список документов (например, заказов клиентов) с реквизитом из присоединенной таблицы через левое соединение. Для обработки отсутствующих значений (когда запись в присоединенной таблице отсутствует) разработчик использует конструкцию ЕСТЬNULL:
ЕСТЬNULL(ЗаказДоговорНапечатан.ДоговорНапечатан, ЛОЖЬ) КАК ДоговорНапечатан
Внешне динамический список отображает данные корректно: для одних строк выводится «Да» (ИСТИНА), для других — «Нет» (ЛОЖЬ). Однако при активации быстрого поиска по ячейке со значением «Нет» список ведет себя непредсказуемо: выводятся все строки, но значение «Да» в нерелевантных строках визуально подменяется на «Нет».
Выясним причину такого поведения платформы. Здесь действуют два ключевых фактора:
ЛЕВОЕ СОЕДИНЕНИЕ, СКД может определить составной тип данных для виртуального поля — Булево и NULL. При наложении отбора «по текущему значению» платформа на клиенте пытается принудительно привести отображение строки к значению фильтра, из-за чего происходит сбой клиентского кэша.Таблица.Поле = ЛОЖЬ при наличии значений NULL возвращает результат UNKNOWN. В итоге строки с отсутствующими записями полностью отсекаются, а сам отбор отрабатывает неверно.Разберем по шагам основной способ решения проблемы без изменения логики запроса. Нам необходимо явно указать платформе, как именно строить предложение ГДЕ при фильтрации по данному полю.
Текст запроса динамического списка должен иметь следующий вид:
ВЫБРАТЬ
ЗаказКлиента.Ссылка КАК Ссылка,
ЗаказКлиента.Номер КАК Номер,
ЕСТЬNULL(ЗаказДоговорНапечатан.ДоговорНапечатан, ЛОЖЬ) КАК ДоговорНапечатан
ИЗ
Документ.ЗаказКлиента КАК ЗаказКлиента
ЛЕВОЕ СОЕДИНЕНИЕ РегионСведений.ДоговорыНапечатаны КАК ЗаказДоговорНапечатан
ПО ЗаказДоговорНапечатан.Заказ = ЗаказКлиента.Ссылка
{ГДЕ
ЕСТЬNULL(ЗаказДоговорНапечатан.ДоговорНапечатан, ЛОЖЬ) КАК ДоговорНапечатан}
В данном случае секция {ГДЕ ...} явно указывает системе компоновки данных, какое именно выражение необходимо использовать при наложении быстрых и пользовательских отборов.
Рассмотрим еще один надежный способ, позволяющий избавить СКД от составного типа данных. Замена ЕСТЬNULL на конструкцию ВЫБОР КОГДА гарантирует, что поле всегда будет иметь строго единственный тип Булево без возможности появления NULL.
Изменим выражение запроса динамического списка следующим образом:
ВЫБОР
КОГДА ЗаказДоговорНапечатан.ДоговорНапечатан ИСТИНА
ТОГДА ИСТИНА
ИНАЧЕ ЛОЖЬ
КОНЕЦ КАК ДоговорНапечатан
Поскольку выражение возвращает либо ИСТИНА, либо ЛОЖЬ, система компоновки данных однозначно определяет тип поля как Булево. При использовании быстрого поиска Ctrl+Alt+F платформа корректно накладывает отборы и не искажает данные в клиентском интерфейсе.
Посмотрим на альтернативный вариант настройки типа поля без изменения текста самого SQL-запроса:
ДоговорНапечатан откроем колонку Тип и снимем флаг с типа NULL, оставив только Булево.Это действие запрещает платформе трактовать поле как составное, что устраняет визуальные сбои при кешировании данных на форме.
В некоторых сложных архитектурных решениях динамического списка оптимальнее вынести визуальную логику за пределы SQL-запроса:
ЕСТЬNULL. На форме создается условное оформление, которое при отсутствии значения или значении ЛОЖЬ подставляет нужный текст или скрывает флажок.ЛЕВОЕ СОЕДИНЕНИЕ на ВНУТРЕННЕЕ СОЕДИНЕНИЕ. Это исключит появление значений NULL на уровне базовой таблицы.ВключитьСочетанияКлавишПоиска = Ложь и вынесите на форму отдельный флаг или переключатель, управляющий коллекцией Список.Отбор.Элементы программно.