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