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