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