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