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