Урок 12.
"Подчиненные справочники (II часть)".

 

Сегодня мы рассмотрим, как реализована работа с подчиненными справочниками на уровне встроенного языка и конфигуратора.

Чтобы справочник А сделать подчиненным справочнику Б - надо в режиме Конфигуратор в свойствах справочника А в поле "Подчинен" - выбрать справочник Б. Этого будет достаточно.

При работе с подчиненным справочником появляется один важный метод: «Использовать Владельца» и важный атрибут «Владелец».

Метод «ИспользоватьВладельца» - может применяться к объектам типа «Справочник» в нескольких случаях:
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 (вот так надо писать когда вопросы задаете!)

Hosted by uCoz