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