Как правильно настроить интерактивный флажок в табличном поле 1С, не связанном с табличной частью?

Программист 1С v8.3 (Обычные формы) IT и автоматизация бизнеса
← На главную

При разработке интерфейсов на обычных формах в 1С:Предприятии 8 программисты часто сталкиваются с задачей добавления колонки-флажка (галочки) в табличное поле. Ситуация усложняется, когда табличное поле не связано напрямую с табличной частью документа или справочника, а данные выводятся динамически или формируются программно. Попытка просто добавить колонку с типом Булево приводит к типичным ошибкам: вместо красивого флажка отображается текст «Да»/«Нет», галочка появляется только при двойном клике, либо установка одного флажка приводит к тому, что пометки проставляются сразу во всех строках таблицы.

В этой статье мы подробно разберем природу этого поведения платформы 1С и рассмотрим два надежных практических способа реализации интерактивных флажков в несвязанных колонках табличного поля.

Почему возникает проблема с отображением флажка?

Для начала проанализируем, почему платформа ведет себя подобным образом. В обычных формах элемент управления ТабличноеПоле отвечает за визуализацию данных, которые физически хранятся в связанном источнике (например, в ТаблицеЗначений или ТабличнойЧасти). Если колонка табличного поля не связана с реальным реквизитом источника данных через свойство Данные, то ячейкам этой колонки просто негде хранить свое состояние.

Когда пользователь нажимает на флажок в строке, платформа пытается записать значение Истина или Ложь в источник данных. Если источник отсутствует:

  1. Платформа не может привязать значение к конкретной строке.
  2. Визуальное состояние ячейки сбрасывается или дублируется для всего списка.
  3. При попытке редактирования система переходит в режим текстового ввода, отображая стандартное представление булева типа — «Да» или «Нет».

Чтобы решить эту задачу, мы можем пойти двумя путями: использовать промежуточный источник данных (коллекцию с добавленной колонкой) либо управлять состоянием флажков вручную с помощью событий табличного поля и внешней коллекции для хранения состояний.

---

Решение 1. Использование промежуточной Таблицы Значений (Рекомендуемый метод)

Если табличное поле предназначено для вывода информации, которую можно предварительно подготовить и загрузить целиком, самым простым и производительным решением будет использование временной ТаблицыЗначений в качестве источника данных.

Давайте разберем этот процесс по шагам:

Шаг 1. Настройка свойств колонки в конфигураторе

Откройте палитру свойств для колонки, в которой должен отображаться флажок, и установите следующие значения:

Шаг 2. Программное создание источника данных

В модуле формы при инициализации (например, в обработчике события ПриОткрытии или в собственной процедуре инициализации) мы должны подготовить ТаблицуЗначений, наполнить её данными и обязательно добавить булеву колонку для флажков. Рассмотрим пример кода:


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

При использовании этого метода нам вообще не нужно писать код в событиях табличного поля. Платформа берет на себя всю работу: отображает флажки, считывает их текущее состояние из таблицы значений и автоматически обновляет данные при клике пользователя.

---

Решение 2. Программное управление отображением (Для динамических списков)

Иногда первый способ применить невозможно. Например, если наше табличное поле отображает динамический список документов или справочников (тип значения — СправочникСписок или ДокументСписок), мы не можем добавить произвольную булеву колонку непосредственно в базу данных или в структуру динамического считывания платформы.

В этом случае состояние флажков придется хранить отдельно в переменной модуля формы, а саму отрисовку галочек и обработку кликов производить программно.

Выясним причину, почему стандартные события могут замедлять работу интерфейса. Многие разработчики используют событие ПриВыводеСтроки. Оно отлично подходит для небольших таблиц, но если в списке тысячи строк, частый вызов этого события при прокрутке экрана приведет к заметным зависаниям. Поэтому для оптимизации мы будем использовать событие ПриПолученииДанных, обрабатывающее строки пакетами.

Разберем реализацию этого подхода по шагам:

Шаг 1. Подготовка хранилища состояний

В самом верху модуля формы объявим переменную, которая будет хранить информацию о том, в каких именно строках установлен флажок. В качестве хранилища оптимально использовать объект Соответствие, где ключом будет уникальный идентификатор строки (например, ссылка на элемент списка), а значением — булево Истина.

Перем ОтмеченныеСтроки; // Переменная будет хранить объект Соответствие

Инициализируем её при открытии формы:


Процедура ПриОткрытии()
    ОтмеченныеСтроки = Новый Соответствие;
КонецПроцедуры

Шаг 2. Отрисовка флажков в событии ПриПолученииДанных

Создадим обработчик события ПриПолученииДанных для нашего табличного поля. В этом событии мы пробегаемся по массиву оформлений строк, которые в данный момент видны на экране пользователя, и принудительно включаем отображение флажка:


Процедура ТабличноеПоле1ПриПолученииДанных(Элемент, ОформленияСтрок)
    
    Для Каждого ОформлениеСтроки Из ОформленияСтрок Цикл
        
        ДанныеСтроки = ОформлениеСтроки.ДанныеСтроки;
        Если ДанныеСтроки = Неопределено Тогда
            Продолжить;
        КонецЕсли;
        
        // Получаем ячейку, в которой хотим видеть флажок
        Ячейка = ОформлениеСтроки.Ячейки.КолонкаФлажка;
        
        // Отключаем текстовое представление, чтобы не выводилось "Да/Нет"
        Ячейка.ОтображатьТекст = Ложь;
        
        // Говорим платформе отображать флажок в ячейке
        Ячейка.ОтображатьФлажок = Истина;
        
        // Проверяем, отмечена ли текущая строка в нашем соответствии
        СсылкаНаОбъект = ДанныеСтроки.Ссылка;
        Если ОтмеченныеСтроки.Получить(СсылкаНаОбъект) = Истина Тогда
            Ячейка.Флажок = Истина;
        Иначе
            Ячейка.Флажок = Ложь;
        КонецЕсли;
        
    КонецЦикла;
    
КонецПроцедуры

Шаг 3. Обработка интерактивного изменения флажка

Теперь нам нужно сделать так, чтобы при клике на флажок его состояние менялось и запоминалось в нашем соответствии. Для этого используется событие табличного поля ПриИзмененииФлажка:


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

Рассмотренный второй метод позволяет организовывать работу с пометками элементов в любых динамических списках без изменения структуры метаданных конфигурации. Этот паттерн программирования часто применяется при разработке различных групповых обработок справочников или документов в типовых решениях на обычных формах (например, в Управлении производственным предприятием ред. 1.3 или Управлении торговлей ред. 10.3).

Оба этих метода являются стандартными, надежными и гарантируют корректную работу пользовательского интерфейса без "залипаний" флажков или нежелательных текстовых надписей.

← На главную