Сегодня мы рассмотрим, как
реализована работа с подчиненными справочниками
на уровне встроенного языка и конфигуратора.
Чтобы справочник А сделать подчиненным
справочнику Б - надо в режиме Конфигуратор в
свойствах справочника А в поле "Подчинен" -
выбрать справочник Б. Этого будет достаточно.
При работе с подчиненным справочником
появляется один важный метод: «Использовать
Владельца» и важный атрибут «Владелец».
Метод «ИспользоватьВладельца» - может
применяться к объектам типа «Справочник» в
нескольких случаях:
1. В качестве параметра выборки.
Применяется для объектов полученных с помощью
функции «СоздатьОбъект», являющихся
подчиненными справочниками. Метод используется
ДО метода «ВыбратьЭлементы». Дальнейшая выборка
элементов с помощью функции ПолучитьЭлемент()
будет происходить только среди элементов
подчиненного справочника, для которых
владельцем является элемент, установленный
методом «ИспользоватьВладельца»
2. При создании нового элемента в
подчиненном справочнике метод
«ИспользоватьВладельца» - устанавливает
владельца создаваемому элементу.
3. Для объектов типа «Справочник»,
являющихся реквизитами формы (например в
документе или отчете) метод
«ИспользоватьВладельца» позволяет программно
установить владельца, который будет использован
при выборе данного реквизита.
Атрибут «Владелец» - предоставляет
доступ к значению элемента сопряженного
справочника, которому подчинен выбранный
элемент. Важно помнить, что этот атрибут
может быть изменен, но только для объектов,
полученных с помощью функции «СоздатьОбъект».
Это теоретические сведения.
Рассмотрим практические примеры. Все
практические примеры используют справочники
«Контрагенты» - «Расчетные счета». Эти
справочники есть во многих конфигурациях, и Вы
без проблем сможете опробовать примеры.
Пример 1. Перебрать все элементы
справочника «Контрагенты» и подчиненного ему
справочника «РасчетныеСчета».
Процедура Пример1()
Контр=СоздатьОбъект("Справочник.Контрагенты");
Рсч=СоздатьОбъект("Справочник.РасчетныеСчета");
Контр.ВыбратьЭлементы();//открываем выборку
контрагентов
Пока Контр.ПолучитьЭлемент()=1 цикл
Сообщить("Контрагент
"+Контр.Наименование);//сообщаем того по куму
будем выводить счета
рсч.ИспользоватьВладельца(контр.ТекущийЭлемент());////ВОТ
ОН!
рсч.ВыбратьЭлементы();//теперь
открываем выборку
Пока рсч.ПолучитьЭлемент()=1
цикл//получаем из выборки новый элемент
сообщить("_____"+рсч.Наименование+"
№"+рсч.Номер);// выводим имя и номер счета
конецЦикла;
конецЦикла;
КонецПроцедуры
Пример 2. Как перебрать элементы
подчиненного справочника, «не глядя» на
владельца. Номера и названия счетов всех
контрагентов.
Процедура Пример2()
Рсч=СоздатьОбъект("Справочник.РасчетныеСчета");
рсч.ВыбратьЭлементы(0);//теперь
открываем выборку
//Ноль означает, что выбираем без учета
иерархии
//это все-равно, что отключить
иерархический список в меню "Действия"
Пока рсч.ПолучитьЭлемент()=1
цикл//получаем из выборки новый элемент
сообщить(+рсч.Наименование+" №"+рсч.Номер);//
выводим имя и номер счета
конецЦикла;
КонецПроцедуры
Пример 3. В примере 2 кроме названия и
номера счета вывести название контрагента.
Процедура Пример3()
Рсч=СоздатьОбъект("Справочник.РасчетныеСчета");
рсч.ВыбратьЭлементы(0);//теперь
открываем выборку
Пока рсч.ПолучитьЭлемент()=1
цикл//получаем из выборки новый элемент
Контрагент=рсч.Владелец;//вот
мы и посмотрели на владельца
сообщить(рсч.Наименование+" №"+рсч.Номер+"
"+Контрагент);
конецЦикла;
КонецПроцедуры
Обратите внимание! Очень важный
момент. Разница между примером 1 и примером 3 – в
первом случае перебираем справочник-владелец, а
во втором случае – подчиненный справочник. В
первом случае все счета оказываются
сгруппированы по контрагентам. Во втором случае
– один контрагент может встретиться несколько
раз в разных местах (у разных счетов).
Пример 4. Для выбранного в форме
контрагента – создать новый расчетный счет.
Процедура Пример4()
Рсч=СоздатьОбъект("Справочник.РасчетныеСчета");
Если ПустоеЗначение(выбКонтрагент)=1
тогда//смотрим - есть ли контрагент
предупреждение("Укажите контрагента -
хозяина");//если нет - ругаемся
возврат;
// и уходим
конецЕсли;
рсч.ИспользоватьВладельца(ВыбКонтрагент);//используем
нового контрагента как владельца
рсч.Новый();//делаем новый элемент
рсч.Наименование="Валютный";
//заполняем реквизиты
рсч.Номер=777777777777;
//..................
//..................
рсч.Записать();//не забываем записать!
КонецПроцедуры
Важно: бывает так, что в диалоге лежит 2
реквизита. При этом один из них подчинен другому.
Например, такое есть в любой расходной или
приходной накладной: реквизит «Контрагент» и
реквизит «Договор» (или основание). Вы точно
знаете, что договор надо выбирать из списка
договоров конкретного контрагента.
Подчиненность можно установить программно:
Договор.ИспользоватьВладельца(Контрагент).
Программно надо устанавливать в момент выбора
контрагента. Но можно подчиненность установить
прямо в свойствах подчиненного реквизита – в
поле «Связан с» - надо написать имя
реквизита-владельца. В этом случае – после
выбора владельца в реквизите хозяине, в
подчиненном реквизите – автоматически будет
устанавливаться выборка элементов по хозяину.
Пример можно посмотреть в любой расходной
накладной.
Задание для самостоятельной работы.
1. Не часто, но иногда требуется
подчиненные элементы перенести (или скопировать)
из под одного владельца – другому владельцу.
Встроенного механизма – нет. Попробуйте
написаться обработку, выполняющую перенос или
копирование элементов из одного подчинения в
другое.
2. Для тех, кому первое задание
показалось легким: попробуйте написать
универсальную обработку, которая бы позволяла
работать с любыми двумя справочниками – один из
которых владелец, а другой подчиненный.
3. Вопрос на засыпку: что будет после
выполнения следующего программного кода. Где
искать подчиненные элементы? Как система
отреагирует на провокацию?
Процедура Засыпка()
пусто=ПолучитьПустоеЗначение("Справочник.Контрагенты");
Рсч=СоздатьОбъект("Справочник.РасчетныеСчета");
рсч.ВыбратьЭлементы(0);//теперь
открываем выборку
Пока рсч.ПолучитьЭлемент()=1
цикл//получаем из выборки новый элемент
рсч.Владелец=пусто;//
чистим владельца
рсч.Записать(); //и
записываем с ПУСТЫМ пладельцем
конецЦикла;
КонецПроцедуры
Все примеры можно посмотреть и попробовать в
действии здесь. Тестировалось в
1С:Бухгалтерии 7.7. ред.4.24 релиз 18 (вот так надо
писать когда вопросы задаете!) |