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

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

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

В чем заключается основная проблема виртуальных колонок

В отличие от Управляемых форм, где динамический список работает иначе, в обычных формах ТабличноеПоле (связанное с типом ДокументСписок) отображает данные непосредственно из базы. Если мы просто добавим колонку в форму, 1С не будет знать, где хранить состояние флажка при прокрутке списка или его обновлении. Как только строка исчезает из поля зрения, ее визуальное состояние сбрасывается. Поэтому нам необходимо создать собственное хранилище в памяти формы.

Шаг 1: Подготовка хранилища данных (Соответствие)

Для хранения состояния флажков идеально подходит объект Соответствие. Мы будем использовать Ссылку на документ в качестве Ключа и Булево значение в качестве Значения флажка. Проанализируем, почему важно использовать именно ссылку: если использовать какой-либо другой признак (например, просто значение реквизита), то флажок будет меняться сразу у всех строк с таким же признаком.

В модуле формы объявим переменную:

Перем мКэшФлажков; // Переменная для хранения состояний флажков

Инициализируем ее в процедуре ПриОткрытии:


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

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

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

Разберем реализацию:


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

Шаг 3: Интерактивное изменение состояния

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

Проанализируем алгоритм обработки клика:


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

Типичные ошибки при работе с виртуальными флажками

Рассмотрим ситуации, в которых новички часто допускают промахи:

  1. Использование переменных в ПриОткрытии: Попытка заполнить флажки циклом по всему списку в момент открытия формы. Если документов тысячи, это приведет к зависанию системы. Правильный подход — ленивая инициализация в ПриПолученииДанных, только для видимых строк.
  2. Неверный ключ в Соответствии: Использование булева значения или строки вместо Ссылка. Ключ должен быть уникальным идентификатором объекта базы данных.
  3. Тяжелые запросы в отрисовке: Выполнение запросов к базе внутри цикла Для Каждого ОформлениеСтроки. Это катастрофически замедляет прокрутку списка. Все необходимые данные должны быть либо уже в колонках списка, либо получены заранее одним запросом.
  4. Забытая очистка кэша: Если список фильтруется или обновляется программно, иногда требуется очистить мКэшФлажков, чтобы значения пересчитались заново.

Дополнительные рекомендации

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

Таким образом, мы выяснили, что связка ПриПолученииДанных + Соответствие(Ссылка) + ПриИзмененииФлажка является эталонным способом работы с виртуальными данными в списках 1С на обычных формах. Этот метод обеспечивает высокую производительность и корректное поведение интерфейса при любых манипуляциях пользователя.

← На главную