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