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