Как в 1С при выборе элементов списка значений добавить кнопки «Выделить все» и «Снять выделение»?

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

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

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

Способ 1. Пользовательский лайфхак (без программирования)

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

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

  1. Пользователю достаточно щелкнуть мышью по любому элементу в открывшемся списке.
  2. Нажать стандартную комбинацию клавиш Ctrl + A (это выделит все строки списка синим цветом).
  3. Нажать клавишу Пробел.

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

Способ 2. Оптимальный вариант с собственной формой и методом ЗаполнитьПометки()

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

Для реализации этого решения выполним следующие шаги:

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

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

Для быстрого управления пометками у объекта СписокЗначений существует встроенный высокопроизводительный метод, работающий непосредственно на уровне платформы. Рассмотрим пример правильного кода для модулей нашей формы:


&НаКлиенте
Процедура ВыделитьВсеЭлементы(Команда)
    // Быстро устанавливаем галочки для всех элементов списка
    СписокДляВыбора.ЗаполнитьПометки(Истина);
КонецПроцедуры

&НаКлиенте
Процедура СнятьВсеВыделения(Команда)
    // Быстро снимаем галочки со всех элементов списка
    СписокДляВыбора.ЗаполнитьПометки(Ложь);
КонецПроцедуры

Использование встроенного метода ЗаполнитьПометки() позволяет мгновенно обрабатывать списки любой длины без зависания интерфейса клиентского приложения.

Способ 3. Современный асинхронный подход (Платформа 8.3.18 и выше)

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

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

Рассмотрим, как выглядит вызов асинхронного метода выбора:


&НаКлиенте
Асинх Процедура ВыбратьАдресаДляРассылки()
    
    СписокАдресов = ПолучитьСписокПочтовыхАдресовНаСервере();
    
    // Вызываем асинхронное окно разметки элементов
    РезультатВыбора = Ждать СписокАдресов.ОтметитьЭлементыАсинх("Выберите адреса получателей");
    
    Если РезультатВыбора <> Неопределено Тогда
        // РезультатВыбора содержит список значений с установленными пометками
        Для Каждого Элемент Из РезультатВыбора Цикл
            Если Элемент.Пометка Тогда
                Сообщить("Выбран адрес: " + Элемент.Значение);
            КонецЕсли;
        КонецЦикла;
    КонецЕсли;
    
КонецПроцедуры

Этот код лаконичен, безопасен для веб-клиента и полностью соответствует современным стандартам разработки фирмы «1С».

Способ 4. Использование готовых инструментов БСП

Зачем изобретать велосипед и тратить время на рисование собственных диалоговых окон, если в вашей конфигурации установлена БСП (Библиотека стандартных подсистем)? В типовых решениях (таких как УТ, ERP, КА, УНФ) уже есть отличные универсальные формы, спроектированные специально для решения подобных задач.

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

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


&НаКлиенте
Процедура ВыбратьЭлементыЧерезБСП()
    
    // Заполняем исходный список значений данными
    ПараметрыСписка = Новый СписокЗначений;
    ПараметрыСписка.Добавить("Адрес_1", "Офис на Севере", Ложь);
    ПараметрыСписка.Добавить("Адрес_2", "Склад Центр", Истина);
    ПараметрыСписка.Добавить("Адрес_3", "Филиал Запад", Ложь);
    
    // Формируем параметры для открытия общей формы БСП
    ПараметрыФормы = Новый Структура;
    ПараметрыФормы.Вставить("СписокЗначений", ПараметрыСписка);
    ПараметрыФормы.Вставить("Заголовок", "Выберите склады для инвентаризации");
    
    // Задаем описание оповещения для обработки результата
    Оповещение = Новый ОписаниеОповещения("ПослеВыбораЭлементовБСП", ЭтотОбъект);
    
    // Открываем готовую форму выбора из состава БСП
    ОткрытьФорму("ОбщаяФорма.ВыборЭлементов", ПараметрыФормы, ЭтотОбъект,,,, Оповещение);
    
КонецПроцедуры

&НаКлиенте
Процедура ПослеВыбораЭлементовБСП(РезультатВыбора, ДополнительныеПараметры) Экспорт
    
    Если РезультатВыбора <> Неопределено Тогда
        // В РезультатВыбора возвращается измененный список значений
        Для Каждого Элемент Из РезультатВыбора Цикл
            Если Элемент.Пометка Тогда
                ПоказатьПредупреждение(, "Выбран элемент: " + Элемент.Представление);
            КонецЕсли;
        КонецЦикла;
    КонецЕсли;
    
КонецПроцедуры

Использование готовых форм БСП существенно сокращает время разработки, снижает количество ошибок в коде и обеспечивает единый, привычный для пользователей интерфейс во всей системе.

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

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

Давайте детально разберем эту логику:

  1. В запросе динамического списка мы создаем вычисляемое поле, которое определяет состояние флажка на основании параметра-массива &СписокОтмеченных.
  2. При нажатии пользователем на колонку с флажком мы программно добавляем или удаляем идентификатор строки из массива и обновляем параметр списка.

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


ВЫБРАТЬ
    ВЫБОР
        КОГДА СправочникСклады.Ссылка В (&СписокОтмеченных) ТОГДА ИСТИНА
        ИНАЧЕ ЛОЖЬ
    КОНЕЦ КАК Отметка,
    СправочникСклады.Ссылка КАК Ссылка,
    СправочникСклады.Наименование КАК Наименование
ИЗ
    Справочник.Склады КАК СправочникСклады

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


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

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

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

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

← На главную