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

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

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

Почему стандартный подход с ПриВыводеСтроки не всегда работает

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

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

Шаг 1: Создание хранилища состояний

Поскольку наш флажок — это временная пометка, существующая только пока открыта форма, нам нужно где-то хранить информацию о том, для каких документов галочка установлена, а для каких — нет. Лучшим инструментом для этого в 1С является объект Соответствие.

Рассмотрим, как инициализировать такое хранилище. В модуле формы в самом верху (в разделе описания переменных) определим переменную, которая будет доступна во всех процедурах формы:

Перем СоответствиеПометок;

Затем в процедуре ПриОткрытии создадим сам объект:


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

В этом соответствии ключом будет Ссылка на документ, а значением — булево (Истина или Ложь).

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

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

Разберем программный код для отображения флажков:


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

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

Шаг 3: Обработка клика пользователя

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

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


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

Обратите внимание: если вы хотите, чтобы флажок менялся "в один клик", убедитесь, что в свойствах колонки параметр РежимРедактирования установлен в значение Непосредственно. Если оставить "Вход при вводе", пользователю придется кликнуть дважды (первый клик активирует ячейку, второй переключит флаг).

Шаг 4: Дополнительные советы и оптимизация

Рассмотрим несколько продвинутых моментов, которые сделают вашу работу с флажками профессиональной:

  1. Событие "Выбор": Если вы хотите, чтобы флажок менялся не только при клике на сам квадратик, но и при двойном клике по ячейке или нажатии Enter, используйте событие Выбор. В нем нужно установить СтандартнаяОбработка = Ложь, чтобы не открывалась форма документа.
  2. Предустановка значений: Если при открытии формы некоторые документы уже должны быть помечены (например, на основании какого-то условия в БД), вы можете заполнить СоответствиеПометок запросом прямо в процедуре ПриОткрытии.
  3. Очистка памяти: Если список документов очень большой и пользователь долго с ним работает, Соответствие может накапливать ссылки. Если это критично, можно удалять из соответствия элементы со значением Ложь, используя метод Удалить(). Тогда в коллекции будут храниться только "Истинные" пометки.

Посмотрим на пример того, как можно проверить, какие документы в итоге выбрал пользователь (например, по нажатию кнопки "Выполнить"):


Процедура КнопкаВыполнитьНажатие(Кнопка)
    
    МассивВыбранныхДокументов = Новый Массив;
    
    // Обходим наше соответствие
    Для Каждого Запись Из СоответствиеПометок Цикл
        Если Запись.Значение = Истина Тогда
            МассивВыбранныхДокументов.Добавить(Запись.Ключ);
        КонецЕсли;
    КонецЦикла;
    
    Если МассивВыбранныхДокументов.Количество() = 0 Тогда
        Сообщить("Ни один документ не выбран!");
        Возврат;
    КонецЕсли;
    
    // Далее логика обработки массива документов...
    
КонецПроцедуры

Таким образом, мы разделили визуальное представление (в событиях списка) и логику хранения данных (в переменной формы). Это надежный и классический способ реализации временных пометок в 1С 8.2/8.3 на обычных формах.

← На главную