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