При разработке управляемых форм в 1С часто возникает задача динамически скрыть определенные строки в таблице или дереве значений. Одним из частых приемов разработчиков является использование механизма УсловноеОформление со свойством Видимость = Ложь. Однако при перемещении по строкам с помощью клавиатуры можно столкнуться с неприятным поведением: пропадает шапка таблицы, сбивается прокрутка, а курсор застревает на невидимых строках.
Разберем подробно причины такого поведения платформы, способы настройки условного оформления, методы обхода сбоев фокуса и архитектурно правильные способы фильтрации строк.
Рассмотрим по шагам, как заставить строки визуально скрываться с помощью условного оформления формы или таблицы:
Видимость и снимем для него значение (установим в Ложь).Проанализируем механику работы платформы 1С:Предприятие. Свойство Видимость = Ложь в условном оформлении скрывает отрисовку ячеек, но физически строка не удаляется из коллекции данных на клиенте. Когда пользователь нажимает клавиши со стрелками «Вверх» или «Вниз», фокус пытается переключиться на скрытую строку. В этот момент табличный элемент не может корректно рассчитать геометрию отрисовки фокуса, что приводит к исчезновению заголовков колонок и зависанию таблицы.
Попытка изменить текущую строку внутри обработчика ПриАктивизацииСтроки не дает результата, так как во время выполнения этого события платформа блокирует переопределение свойства Элементы.Таблица.ТекущаяСтрока до завершения цикла смены фокуса.
Выясним причину, почему перехват в ячейке работает корректно. В отличие от строки, при смене фокуса ячейки цикл перерисовки находится на другом этапе. Переопределив текущую строку в событии ПриАктивизацииЯчейки, можно автоматически перебросить пользователя на следующую или предыдущую видимую строку.
Посмотрим на пример клиентского кода:
&НаКлиенте
Процедура ТаблицаПриАктивизацииЯчейки(Элемент)
ТекущиеДанные = Элемент.ТекущиеДанные;
Если ТекущиеДанные = Неопределено Тогда
Возврат;
КонецЕсли;
// Проверяем условие, при котором строка скрыта
Если Не СтрокаЯвляетсяВидимой(ТекущиеДанные) Тогда
// Сбрасываем фокус или смещаем его на подходящую строку
Элемент.ТекущаяСтрока = ПолучитьИдентификаторБлижайшейВидимойСтроки();
КонецЕсли;
КонецПроцедуры
Если расчет следующей строки сложен, можно просто сбросить фокус, что предотвратит исчезновение шапки таблицы:
&НаКлиенте
Процедура ТаблицаПриАктивизацииЯчейки(Элемент)
Если Элемент.ТекущиеДанные <> Неопределено И Элемент.ТекущиеДанные.ЭтоСкрытаяСтрока Тогда
Элементы.Таблица.ТекущаяСтрока = Неопределено;
КонецЕсли;
КонецПроцедуры
Нередко разработчики пытаются управлять доступностью или видимостью строк через обход данных в цикле, например:
Для Каждого Стр Из Объект.Инвентарь Цикл
Если Найти(Строка(Стр.Номенклатура), СтрокаПоиска) >= 1 Тогда
Стр.Доступность = Истина; // Вызовет ошибку!
Иначе
Стр.Доступность = Ложь;
КонецЕсли;
КонецЦикла;
Выясним причину ошибки: объекты коллекций данных (ДанныеФормыКоллекция, ДанныеФормыДерево, ТабличнаяЧасть) содержат только прикладные реквизиты (колонки данных). Свойства Доступность, Видимость и ЦветФона принадлежат исключительно элементам интерфейса или настраиваются через УсловноеОформление.
Управлять доступностью конкретной строки можно через добавление соответствующего правила в условное оформление:
// Программное добавление правила оформления доступности
ЭлементОформления = УсловноеОформление.Элементы.Добавить();
ПолеОформления = ЭлементОформления.Поля.Элементы.Добавить();
ПолеОформления.Поле = Новый ПолеКомпоновкиДанных("Инвентарь");
ОтборОформления = ЭлементОформления.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
ОтборОформления.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("Объект.Инвентарь.ПометкаУдаления");
ОтборОформления.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно;
ОтборОформления.ПравоеЗначение = Истина;
ЭлементОформления.Оформление.УстановитьЗначениеПараметра("Доступность", Ложь);
Согласно стандартам разработки 1С, условное оформление не рекомендуется использовать как замену полноценной фильтрации, так как скрытые строки продолжают обрабатываться клиентским приложением и замедляют форму. Если для табличной части можно применить ОтборСтрок, то для реквизитов типа ДеревоЗначений или ТаблицаЗначений рекомендуется применять другие шаблоны.
ЗначениеВРеквизитФормы().