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