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