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

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

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

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

Способ 1. Реализация через параметр запроса динамического списка

Это самое простое и популярное решение, которое отлично подходит для небольших баз данных и списков с малым объемом элементов. Идея заключается в том, чтобы передавать список отмеченных ссылок в параметр запроса динамического списка и «на лету» вычислять состояние флажка.

Рассмотрим пошагово, как это реализовать:

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

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

Этот способ интуитивно понятен, но при его внедрении на реальных предприятиях разработчики часто сталкиваются с падением производительности программы.

Почему базовое решение может стать «костылем» на больших базах?

Проанализируем технические проблемы, которые возникают при использовании конструкции В (&СписокОтбора):

Способ 2. Оптимальное решение через временное хранилище

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

Вместо того чтобы при каждом клике гонять весь массив выбранных ссылок через серверные вызовы, мы сохраняем его во Временное хранилище. В параметры динамического списка (через компоновщик настроек) мы передаем только Адрес временного хранилища. На стороне сервера СУБД считывает эти данные через временную таблицу. Это позволяет разгрузить оперативную память и исключить постоянную передачу тяжелых массивов данных.

Способ 3. Имитация флажков через «Поле картинки» с одинарным кликом

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

Разберем, как это реализовать:

  1. Добавим в динамический список колонку с типом Поле картинки.
  2. В качестве источника картинки укажем системную коллекцию картинок, содержащую два состояния: «Флажок включен» и «Флажок выключен».
  3. Свойство колонки ГиперссылкаЯчейки установим в значение Истина.
  4. Теперь мы можем обрабатывать событие одинарного клика (событие Нажатие или Выбор) по этой ссылке-картинке.
  5. Для хранения состояний на клиенте будем использовать быстрый объект Соответствие, а визуальное отображение картинки в списке свяжем через условное оформление динамического списка.

Способ 4. Хранение выбора в физической таблице (для высоконагруженных систем)

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

В этом случае эффективным решением будет создание легкого вспомогательного Регистра сведений (например, ВыбранныеДокументыПользователей) со следующей структурой:

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

Способ 5. Использование штатного множественного выбора (без программирования)

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

  1. У элемента формы таблицы динамического списка установим свойство МножественныйВыбор в значение Истина.
  2. Пользователь сможет выделять необходимые строки стандартными горячими клавишами операционной системы (удерживая клавишу Ctrl для единичного выбора или Shift для выделения диапазона).
  3. Для выполнения целевого действия (например, проведение выбранных документов) добавим кнопку на командную панель, в обработчике которой получим выделенные строки одной строчкой кода: МассивВыбранныхСтрок = Элементы.Список.ВыделенныеСтроки;

Этот вариант является наиболее производительным, так как платформа 1С не делает никаких дополнительных запросов к СУБД в процессе интерактивного выделения строк пользователем, и интерфейс программы работает мгновенно.

← На главную