Как правильно добавить колонку с флажками на обычную форму в 1С и победить отображение текста «Да/Нет»

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

Работа с обычными формами в 1С:Предприятии 8 сегодня у многих разработчиков вызывает легкую ностальгию, смешанную с растерянностью. Стандарты управляемого интерфейса приучили нас к тому, что платформа берет на себя большинство рутинных задач по отрисовке интерфейса. Возвращаясь к классическому интерфейсу («обычным формам»), мы мгновенно сталкиваемся с неочевидным поведением стандартных элементов управления.

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

  1. При попытке установить флажок в динамическом списке (СправочникСписок) система настырно пытается открыть карточку элемента справочника.
  2. Если для решения этой проблемы использовать Таблицу Значений (ТаблицаЗначений), то вместо аккуратного флажка в ячейке выводится текстовое представление булева значения: «Да» или «Нет» («Истина»/«Ложь»).

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

---

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

Рассмотрим ситуацию, когда мы решили отказаться от динамического списка в пользу обычной Таблицы Значений (ТЗ), размещенной на форме. Нам нужно заполнить ее данными, дать пользователю возможность интерактивно проставлять флажки и при этом избежать появления раздражающих надписей «Да» и «Нет» при потере фокуса ячейкой.

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

  1. Откроем свойства колонки «Пометка» в свойствах табличного поля формы.
  2. Поле свойства Данные оставляем абсолютно пустым. Это критически важно! Если здесь указать имя колонки ТЗ (например, Пометка), платформа при потере фокуса ячейкой будет упорно выводить текст.
  3. В свойстве ЭлементУправления выбираем значение Флажок.
  4. В свойстве ДанныеФлажка указываем имя нашей колонки из Таблицы Значений — Пометка. Таким образом, колонка будет связана с данными ТЗ только по значению флажка, игнорируя текстовое представление.
  5. Для свойства РежимРедактирования выбираем значение Непосредственно. Это позволит пользователю менять состояние флажка в один клик мыши без предварительной активации строки и входа в режим редактирования ячейки.

Поскольку свойство Данные у колонки теперь пустое, стандартное событие колонки ПриИзменении вызываться не будет. Если вам необходимо выполнять какие-то действия в коде сразу в момент клика по флажку (например, динамически пересчитывать итоги или проверять условия), используем событие самого табличного поля ПриИзмененииФлажка:


Процедура ТабличноеПолеПриИзмененииФлажка(Элемент, Колонка)
    Если Колонка.Имя = "Пометка" Тогда
        // Значение в Элемент.ТекущиеДанные.Пометка уже автоматически изменилось.
        // Здесь мы можем прописать сопутствующую логику:
        ТекущаяСтрока = Элемент.ТекущиеДанные;
        Если ТекущаяСтрока.Пометка Тогда
            Сообщить("Пользователь выбрал элемент: " + СокрЛП(ТекущаяСтрока.Ссылка));
        КонецЕсли;
    КонецЕсли;
КонецПроцедуры

---

Вариант 2. Программное управление отображением ячеек ТЗ через события отрисовки

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

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


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

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

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

Разберем пример реализации через пакетную обработку строк:


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

---

Вариант 3. Использование динамического списка «СправочникСписок» с виртуальным флагом

Вернемся к первоначальной задаче автора темы. Что делать, если мы принципиально не хотим отказываться от динамического списка СправочникСписок? Ведь динамический список чрезвычайно удобен: он обеспечивает быструю порционную выборку данных из базы, поддерживает стандартные отборы, сортировки и поиск, не требуя полной загрузки всей базы в оперативную память сервера и клиента.

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

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

Разберем этот алгоритм по шагам.

Шаг 1. Подготовка формы и переменных

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

Мы объявим переменную на уровне модуля формы. В качестве структуры хранения идеально подойдет объект Соответствие, поскольку поиск по ключу в нем происходит практически мгновенно.


Перем СоответствиеВыбранныхЭлементов;

Процедура ПриОткрытии()
    // Инициализируем хранилище при открытии формы
    СоответствиеВыбранныхЭлементов = Новый Соответствие;
КонецПроцедуры

Шаг 2. Добавление виртуальной колонки

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

Шаг 3. Отрисовка состояния виртуальных флагов

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


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

Шаг 4. Перехват клика и блокировка стандартного открытия карточки

Теперь решим ключевую проблему — заблокируем открытие формы элемента при клике по колонке с пометкой. Для этого идеально подходит событие табличного поля ПередНачаломИзменения. Установив флаг Отказ = Истина, мы предотвращаем стандартную реакцию платформы и вместо этого меняем значение в нашем соответствии:


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

Благодаря вызову метода Элемент.ОбновитьСтроки() система мгновенно инициирует событие отрисовки, и пользователь сразу увидит изменившийся статус флажка без каких-либо задержек и артефактов.

---

Резюме и рекомендации

Мы детально изучили внутренние механизмы работы с флажками на обычных формах 1С. Подведем итог, какой подход выбрать в зависимости от архитектурных требований:

← На главную