Продвинутый курс. Занятие №3

Третье занятие по 0-му блоку продвинутого курса.

Необходимо изучить следующие главы 0-го курса.
Глава 16.Настройка командного интерфейса конфигурации.
Глава 17. Функциональные опции.
Глава 18. Простые правила разработки интерфейсов.
Глава 19. Работа с метаданными.
Глава 20. Параметры сеанса.

К сожалению, у Вас недостаточно прав для просмотра этой записи. Если Вы еще не залогинены на сайте
залогиньтесь.

Если не активировали токен — посмотрите видео-инструкцию (видео N5)

Если вы залогинены, у Вас активирован токен доступа, но вы все равно видите эту запись —
напишите нам на e-mail поддержки.

комментариев 29 на “Продвинутый курс. Занятие №3”

  1. respublica 26.06.2011 в 12:27

    Задание выполнил. С функциональными опциями и параметры функц. опций проблем не возникло, в материалах курса эта тема хорошо освещена. C метаданным уже работал, проблем с обработкой не возникло. Вывод дерева метаданных реализовал через рекурсивную функцию. Проверку на ссылочный тип реализовал как <code>НЕ Метаданные.НайтиПоТипу(мРеквизит.Тип.Типы()[0]) = Неопределено </code>

  2. Евгений Шилов 16.06.2011 в 21:20

    Задание выполнил.
    По первой части проблем не возникло.
    Поработать с деревом пришлось впервые. Эта и была самая большая сложность. В своем решении не далал проверку на зацикливание и не выводил стандартные реквизиты

  3. ДЗ выполнил

  4. Максим Ефимов 05.06.2011 в 22:04

    Первую часть сделал, ничего вроде сложного: <code>&НаСервере
    Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    ПараметрыФО = Новый Структура(“Организация”, Объект.Организация);
    УстановитьПараметрыФункциональныхОпцийФормы(ПараметрыФО);    
    КонецПроцедуры

    &НаКлиенте
    Процедура ОрганизацияПриИзменении(Элемент)
    ПараметрыФО = Новый Структура(“Организация”, Объект.Организация);
    УстановитьПараметрыФункциональныхОпцийФормы(ПараметрыФО);        
    КонецПроцедуры

    </code>
     
    Во второй части не разобрался, как обходить все коллекции, не думал, что решение настолько простое, поэтому пришлось лезть в решение и делать уже дальше по аналогии.

  5. 1. Функциональными опциями овладел
    2. Обработка заняла больше времени чем ФО.
    Из интересного для себя: нахожу ссылочный тип методом <code>Метаданные.НайтиПоТипу(СтрокаРеквизита.тип.типы()[0]) </code>
    обхожу реквизиты, ТЧ(немного отличается от реквизитов),макеты, команды, Стандартные реквизиты, формы если таковые присутствуют.
    Попрактиковался с Метаданными.

  6. Задание выполнила. Первая часть не вызвала затруднений. Со второй пришлось повозиться, не уверена в оптимальности своего решения.

  7. &НаКлиенте
    Процедура ОпределитьСтруктуруДокумента(Команда)
    ЗаполнитьФормуНаСервере(МетаДокумент);
    КонецПроцедуры
    &НаСервере
    Функция ЗаполнитьФормуНаСервере(Ссылка)

    СписокСвойствДок=Новый ДеревоЗначений;
    СписокСвойствДок.Колонки.Добавить(“Состав”,,”Структура документа”);
    КолекцияЗначенийСвойств=Новый Массив;
    КолекцияЗначенийСвойств.Добавить(“Реквизиты”);
    КолекцияЗначенийСвойств.Добавить(“ТабличныеЧасти”);
    КолекцияЗначенийСвойств.Добавить(“Формы”);
    КолекцияЗначенийСвойств.Добавить(“Макеты”);
    ЗаполнитДеревоДляДок(СписокСвойствДок,КолекцияЗначенийСвойств,сСылка);
    ЗначениеВДанныеФормы(СписокСвойствДок, ДеревоСвойств);

    КонецФункции // ()
    &НаСервереБезКонтекста
    Процедура ЗаполнитДеревоДляДок(СписокСвойствДок,КолекцияЗначенийСвойств,сСылка)
    ВсеСвойства=Ссылка.Метаданные();
    Для Каждого ЗначениеСвойства из КолекцияЗначенийСвойств Цикл
    СтруктураЗначенияСвойства=ВсеСвойства[ЗначениеСвойства];
    Строка=СписокСвойствДок.Строки.Добавить();
    Строка.Состав=ЗначениеСвойства;
    Для каждого ЗначениеСвойстваДок из СтруктураЗначенияСвойства Цикл
    строкаП=Строка.Строки.Добавить();
    СтрокаП.Состав=ЗначениеСвойстваДок.Имя;
    // Проверка реквизита на наличии ссылки
    Если ЗначениеСвойства=”Реквизиты” и Справочники.ТипВсеСсылки().СодержитТип( ТипЗнч( Ссылка[ЗначениеСвойстваДок.Имя] ))  Тогда
    //Рекурсия
    ЗаполнитДеревоДляДок(СтрокаП,КолекцияЗначенийСвойств, Ссылка[ЗначениеСвойстваДок.Имя]);
    КонецЕсли;
    КонецЦикла;
    КонецЦикла;
    КонецПроцедуры

    Задание выполнено
    Были сложности
    1 Обратиться к свойствам объекта метаданных
    ВсеСвойства=Ссылка.Метаданные();
    ВсеСвойства[ЗначениеСвойства]; (Для каждого из и Следующий -не работает) а за индекс в синтакс помощнике забыли написать.
    Выделил два способа:
    ВсеСвойства.Реквизит;
    ВсеСвойства[«Реквизит»];
    Есть ли еще способы?

    2 определить ссылочный реквизит
    Справочники.ТипВсеСсылки().СодержитТип(ТипЗнч( Ссылка[ЗначениеСвойстваДок.Имя] ))
    Помог первый блок базового курса

    &НаКлиенте
    Процедура ОпределитьСтруктуруДокумента(Команда)
    ЗаполнитьФормуНаСервере(МетаДокумент);
    КонецПроцедуры

    &НаСервере
    Функция ЗаполнитьФормуНаСервере(Ссылка)

    СписокСвойствДок=Новый ДеревоЗначений;
    СписокСвойствДок.Колонки.Добавить(“Состав”,,”Структура документа”);
    КолекцияЗначенийСвойств=Новый Массив;
    КолекцияЗначенийСвойств.Добавить(“Реквизиты”);
    КолекцияЗначенийСвойств.Добавить(“ТабличныеЧасти”);
    КолекцияЗначенийСвойств.Добавить(“Формы”);
    КолекцияЗначенийСвойств.Добавить(“Макеты”);
    ЗаполнитДеревоДляДок(СписокСвойствДок,КолекцияЗначенийСвойств,сСылка);
    ЗначениеВДанныеФормы(СписокСвойствДок, ДеревоСвойств);

    КонецФункции // ()

    &НаСервереБезКонтекста
    Процедура ЗаполнитДеревоДляДок(СписокСвойствДок,КолекцияЗначенийСвойств,сСылка)
    ВсеСвойства=Ссылка.Метаданные();
    Для Каждого ЗначениеСвойства из КолекцияЗначенийСвойств Цикл
    СтруктураЗначенияСвойства=ВсеСвойства[ЗначениеСвойства];
    Строка=СписокСвойствДок.Строки.Добавить();
    Строка.Состав=ЗначениеСвойства;
    Для каждого ЗначениеСвойстваДок из СтруктураЗначенияСвойства Цикл
    строкаП=Строка.Строки.Добавить();
    СтрокаП.Состав=ЗначениеСвойстваДок.Имя;
    // Проверка реквизита на наличии ссылки
    Если ЗначениеСвойства=”Реквизиты” и Справочники.ТипВсеСсылки().СодержитТип( ТипЗнч( Ссылка[ЗначениеСвойстваДок.Имя] )) Тогда
    //Рекурсия
    ЗаполнитДеревоДляДок(СтрокаП,КолекцияЗначенийСвойств, Ссылка[ЗначениеСвойстваДок.Имя]);
    КонецЕсли;
    КонецЦикла;
    КонецЦикла;
    КонецПроцедуры

  8. Задание выполнено, правда с небольшим опозданием (к сожалению, последние несколько дней не было возможности позаниматься).
    В первой части каких-то сложностей не возникло, управление видимостью сделал через функциональную опцию аналогично урокам.
    Во второй части уже пришлось поломать голову, но сделал. Естественно, используется рекурсия, а также учтена возможность наличия взаимных ссылок – повторно не разворачиваются реквизиты типов, которые уже встречались ранее в текущей ветке.
    Привожу серверный кусок кода обработки:
    <code>
    &НаСервере
    Перем МассивКоллекций;
    Перем СписокТипов;

    &НаСервере
    Процедура ЗаполнитьКоллекциюМД(Коллекция, НаимКоллекции, Строки)
    Если Коллекция.Количество()=0 Тогда
    Возврат;
    КонецЕсли;

    Корень = Строки.Добавить();
    Корень.Наименование = НаимКоллекции;

    Для каждого Элемент Из Коллекция Цикл
    Стр = Корень.Строки.Добавить();
    Стр.Наименование = Элемент.Имя;

    Если НаимКоллекции=”ТабличныеЧасти” или НаимКоллекции=”Формы” Тогда
    ЗаполнитьДанныеОбъекта(Элемент, Стр.Строки);
    ИначеЕсли НаимКоллекции=”Реквизиты” Тогда
    МассивТипов = Элемент.Тип.Типы();
    Если МассивТипов.Количество()=1 Тогда
    Если СписокТипов.НайтиПоЗначению(МассивТипов[0])=Неопределено Тогда
    Эл = СписокТипов.Добавить(МассивТипов[0]);
    Попытка
    ЗаполнитьДанныеОбъекта(Метаданные.НайтиПоТипу(МассивТипов[0]), Стр.Строки);
    Исключение
    КонецПопытки;
    СписокТипов.Удалить(Эл);
    КонецЕсли;
    КонецЕсли;
    КонецЕсли;
    КонецЦикла;
    КонецПроцедуры

    &НаСервере
    Процедура ЗаполнитьДанныеОбъекта(МД, Строки)
    Для Инд=0 по МассивКоллекций.Количество()-1 Цикл
    ИмяКоллекции = МассивКоллекций[Инд];
    Попытка
    ЗаполнитьКоллекциюМД(МД[ИмяКоллекции], ИмяКоллекции, Строки);
    Исключение
    КонецПопытки;
    КонецЦикла;
    КонецПроцедуры

    &НаСервере
    Процедура ЗаполнитьНаСервере()
    МассивКоллекций = Новый Массив;
    МассивКоллекций.Добавить(“Реквизиты”);
    МассивКоллекций.Добавить(“ТабличныеЧасти”);
    МассивКоллекций.Добавить(“Формы”);
    МассивКоллекций.Добавить(“Макеты”);

    Ссылка = Документ.Ссылка;
    СписокТипов = Новый СписокЗначений;
    СписокТипов.Добавить(ТипЗнч(Ссылка));

    Дерево = РеквизитФормыВЗначение(“СтруктураМетаданных”);
    Дерево.Строки.Очистить();
    Корень = Дерево.Строки.Добавить();
    Корень.Наименование = Ссылка.Метаданные().ПолноеИмя();

    ЗаполнитьДанныеОбъекта(Ссылка.Метаданные(), Корень.Строки);
    ЗначениеВРеквизитФормы(Дерево, “СтруктураМетаданных”);
    КонецПроцедуры
    </code>

  9. задание выполнил не до конца

    с функциональной опцией проблем не возникло.
      
    Не смог построить дерево реквизитов полностью.
      
    &НаСервере
    Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
     Для Каждого ТекДок Из Метаданные.Документы Цикл
      Элементы.МетаДокумент.СписокВыбора.Добавить(ТекДок.Имя, ТекДок.Синоним); 
     КонецЦикла;
     МетаДокументСписокВыбора = Элементы.МетаДокумент.СписокВыбора;
     Если МетаДокументСписокВыбора.Количество() > 0 Тогда
      Объект.МетаДокумент = МетаДокументСписокВыбора[0].Значение;
     КонецЕсли; 
    КонецПроцедуры
       

    &НаКлиенте
    Процедура МетаДокументПриИзменении(Элемент)
     МетаДокументПриИзмененииСервер(); 
    КонецПроцедуры
        

    &НаСервере
    Процедура МетаДокументПриИзмененииСервер()
     
     ИмяДокумента = Объект.МетаДокумент;
     ТекДокумент = Метаданные.Документы.Найти(ИмяДокумента);
     
     ДеревоРеквизитов = Новый ДеревоЗначений;
     ДеревоРеквизитов.Колонки.Добавить(“Данные”);
     
     Для Каждого ТекРеквизит Из ТекДокумент.Реквизиты Цикл
      НовСтр = ДеревоРеквизитов.Строки.Добавить(); 
      НовСтр.Данные = ТекРеквизит.Имя;
     КонецЦикла;
     
     ЗначениеВРеквизитФормы(ДеревоРеквизитов, “Объект.ДеревоРеквизитов”);
      
    КонецПроцедуры

  10. Задание выполнено.
    Первое при помощи параметризуемой ФО.
    Второе при помощи рекурсии с анализом метаданных.
     

  11. Задание выполнено.
    Настройка видимости реквизитов реализована с использованием функциональной опции с параметрами.
    Обработка “Метаданные документа” выполнена с использованием рекурсивной функции. Предусмотрена защита от зацикливания с помощью ограничения уровня вложенности.

  12. Задание выполнила. Первую часть реализовала через функциональную опцию ВестиУчетПоСкладам и параметр функциональной опции Организация.
    Вторая часть реализована следующим образом. На сервере заполняю объект ДеревоЗначений обходя реквизиты, табличные части, формы и макеты выбранного документа. Для реквизитов документа и реквизитов табличных частей далее проверяю в рекурсии являются ли они объектами метаданных, разворачивая их по такому же принципу. В связи с тем, что ДеревоЗначений доступно только на сервере, в управляемой форме используется тип ДанныеФормыДерево. Для преобразования ДеревоЗначений -> ДанныеФормыДерево используются методы управляемой формы ЗначениеВРеквизитФормы(). Для непосредственного отображения дерева используется элемент формы типа ТаблицаФормы связанный через реквизит ПутьКДанным с реквизитом формы типа ДанныеФормыДерево.
    &НаСервереБезКонтекста
    Процедура ДобавитьЭлементНаСервере(Реквизит, ДеревоОбъект, СвойстваДокумента = Неопределено);
    Если СвойстваДокумента = Неопределено Тогда
    СвойстваОбъекта = Метаданные.НайтиПоТипу(Реквизит.Тип.Типы()[0]); 
    Иначе
    СвойстваОбъекта = СвойстваДокумента;
    КонецЕсли; 
    Если СвойстваОбъекта <> Неопределено Тогда
    Если СвойстваОбъекта.Реквизиты.Количество() <> 0 Тогда
    Строка = ДеревоОбъект.Строки.Добавить();
    Строка.Узел = “Реквизиты”;
    Для Каждого ТекРеквизит Из СвойстваОбъекта.Реквизиты Цикл
    СтрокаРеквизит = Строка.Строки.Добавить();
    СтрокаРеквизит.Узел = ТекРеквизит.Имя;
    ДобавитьЭлементНаСервере(ТекРеквизит, СтрокаРеквизит, Неопределено);
    КонецЦикла;
    КонецЕсли; 

    Если СвойстваОбъекта.ТабличныеЧасти.Количество() <> 0 Тогда
    Строка = ДеревоОбъект.Строки.Добавить();
    Строка.Узел = “ТабличныеЧасти”;
    Для Каждого ТекРеквизит Из СвойстваОбъекта.ТабличныеЧасти Цикл
    СтрокаРеквизит = Строка.Строки.Добавить();
    СтрокаРеквизит.Узел = ТекРеквизит.Имя;
    Если ТекРеквизит.Реквизиты.Количество() <> 0 Тогда
    Для Каждого ТекРеквизитТабличнойЧасти Из ТекРеквизит.Реквизиты Цикл 
    СтрокаРеквизитТабличнойЧасти = СтрокаРеквизит.Строки.Добавить();
    СтрокаРеквизитТабличнойЧасти.Узел = ТекРеквизитТабличнойЧасти.Имя; 
    ДобавитьЭлементНаСервере(ТекРеквизитТабличнойЧасти, СтрокаРеквизитТабличнойЧасти, Неопределено);
    КонецЦикла; 
    КонецЕсли; 
    КонецЦикла;
    КонецЕсли; 

    Если СвойстваОбъекта.Формы.Количество() <> 0 Тогда
    Строка = ДеревоОбъект.Строки.Добавить();
    Строка.Узел = “Формы”;
    Для Каждого ТекРеквизит Из СвойстваОбъекта.Формы Цикл
    СтрокаРеквизит = Строка.Строки.Добавить();
    СтрокаРеквизит.Узел = ТекРеквизит.Имя;
    КонецЦикла;
    КонецЕсли; 

    Если СвойстваОбъекта.Макеты.Количество() <> 0 Тогда
    Строка = ДеревоОбъект.Строки.Добавить();
    Строка.Узел = “Макеты”;
    Для Каждого ТекРеквизит Из СвойстваОбъекта.Макеты Цикл
    СтрокаРеквизит = Строка.Строки.Добавить();
    СтрокаРеквизит.Узел = ТекРеквизит.Имя;
    КонецЦикла;
    КонецЕсли; 
    КонецЕсли;
    КонецПроцедуры
    &НаСервере
    Процедура ПостроитьДеревоНаСервере(ИмяДокумента);
    ДеревоОбъект = Новый ДеревоЗначений;
    ДеревоОбъект.Колонки.Добавить(“Узел”, Новый ОписаниеТипов(“Строка”));

    СвойстваДокумента = Метаданные.Документы.Найти(ИмяДокумента);
    ДобавитьЭлементНаСервере(Неопределено,ДеревоОбъект, СвойстваДокумента);
    МассивДобавляемыхРеквизитов = Новый Массив;
    МассивДобавляемыхРеквизитов.Добавить(Новый РеквизитФормы(“Дерево”,
    Новый ОписаниеТипов(“ДеревоЗначений”)));
    Для Каждого Колонка Из ДеревоОбъект.Колонки Цикл
    МассивДобавляемыхРеквизитов.Добавить(
    Новый РеквизитФормы(Колонка.Имя, Колонка.ТипЗначения, “Дерево”));
    КонецЦикла;
    ИзменитьРеквизиты(МассивДобавляемыхРеквизитов);
    ЗначениеВРеквизитФормы(ДеревоОбъект, “Дерево”);
    ЭлементДерево = Элементы.Добавить(“Дерево”, Тип(“ТаблицаФормы”));
    ЭлементДерево.ПутьКДанным = “Дерево”;
    ЭлементДерево.Отображение = ОтображениеТаблицы.Дерево;
    Для Каждого Колонка Из ДеревоОбъект.Колонки Цикл
    НовыйЭлемент = Элементы.Добавить(Колонка.Имя, Тип(“ПолеФормы”),
    ЭлементДерево);
    НовыйЭлемент.Вид = ВидПоляФормы.ПолеВвода;
    НовыйЭлемент.ПутьКДанным = “Дерево.” + Колонка.Имя;
    КонецЦикла;
    КонецПроцедуры

  13. Задача решена.
    Первая достаточно несложно решается с помощью функциональных опций. Похожий пример разбирался в видеолекциях.
    Вторая решена с помощью рекурсивной процедуры формирования веток дерева для ссылочных типов. Единственное, не очень уверен  насчет оптимального определения этих самых ссылочных типов (использовал ТипВсеСсылки())..в общем, дождусь решения.

  14. С первой задачей вопросов не возникло.
    Во второй задаче в форме, кроме поля ввода для  документа и дерева значений для вывода метаданных, добавлен список значений “КоллекцииОбъектовМетаданных”, который используется для перебора возможных коллекций объектов метаданных документов и справочников, в прочих случаях коллекции указываются явно.
    Дерево значений заполняется сразу с использованием рекурсии.
    Используются:
    – процедура ПолучитьМетаданныеДокументаНаСервере(ИмяДокумента) для заполнения верхнего уровня дерева метаданных документа,
    – процедура с рекурсией ПолучитьРасшифровкуНаСервере(СтрокаДЗ) для расшифровки ветвей реквизитов и табличных частей,
    – функция ДЗДобавитьСтрокуНаСервере (СтрокаВерхнегоУровня, ОбъектМетаданных) для добавления строк в дерево значений.
    Затрудения возникли при выводе реквизитов табличных частей. Также не учитывала, что реквизиты могут быть составного типа.

  15. Задание выполнил. Первая часть проблем не вызвала. А на выполнение  второй части пришлось потратить много времени. Интересно будет сравнить с эталонным решением.
    Эта процедура заполняет дерево метаданных документа
    &НаСервере
    Процедура   ПолучитьСписокМетаданныхДокумента()

    СвойстваДокумента = Метаданные.НайтиПоПолномуИмени(“Документ.” + МетаДокумент);    
    ДеревоМетаданных = ДанныеФормыВЗначение(МетаданныеДокумента, Тип(“ДеревоЗначений”));
    ДеревоМетаданных.Колонки.Очистить();
    ДеревоМетаданных.Колонки.Добавить(“Метаданные”);

    УровеньВложения = 0;
    СтрокаВерхнегоУровня = ДеревоМетаданных.Строки.Добавить();
    СтрокаВерхнегоУровня.Метаданные = “Реквизиты”;
    ЗаполнитьВетвьДерева(СтрокаВерхнегоУровня, СвойстваДокумента, “Реквизиты”, УровеньВложения);

    УровеньВложения = 0;
    СтрокаВерхнегоУровня = ДеревоМетаданных.Строки.Добавить();
    СтрокаВерхнегоУровня.Метаданные = “Табличные части”;
    ЗаполнитьВетвьДерева(СтрокаВерхнегоУровня, СвойстваДокумента, “ТабличныеЧасти”, УровеньВложения);

    УровеньВложения = 0;    
    СтрокаВерхнегоУровня = ДеревоМетаданных.Строки.Добавить();
    СтрокаВерхнегоУровня.Метаданные = “Формы”;
    ЗаполнитьВетвьДерева(СтрокаВерхнегоУровня, СвойстваДокумента, “Формы”, УровеньВложения);

    СтрокаВерхнегоУровня = ДеревоМетаданных.Строки.Добавить();
    СтрокаВерхнегоУровня.Метаданные = “Команды”;
    ЗаполнитьВетвьДерева(СтрокаВерхнегоУровня, СвойстваДокумента, “Команды”, УровеньВложения);

    СтрокаВерхнегоУровня = ДеревоМетаданных.Строки.Добавить();
    СтрокаВерхнегоУровня.Метаданные = “Макеты”;
    ЗаполнитьВетвьДерева(СтрокаВерхнегоУровня, СвойстваДокумента, “Макеты”, УровеньВложения);

    ЗначениеВДанныеФормы(ДеревоМетаданных, МетаданныеДокумента);
    КонецПроцедуры

    Для рекурсивного заполнения используются две процедуры
    &НаСервереБезКонтекста
    Процедура ЗаполнитьВетвьДерева(СтрокаДерева, МетаданныеДокумента, Свойство, УровеньВложения)
    Если УровеньВложения > 2 Тогда
    УровеньВложения = 0;
    Возврат;
    КонецЕсли;    
    Для каждого Значение Из МетаданныеДокумента[Свойство] Цикл
    ПодчиненнаяСтрока = СтрокаДерева.Строки.Добавить();
    ПодчиненнаяСтрока.Метаданные = Значение.Имя;
    Попытка            
    Если Свойство = “ТабличныеЧасти” Тогда
    ВложенноеМетаданное = Метаданные.НайтиПоПолномуИмени(Значение.ПолноеИмя());
    Иначе
    ВложенноеМетаданное = Метаданные.НайтиПоТипу(Значение.Тип.Типы()[0]);     
    КонецЕсли;    
    Если ВложенноеМетаданное <> Неопределено Тогда
    УровеньВложения = УровеньВложения + 1;
    ЗаполнитьДеревоМетаданного(ПодчиненнаяСтрока, ВложенноеМетаданное, УровеньВложения);
    КонецЕсли;
    Исключение
    КонецПопытки;          
    КонецЦикла;
    КонецПроцедуры // ЗаполнитьВетвьДерева()

    &НаСервереБезКонтекста
    Процедура ЗаполнитьДеревоМетаданного(ДеревоМетаданных, Метаданное, УровеньВложения)
    Если УровеньВложения > 2 Тогда
    УровеньВложения = 0;
    Возврат;
    КонецЕсли;    
    ПолноеИмя = Метаданное.ПолноеИмя();
    ЕстьЗначенияПеречисления = Истина;
    ЕстьРеквизиты = Истина;
    ЕстьТабличныеЧасти = Истина;
    ЕстьФормы = Истина;
    ЕстьКоманды = Истина;
    ЕстьМакеты = Истина;
    Если Найти(ПолноеИмя, “Перечисление.”) > 0 Тогда
    ЕстьЗначенияПеречисления = Истина;
    ЕстьРеквизиты = Ложь;
    ЕстьТабличныеЧасти = Ложь;
    ЕстьФормы = Истина;
    ЕстьКоманды = Истина;
    ЕстьМакеты = Истина;
    ИначеЕсли Найти(ПолноеИмя, “Справочник.”) > 0 Тогда
    Если Найти(ПолноеИмя, “ТабличнаяЧасть”) > 0 Тогда
    ЕстьЗначенияПеречисления = Ложь;
    ЕстьРеквизиты = Истина;
    ЕстьТабличныеЧасти = Ложь;
    ЕстьФормы = Ложь;
    ЕстьКоманды = Ложь;
    ЕстьМакеты = Ложь;
    Иначе
    ЕстьЗначенияПеречисления = Ложь;
    ЕстьРеквизиты = Истина;
    ЕстьТабличныеЧасти = Истина;
    ЕстьФормы = Истина;
    ЕстьКоманды = Истина;
    ЕстьМакеты = Истина;             
    КонецЕсли;    
    ИначеЕсли Найти(ПолноеИмя, “Документ.”) > 0 Тогда
    Если Найти(ПолноеИмя, “ТабличнаяЧасть”) > 0 Тогда
    ЕстьЗначенияПеречисления = Ложь;
    ЕстьРеквизиты = Истина;
    ЕстьТабличныеЧасти = Ложь;
    ЕстьФормы = Ложь;
    ЕстьКоманды = Ложь;
    ЕстьМакеты = Ложь;
    Иначе
    ЕстьЗначенияПеречисления = Ложь;
    ЕстьРеквизиты = Истина;
    ЕстьТабличныеЧасти = Истина;
    ЕстьФормы = Истина;
    ЕстьКоманды = Истина;
    ЕстьМакеты = Истина;             
    КонецЕсли;    
    Иначе
    ЕстьЗначенияПеречисления = Ложь;
    ЕстьРеквизиты = Ложь;
    ЕстьТабличныеЧасти = Ложь;
    ЕстьФормы = Ложь;
    ЕстьКоманды = Ложь;
    ЕстьМакеты = Ложь;
    КонецЕсли;

    Если ЕстьЗначенияПеречисления Тогда
    СтрокаВерхнегоУровня = ДеревоМетаданных.Строки.Добавить();
    СтрокаВерхнегоУровня.Метаданные = “Значения”;
    ЗаполнитьВетвьДерева(СтрокаВерхнегоУровня, Метаданное, “ЗначенияПеречисления”, УровеньВложения);
    КонецЕсли;

    Если ЕстьРеквизиты Тогда
    СтрокаВерхнегоУровня = ДеревоМетаданных.Строки.Добавить();
    СтрокаВерхнегоУровня.Метаданные = “Реквизиты”;
    ЗаполнитьВетвьДерева(СтрокаВерхнегоУровня, Метаданное, “Реквизиты”, УровеньВложения);
    КонецЕсли;

    Если ЕстьТабличныеЧасти Тогда
    СтрокаВерхнегоУровня = ДеревоМетаданных.Строки.Добавить();
    СтрокаВерхнегоУровня.Метаданные = “Табличные части”;
    Для каждого Значение Из Метаданное[“ТабличныеЧасти”] Цикл
    ПодчиненнаяСтрока = СтрокаВерхнегоУровня.Строки.Добавить();
    ПодчиненнаяСтрока.Метаданные = Значение.Имя;
    ЗаполнитьДеревоМетаданного(ПодчиненнаяСтрока, Значение, УровеньВложения);
    КонецЦикла;
    КонецЕсли;

    Если ЕстьФормы Тогда
    СтрокаВерхнегоУровня = ДеревоМетаданных.Строки.Добавить();
    СтрокаВерхнегоУровня.Метаданные = “Формы”;
    ЗаполнитьВетвьДерева(СтрокаВерхнегоУровня, Метаданное, “Формы”, УровеньВложения);
    КонецЕсли;

    Если ЕстьКоманды Тогда
    СтрокаВерхнегоУровня = ДеревоМетаданных.Строки.Добавить();
    СтрокаВерхнегоУровня.Метаданные = “Команды”;
    ЗаполнитьВетвьДерева(СтрокаВерхнегоУровня, Метаданное, “Команды”, УровеньВложения);
    КонецЕсли;

    Если ЕстьМакеты Тогда
    СтрокаВерхнегоУровня = ДеревоМетаданных.Строки.Добавить();
    СтрокаВерхнегоУровня.Метаданные = “Макеты”;
    ЗаполнитьВетвьДерева(СтрокаВерхнегоУровня, Метаданное, “Макеты”, УровеньВложения);
    КонецЕсли;     
    КонецПроцедуры

    Переменная УровеньВложения используется для защиты от зацикливания.

  16. Первая часть затруднений не вызвала
    Во второй части,  не знал про функцию ЗначениеВРеквизитФормы()
    Смог сделать, только заглянув в комментарии

  17. 1.Создал справочник Склады и необходимые реквизиты в справочнике Организации и Документах Поступления и Реализации. Затем создал функциональную опцию “Вести учет по складам”. При создании параметра функциональной опции немного забуксовал. Сразу не сообразил, что должно содержаться в свойстве “Использование” и, кроме того, забыл настроить состав самой функциональной опции. Затем, все же разобрался со всеми этими проблемами и добавил в обработчики событий документов (ПриОткрытии и при изменении реквизита Организация) код по установке параметров функциональной опции.
    2.Обработку создал. Перед тем как создавать дерево метаданных. Создаю объект СсылочныеТипы с типом ОписаниеТипов, в котором находятся все ссылочные типы данных конфигурации (Документы, Сравочники, Перечисления и т.д.). Заполнение дерева происходит при помощи рекурсивной процедуры. Вот часть ее кода:

    Реквизиты = МетаОбъект.Реквизиты;
    Если Реквизиты.Количество() > 0 Тогда
    СтрокаРеквизит = СтрокаДерева.Строки.Добавить();
    СтрокаРеквизит.МетаОбъект = “Реквизиты”;
    Для каждого Реквизит Из Реквизиты Цикл
    НоваяСтрока = СтрокаРеквизит.Строки.Добавить();
    НоваяСтрока.МетаОбъект = Реквизит.Имя;
    ТипРеквизита = Реквизит.Тип.Типы()[0];
    Если СсылочныеТипы.СодержитТип(ТипРеквизита) Тогда
    ДобавитьСвойстваОбъекта(Метаданные.НайтиПоТипу(ТипРеквизита), НоваяСтрока, СсылочныеТипы)
    КонецЕсли;
    КонецЦикла;
    КонецЕсли;
    ….. Далее заполняются формы, макеты и табличные части

    При решении столкнулся вот с какой проблемой. В отладчике для выражения Метаданные.НайтиПоТипу(Реквизит.Тип.Типы()[0]) и самого объекта Реквизит (элемент из КоллекцияОбъектовМетаданных) тип отображается как “ОбъектМетаданных”, хотя набор свойств у них разный. Вот тут я немного потупил, не понимал чего от меня хочет платформа. Вроде бы объект соответствующего типа, а нужных коллекций в нем нет.
    В итоге задание выполнил. Дерево на форму выводится. Кроме того, при решении задания основывался на том, что циклических ссылок в конфигурации нет.

  18. Задание  выполнил.
    Создал справочник «Склад», добавил одноименные реквизиты в документы поступление и реализация. В справочник «организации» был добавлен реквизит «УчетПоСкладам» тип булево.   Добавил в конфигурацию функциональную опцию «Учет по складам» и указал хранение в реквизите «учетпоскладам» справочника «Организации», так же в состав данной функ. опции включил  реквизиты, документов  поступление и реализации, «склад».  В состав параметров функциональных опций был добавлен элемент «Организация» с типом справочника «организации». При открытии форм документов и при изменении организации, вызываю функцию УстановитьПараметрыФункциональныхОпцийФормы() с переданным параметром «Организации». Сложностей с первой частью не возникло. Но возникли вопросы, и надеюсь по мере обучения, вопросы отпадут сами собой.
    Для второй части задания создал обработку «Метаданные документа», так же использовал рекурсивную функцию для реквизитов документа и реквизитов табличных частей документа.  Если реквизит является ссылочным типом данных,  то по реквизиту, так же, получаю структуру. Для того что бы узнать является ли реквизит ссылочным типом данных, использовал функцию ТипВсеСсылки(), и сравнивал тип реквизита. Всю информацию по полученным реквизитам добавляю в дерево значений, далее дерево значений с помощью функции ЗначениеВРеквизитФормы(), отображаю на форме обработки. По 2-ой части задания, сложности возникали, но были успешно преодолены.

  19. Подскажите есть возможность выполнить процедуру
    УстановитьПараметрыФункциональныхОпцийФормы()
    В общем модуле.
    Можно перенести контекст формы в общий модуль?

    • Такой возможности нет.

      • а я сделал)
         
        В документах:
         
        &НаКлиенте
        Процедура ОрганизацияПриИзменении(Элемент) 
         РаботаСДокументамиКлиент.УстановитьПараметрыФОпций(ЭтаФорма);  
        КонецПроцедуры
         
        В общем модуле:
         
        Процедура УстановитьПараметрыФОпций(Форма) Экспорт
         
         Объект = Форма.Объект;
         ПараметрыФункОпц = Новый Структура(“Организация”, Объект.Организация);
         Форма.УстановитьПараметрыФункциональныхОпцийФормы(ПараметрыФункОпц);
         
        КонецПроцедуры

        • Действительно, я не верно посмотрел в синтакс-помощник.
          Спасибо, Дмитрий!

          • Евгений, это Вам спасибо за то что даете нам хорошие знания!

            • Вообще, то я имел, в виду не предать параметр с хранящейся в ней формой, а передать только контекст (или создать) в общем модуле и в качестве параметра использовать организацию. Чтобы не переносить все данные формы в общий модуль, и можно было использовать функции и процедуры модуля форм.
              Получается, что мы создаем два экземпляра формы в оперативной памяти, а если бы общий модуль был серверный, то пришлось бы пригонять форму на сервер. Тогда уж лучше повторяющийся код в модуле формы. Правильно я понимаю ситуацию?

              • Только контекст передать невозможно.
                Вообще данные формы нельзя передавать с клиента на сервер.
                Об этом будем говорить по ходу курса в 1-ом блоке.

                Что же касается хранения формы.
                То она изначально создается как на клиенте, так и на сервере. Далее на сервере форма удаляется. И передача ее с клиента на сервер приведет к необходимости повторного создания формы на стороне сервера.

                Но все-таки повторяющегося кода лучше избегать. Например, создав клиентский общий модуль. Тогда можно будет спокойно по ссылке передавать управляемую форму.

  20. Кононов Сергей 07.05.2011 в 21:48

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

    СписокВыбора = Элементы.ДокументМетаданных.СписокВыбора;
    Для Каждого ДокументМ Из Метаданные.Документы Цикл
    СписокВыбора.Добавить(ДокументМ.Имя, ДокументМ.Синоним);
    КонецЦикла;

    КонецПроцедуры
    </doc>
    Далее, в обработчике события ПриИзменения вышеупомянутого реквизита формы, т.е. при выборе пользователем документа выполняю заполнение. Весь процесс я выполняю на сервере, так как только там доступен глобальный контекст Метаданные объекта.
    Для универсальности алгоритма я решил задачу используя рекурсию. Кратко: на сервере создаю новый объект дерево значений, создаю колонку Имя, заполняю и методом: ЗначениеВРеквизитФормы(Дерево, “СтруктураДокумента”), возвращаю в форму.
    <cod>
    &НаКлиенте
    Процедура ДокументМетаданныхПриИзменении(Элемент)
    ДобавитьНаСервере(ДокументМетаданных);
    КонецПроцедуры
    &НаСервере
    Процедура ДобавитьНаСервере(ДокументМ)
    МетаДокумент = Метаданные.Документы[ДокументМ];

    Дерево = Новый ДеревоЗначений;
    Дерево.Колонки.Добавить(“Имя”);

    СоздатьСтруктуруОбъектов(Дерево, МетаДокумент);

    ЗначениеВРеквизитФормы(Дерево, “СтруктураДокумента”);

    КонецПроцедуры // ДобавитьНаСервере()
    &НаСервереБезКонтекста
    Процедура СоздатьСтруктуруОбъектов(Дерево, МетаОбъект)

    СтрокаРеквизиты = Дерево.Строки.Добавить();
    СтрокаРеквизиты.Имя = “Реквизиты”;

    СтрокаТабЧасти = Дерево.Строки.Добавить();
    СтрокаТабЧасти.Имя = “Табличные части”;

    СтрокаФормы = Дерево.Строки.Добавить();
    СтрокаФормы.Имя = “Формы”;

    СтрокаКоманды = Дерево.Строки.Добавить();
    СтрокаКоманды.Имя = “Команды”;

    СтрокаМакеты = Дерево.Строки.Добавить();
    СтрокаМакеты.Имя = “Макеты”;

    // Добавляем реквизиты
    ДобавитьРеквизиты(СтрокаРеквизиты, МетаОбъект);

    // Добавляем таб части
    Для Каждого ТабЧасть Из МетаОбъект.ТабличныеЧасти Цикл
    ДобавитьРеквизиты(СтрокаТабЧасти, ТабЧасть);
    КонецЦикла;

    // Добавляем формы
    Для Каждого ФормаОбъекта Из МетаОбъект.Формы Цикл
    НоваяСтрока = СтрокаФормы.Строки.Добавить();
    НоваяСтрока.Имя = ФормаОбъекта.Имя;
    КонецЦикла;

    // Добавляем команды
    Для Каждого КомандаОбъекта Из МетаОбъект.Команды Цикл
    НоваяСтрока = СтрокаКоманды.Строки.Добавить();
    НоваяСтрока.Имя = КомандаОбъекта.Имя;
    КонецЦикла;

    // Добавляем макеты
    Для Каждого МакетОбъекта Из МетаОбъект.Макеты Цикл
    НоваяСтрока = СтрокаМакеты.Строки.Добавить();
    НоваяСтрока.Имя = МакетОбъекта.Имя;
    КонецЦикла;

    КонецПроцедуры
    &НаСервереБезКонтекста
    Процедура ДобавитьРеквизиты(СтрокаРеквизиты, МетаОбъект)

    Для каждого Реквизит Из МетаОбъект.Реквизиты Цикл

    НоваяСтрокаРеквизит = СтрокаРеквизиты.Строки.Добавить();
    НоваяСтрокаРеквизит.Имя = Реквизит.Имя;

    НовыйМетаОбъект = “”;
    Если Справочники.ТипВсеСсылки().СодержитТИп(Реквизит.Тип.Типы()[0]) Тогда
    НовыйМетаОбъект = Метаданные.Справочники[Реквизит.Тип.ПривестиЗначение().Метаданные().Имя];
    ИначеЕсли Документы.ТипВсеСсылки().СодержитТИп(Реквизит.Тип.Типы()[0]) Тогда
    НовыйМетаОбъект = Метаданные.Документы[Реквизит.Тип.ПривестиЗначение().Метаданные().Имя];
    КонецЕсли;

    Если НовыйМетаОбъект<>”” Тогда
    ДобавитьРеквизиты(НоваяСтрокаРеквизит, НовыйМетаОбъект);
    КонецЕсли;

    КонецЦикла;
    КонецПроцедуры
    </cod>
    Я обрабатываю ссылочные реквизиты только на тип справочник и документ, но по желанию можно добавить и все остальные ссылочные типы.
    Задание выполнено.
    Часть 1.Создал справочник Склады и в документах Поступления и Реализации определил соответствующий реквизит Склад типа спр-к Склады.Создал в справочнике Организации реквизит УчетПоСкладам типа Булево.Создал функц-ую опцию УчетПоСкладам и указал в свойстве Хранение значение реквизита УчетПоСкладам спраочника Организации.Создал параметр функциональных опций ПараметрУчетПоСкладам, в котором в свойстве использование указал справочник Организации.Далее в каждом из документов с реквизитом склад, для этих реквизитов указал использование функциональной опции УчетПоСкладам.Далее как и  в видео-уроке я буду программно устанавливать значение параметра функц-ой опции, чтобы форма перерисовывала сразу отображение. Это я буду делать при создании формы данных документов и при изменении реквизитов формы этих документов Организация. Обработчики этих событий в обоих документах будут выглядеть след. образом:
    <doc>
    &НаСервереПроцедура ПриСозданииНаСервере(Отказ,СтандартнаяОбработка)
    МодульКлиентСервер.УстановкаПараметровФункциональныхОпций(ЭтаФорма, Объект.Организация);
    КонецПроцедуры

    &НаКлиентеПроцедура ОрганизацияПриИзменении(Элемент)
    МодульКлиентСервер.УстановкаПараметровФункциональныхОпций(ЭтаФорма, Объект.Организация);
    КонецПроцедуры
    </doc> 
    Я создал общий модуль компидируемый на Сервере и на Клиенте в котором описал код установки параметра функциональной опции след. образом;
    <doc>
    Процедура УстановкаПараметровФункциональныхОпций(Форма, Организация) Экспорт
    ПараметрыФО = Новый Структура(“ПараметрУчетПоСкладам”, Организация); Форма.УстановитьПараметрыФункциональныхОпцийФормы(ПараметрыФО);
    КонецПроцедуры
    </doc>
    В эту процедуру я передаю саму форму, которую надо обновить и ссылку для параметра функциональной опции.
    Часть 2.
    Создал обработку внешнюю. Создал форму. Создал два реквизита на форме:ДокументМетаданных – Тип строка, с возможностью выбора из спискаСтруктураДокумента – Тип Дерево значений, в дереве значений создал реквизит колонку Имя.Далее, в обработчике события создания формы на сервере, я заполняю список выбора реквизита ДокументМетаданных всеми документами моей конфигурации:<doc>
    &НаСервереПроцедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    СписокВыбора = Элементы.ДокументМетаданных.СписокВыбора; Для Каждого ДокументМ Из Метаданные.Документы Цикл СписокВыбора.Добавить(ДокументМ.Имя, ДокументМ.Синоним);
    КонецЦикла;
    КонецПроцедуры
    </doc>
    Далее, в обработчике события ПриИзменения вышеупомянутого реквизита формы, т.е. при выборе пользователем документа выполняю заполнение. Весь процесс я выполняю на сервере, так как только там доступен глобальный контекст Метаданные объекта.Для универсальности алгоритма я решил задачу используя рекурсию. Кратко: на сервере создаю новый объект дерево значений, создаю колонку Имя, заполняю и методом: ЗначениеВРеквизитФормы(Дерево, “СтруктураДокумента”), возвращаю в форму.
    <cod>
    &НаКлиентеПроцедура ДокументМетаданныхПриИзменении(Элемент)
    ДобавитьНаСервере(ДокументМетаданных);
    КонецПроцедуры

    &НаСервереПроцедура ДобавитьНаСервере(ДокументМ)

    МетаДокумент = Метаданные.Документы[ДокументМ];
    Дерево = Новый ДеревоЗначений; Дерево.Колонки.Добавить(“Имя”); СоздатьСтруктуруОбъектов(Дерево, МетаДокумент); ЗначениеВРеквизитФормы(Дерево, “СтруктураДокумента”);
    КонецПроцедуры // ДобавитьНаСервере()

    &НаСервереБезКонтекстаПроцедура СоздатьСтруктуруОбъектов(Дерево, МетаОбъект)
    СтрокаРеквизиты = Дерево.Строки.Добавить(); СтрокаРеквизиты.Имя = “Реквизиты”; СтрокаТабЧасти = Дерево.Строки.Добавить(); СтрокаТабЧасти.Имя = “Табличные части”; СтрокаФормы = Дерево.Строки.Добавить(); СтрокаФормы.Имя = “Формы”;
    СтрокаКоманды = Дерево.Строки.Добавить(); СтрокаКоманды.Имя = “Команды”;
    СтрокаМакеты = Дерево.Строки.Добавить(); СтрокаМакеты.Имя = “Макеты”;
    // Добавляем реквизиты ДобавитьРеквизиты(СтрокаРеквизиты, МетаОбъект);
    // Добавляем таб части Для Каждого ТабЧасть Из МетаОбъект.ТабличныеЧасти Цикл  ДобавитьРеквизиты(СтрокаТабЧасти, ТабЧасть); КонецЦикла;
    // Добавляем формы Для Каждого ФормаОбъекта Из МетаОбъект.Формы Цикл  НоваяСтрока = СтрокаФормы.Строки.Добавить(); НоваяСтрока.Имя = ФормаОбъекта.Имя; КонецЦикла;
    // Добавляем команды Для Каждого КомандаОбъекта Из МетаОбъект.Команды Цикл  НоваяСтрока = СтрокаКоманды.Строки.Добавить(); НоваяСтрока.Имя = КомандаОбъекта.Имя; КонецЦикла;
    // Добавляем макеты Для Каждого МакетОбъекта Из МетаОбъект.Макеты Цикл  НоваяСтрока = СтрокаМакеты.Строки.Добавить(); НоваяСтрока.Имя = МакетОбъекта.Имя; КонецЦикла;
    КонецПроцедуры

    &НаСервереБезКонтекстаПроцедура ДобавитьРеквизиты(СтрокаРеквизиты, МетаОбъект)
    Для каждого Реквизит Из МетаОбъект.Реквизиты Цикл НоваяСтрокаРеквизит = СтрокаРеквизиты.Строки.Добавить(); НоваяСтрокаРеквизит.Имя = Реквизит.Имя; НовыйМетаОбъект = “”;
    Если Справочники.ТипВсеСсылки().СодержитТИп(Реквизит.Тип.Типы()[0]) Тогда  НовыйМетаОбъект = Метаданные.Справочники[Реквизит.Тип.ПривестиЗначение().Метаданные().Имя]; ИначеЕсли Документы.ТипВсеСсылки().СодержитТИп(Реквизит.Тип.Типы()[0]) Тогда НовыйМетаОбъект = Метаданные.Документы[Реквизит.Тип.ПривестиЗначение().Метаданные().Имя]; КонецЕсли; Если НовыйМетаОбъект<>”” Тогда  ДобавитьРеквизиты(НоваяСтрокаРеквизит, НовыйМетаОбъект);
    КонецЕсли;
    КонецЦикла;

    КонецПроцедуры
    </cod> 
    Я обрабатываю ссылочные реквизиты только на тип справочник и документ, но по желанию можно добавить и все остальные ссылочные типы.

  21. Домашнее задание выполнено.
    С функциональными опциями трудностей не возникло. Установка параметра функциональной опции осуществляется при открытии формы документа поступления/отгрузки, а также при изменении организации в докуенте.
    Создана обработка “Метаданные документа”. На форме обработки располагается выпадающий список, в котором выбирается вид документа, а также дерево метаданных этого документа. Реализована возможность разворачивать структуру для реквизитов ссылочных типов. При этом, если реквизит содержит несколько ссылочных типов (имеет составной тип), то имеется возможность развернуть каждый из ссылочных типов (как, например, в конструкторе запросов). Данные подгружаются в дерево по мере разворачивания ссылочных реквизитов. При этом под ссылочными типами подразумеваются справочники, документы, перечисления, планы видов характеристик/счетов/видов расчета. Принадлежность к ссылочному типу определяется последовательным сопоставлением типа реквизита с описаниями типов, полученных с помощью функции “ТипВсеСсылки”.
    Домашнее задание выполнено.
    С функциональными опциями трудностей не возникло. Установка параметра функциональной опции осуществляется при открытии формы документа поступления/отгрузки, а также при изменении организации в документе.
    Создана обработка “Метаданные документа”. На форме обработки располагается выпадающий список, в котором выбирается вид документа, а также дерево метаданных этого документа. Реализована возможность разворачивать структуру для реквизитов ссылочных типов. При этом, если реквизит содержит несколько ссылочных типов (имеет составной тип), то имеется возможность развернуть каждый из ссылочных типов (как, например, в конструкторе запросов). Данные подгружаются в дерево по мере разворачивания ссылочных реквизитов. При этом под ссылочными типами подразумеваются справочники, документы, перечисления, планы видов характеристик/счетов/видов расчета. Принадлежность к ссылочному типу определяется последовательным сопоставлением типа реквизита с описаниями типов, полученных с помощью функции “ТипВсеСсылки”.

  22. Задание выполнено. Сложность возникла при создании обработки по метаданным. А если точнее, заполнение реквизитов у реквизита ссылочного типа. Через такие дебри пришлось пролезать, чтобы до них дотянуться. Реквизиты документа, ТЧ и т.п. для данного объекта – без проблем. А вот определить, что реквизит ссылочный, и взять его реквизиты и их тоже вывести…… Но все же результат был достигнут и обработка работает корректно. Единственное, терзают смутные сомнения, что возможно, есть более простой подход.
     
    P.S. Есть недочеты по главе 19. Она есть обновленная или прислать на почту найденные ошибки?

    • Обновления пока не было, поэтому присылайте информацию на почту.