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