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