Продвинутый курс. Домашнее задание №3
Эта запись посвящена участникам 2-го потока продвинутого курса по программированию.
Третье задание по 0-му блоку продвинутого курса.
Для выполнения рекомендуется изучить следующие главы 0-го курса.
Глава 16.Настройка командного интерфейса конфигурации.
Глава 17. Функциональные опции.
Глава 18. Простые правила разработки интерфейсов.
Глава 19. Работа с метаданными.
Глава 20. Параметры сеанса.
К сожалению, у Вас недостаточно прав для просмотра этой записи. Если Вы еще не залогинены на сайте — залогиньтесь. Если Вы оплачивали курс, у Вас активирован токен доступа, Вы залогинены, но Вы видите эту запись — напишите нам на e-mail поддержки.
Задание сделал. Вспоминал назначение параметров функциональных опций. По обработке: появилась идея соединить список реквизитов с расположением на форме (видимость/невидимость и частота использования), наиболее важные реквизиты можно выводить в числе первых.
Речь идет о частоте обращения пользователей к тем или иным реквизитам объекта?
Какая польза будет от такой сортировки?
Например, когда проверяется корректность обновления при большом количестве объектов. Так, мы при тестировании первым делом смотрим проведение документов, печать. Допускается потеря реквизита с формы.
Краткая справка по документу и основным важным реквизитам могла бы быть использована для проверки наличия 10-15 самых важных реквизитов.
Ясно, спасибо.
Задание выполнено. Затруднения были героически преодолены. Особый героизм был проявлен во второй части задания :) Было сразу ясно и понятно, что это рекурсия + метаданные, но вот вопрос техреализации был не так очевиден.
Задание выполнил.
Первая часть затруднений не вызвала.
Вторая часть:
До этого с деревом значений не работал, было интересно разобраться.
В обработчик изменения поля ввода “ВидДокумента” вставил вызов серверной контекстной процедуры. Ниже код:
&НаСервере
Процедура ЗаполнитьДеревоНаСервере()
ТекДерево = ДанныеФормыВЗначение(Объект.Реквизиты, Тип(“ДеревоЗначений”));
Строки = ТекДерево.Строки;
Строки.Очистить();
ЗаполнитьУзелДерева(Метаданные.Документы, ТекДерево, Объект.Документ);
ЗначениеВДанныеФормы(ТекДерево, Объект.Реквизиты);
КонецПроцедуры // ЗаполнитьДеревоНаСервере()
&НаСервереБезКонтекста
Процедура ЗаполнитьУзелДерева(ГдеИскать, Строка, Реквизит, ТекОбъектМД=Неопределено, ТабЧасть=Неопределено)
Если ТекОбъектМД = Неопределено Тогда
ТекОбъектМД = ГдеИскать.Найти(Реквизит);
Если ТекОбъектМД = Неопределено Тогда
Возврат;
КонецЕсли;
КонецЕсли;
СтрокаРеквизитов = Строка.Строки.Добавить();
СтрокаРеквизитов.ИмяРеквизита = “Реквизиты”;
Для каждого ТекРеквизит Из ТекОбъектМД.Реквизиты Цикл
ТекСтрока = СтрокаРеквизитов.Строки.Добавить();
ТекСтрока.ИмяРеквизита = ТекРеквизит.Имя;
ЗаполнитьУзелДерева(Метаданные.Справочники, ТекСтрока, Строка(ТекРеквизит.Тип));
КонецЦикла;
Если НЕ ТабЧасть=Неопределено Тогда
Возврат;
КонецЕсли;
СтрокаТабЧастей = Строка.Строки.Добавить();
СтрокаТабЧастей.ИмяРеквизита = “ТабличныеЧасти”;
Для каждого ТекТабчасть Из ТекОбъектМД.ТабличныеЧасти Цикл
ТекСтрока = СтрокаТабЧастей.Строки.Добавить();
ТекСтрока.ИмяРеквизита = ТекТабчасть.Имя;
ЗаполнитьУзелДерева(Метаданные.Справочники, ТекСтрока, Строка(ТекРеквизит.Тип), ТекТабчасть, Истина);
КонецЦикла;
СтрокаФорм = Строка.Строки.Добавить();
СтрокаФорм.ИмяРеквизита = “Формы”;
Для каждого ТекФорма Из ТекОбъектМД.Формы Цикл
ТекСтрока = СтрокаФорм.Строки.Добавить();
ТекСтрока.ИмяРеквизита = ТекФорма.Имя;
КонецЦикла;
СтрокаКоманд = Строка.Строки.Добавить();
СтрокаКоманд.ИмяРеквизита = “Команды”;
Для каждого ТекКоманда Из ТекОбъектМД.Команды Цикл
ТекСтрока = СтрокаКоманд.Строки.Добавить();
ТекСтрока.ИмяРеквизита = ТекКоманда.Имя;
КонецЦикла;
СтрокаМакетов = Строка.Строки.Добавить();
СтрокаМакетов.ИмяРеквизита = “Макеты”;
Для каждого ТекМакет Из ТекОбъектМД.Макеты Цикл
ТекСтрока = СтрокаМакетов.Строки.Добавить();
ТекСтрока.ИмяРеквизита = ТекМакет.Имя;
КонецЦикла;
КонецПроцедуры // ЗаполнитьУзелДерева()
Задание выполнил. Первый пункт без проблем.
2.
&НаСервере
Процедура СоставДокументаСервер()
Дерево=ДанныеФормыВЗначение(Состав,Тип(“ДеревоЗначений”));
Строки=Дерево.Строки;
Строки.Очистить();
МетаданныеДокумента=Метаданные.Документы.Найти(МетаДокумент);
СформироватьСтрокиДерева(Дерево,МетаданныеДокумента);
ЗначениеВДанныеФормы(Дерево,Состав);
КонецПроцедуры // СоставДокументаСервер()
&НаСервереБезКонтекста
Процедура СформироватьСтрокиДерева(ТекРодитель,ТекущиеМетаданные)
ОбработкаСтрок(“СтандартныеРеквизиты”,ТекРодитель,ТекущиеМетаданные);
ОбработкаСтрок(“Реквизиты”,ТекРодитель,ТекущиеМетаданные);
ОбработкаСтрок(“ТабличныеЧасти”,ТекРодитель,ТекущиеМетаданные);
ОбработкаСтрок(“Формы”,ТекРодитель,ТекущиеМетаданные);
ОбработкаСтрок(“Макеты”,ТекРодитель,ТекущиеМетаданные);
КонецПроцедуры // СформироватьДерево()
&НаСервереБезКонтекста
Процедура ОбработкаСтрок(Группа,ТекРодитель,ТекущиеМетаданные)
Если (ТипЗнч(ТекущиеМетаданные[Группа])=Тип(“КоллекцияОбъектовМетаданных”))И (ТекущиеМетаданные[Группа].Количество()=0) Тогда
Возврат;
КонецЕсли;
НоваяСтрока=ТекРодитель.Строки.Добавить();
НоваяСтрока.Имя=Группа;
Для каждого ТекСтрока Из ТекущиеМетаданные[Группа] Цикл
ПодчиненнаяСтрока=НоваяСтрока.Строки.Добавить();
ПодчиненнаяСтрока.Имя=ТекСтрока.Имя;
Если Группа=”ТабличныеЧасти” Тогда
ОбработкаСтрок(“СтандартныеРеквизиты”,ПодчиненнаяСтрока,ТекСтрока);
ОбработкаСтрок(“Реквизиты”,ПодчиненнаяСтрока,ТекСтрока);
ИначеЕсли Группа=”Реквизиты” Тогда
МассивТипов=ТекСтрока.Тип.Типы();
Для каждого ТекТип Из МассивТипов Цикл
МетаРеквизит=Метаданные.НайтиПоТипу(ТекТип);
Если (МетаРеквизит<>Неопределено)Или(Группа=”ТабличныеЧасти”) Тогда
ОбработкаСтрок(“СтандартныеРеквизиты”,ПодчиненнаяСтрока,МетаРеквизит);
ОбработкаСтрок(“Реквизиты”,ПодчиненнаяСтрока,МетаРеквизит);
КонецЕсли;
КонецЦикла;
КонецЕсли;
КонецЦикла;
КонецПроцедуры //
Задание выполнено.
1) По первому пункту затруднений не возникло. Работа с функциональными опциями понятна.
2) Уже давно активно использую приемы работы с метаданными и рекурсию, так что ход решения был ясен. Ну а вот на реализацию ушло достаточно много времени.
Листинги приводить не буду, т.к. реализация очень близка к эталонному решению. В целом все понятно. Из положительных моментов – освоил работу с деревом значений, до этого практически не использовал.
Задание выполнено.
1) По первому пункту затруднений не возникло. Работа с функциональными опциями понятна.
2) Уже давно активно использую приемы работы с метаданными и рекурсию, так что ход решения был ясен. Ну а вот на реализацию ушло достаточно много времени.
Листинги приводить не буду, т.к. реализация очень близка к эталонному решению. В целом все понятно. Из положительных моментов – освоил работу с деревом значений, до этого практически не использовал.
1) В первой части сделал почти то же, что разбиралось по ходу просмотра:создал ФО, параметр Организация, и При создании на сервере к разбираемому договору в структуре добавил еще и Склад. В реализации то же.
2) Обработку оставил ту же, что делалась в разбираемом материале, только вместо списка форм сделал дерево с реквизитами ИмяРеквизита и ТипЗначения (необязательно). В обработке выбора так же обращаемся к серверной процедуре заполнения дерева, где значение метаданных узнаем по Метаданные.Документы.Найти(ВыбранноеЗначение);
Итак, для того, чтоб определить, ссылочного ли типа реквизит, заранее создал таблицу значений с документами и справочниками – Имя метаданного и Группа (Документ, справочник). Отдельная процедура у меня
РазвернутьСтруктуруМетаданных(СвойстваОбъекта,МассивСправочниковИДокументов,СтрокиДерева,СтрокаРодителя)
Там перебираю и добавляю в дерево отдельно реквизиты объекта, его тч и реквизиты, формы и макеты
1) В первой части сделал почти то же, что разбиралось по ходу просмотра:создал ФО, параметр Организация, и При создании на сервере к разбираемому договору в структуре добавил еще и Склад. В реализации то же.
2) Обработку оставил ту же, что делалась в разбираемом материале, только вместо списка форм сделал дерево с реквизитами ИмяРеквизита и ТипЗначения (необязательно). В обработке выбора так же обращаемся к серверной процедуре заполнения дерева, где значение метаданных узнаем по Метаданные.Документы.Найти(ВыбранноеЗначение);
Итак, для того, чтоб определить, ссылочного ли типа реквизит, заранее создал таблицу значений с документами и справочниками – Имя метаданного и Группа (Документ, справочник).
Отдельная процедура у меня
<code>РазвернутьСтруктуруМетаданных(СвойстваОбъекта,МассивСправочниковИДокументов,СтрокиДерева,СтрокаРодителя)
</code>
Там перебираю и добавляю в дерево отдельно реквизиты объекта, его тч и реквизиты, формы и макеты.
В то время, как перебираю реквизиты, проверяю , ссылочного ли он типа, если да – то снова проверяю
<code>
Разворачивать = ложь;
Если не СтрокаРодителя = Неопределено тогда
Если не СтрокаРеквизитаТч.ИмяРеквизита = СтрокаРодителя.ИмяРеквизита тогда
Разворачивать = истина;
КонецЕсли;
иначе
Разворачивать = истина;
КонецЕсли;
Если Разворачивать тогда
МетаданныеРеквизита = Метаданные[СтрокаМассива.Группа][СтрокаМассива.ОбъектМетаданных];
РазвернутьСтруктуруМетаданных(МетаданныеРеквизита,МассивСправочниковИДокументов,СтрокаРеквизитаТч.Строки,СтрокаРеквизитаТч.Родитель);
КонецЕсли;
</code>
То же – для реквизита ТЧ
В общем, может возникнуть бесконечный цикл, если например у ор-ции есть реквизит контрагент, а у контрагента – ор-ция, поэтому надо проверить это сначала
Была еще небольшая проблема с ДанныеФормыВЗначение и ЗначениеВДанныеФормы. Просто в первый раз в на упр. форме пишу:)
Добрый день. ДЗ сделал. Много потратил времени на поиск метода – перебрать все свойство метаданных документа, такие как (автонумерация, движения, формы, и так далее) если бы нашел то каждый элемент бы проверял на Тип(“КоллекцияОбъектовМетаданных”)- и уже его бы и переберал, но так и не нашел. (( Поэтому пришлось по тупому
// формы
// макеты
Задание выполнила.
Создана ФО «ВестиУчетПоСкладам», настроен состав, создан параметр ФО со ссылкой в свойстве «Использование» на справочник «Организации». В формах документов в обработчиках события «При изменении» устанавливаем параметры ФО
ПараметрФО= Новый Структура(“ПараметрВестиУчетПоСкладам”, Объект.Организация);
УстановитьПараметрыФункциональныхОпцийФормы(ПараметрФО);
Сделала обработку с реквизитами «ВыбДокумент» и «Дерево». Реквизиту «Дерево» добавлена колонка «Имя».
В обработчике формы «ПриСозданииНаСервере» заполняю список документов.
При выборе документа в форме обработки в обработчике события «ВыбДокументПриИзменении» заполняю дерево значений, вызываю серверную процедуру:
&НаСервере
Процедура ЗаполнитьНаСервере()
СписокДерево = ДанныеФормыВЗначение(Дерево, Тип(“ДеревоЗначений”));
СтрокиДерева = СписокДерево.Строки;
СтрокиДерева.Очистить();
ОбъектМетаданных = Метаданные.НайтиПоПолномуИмени(“Документ.” + ВыбДокумент);
ДобавитьСтроки(ОбъектМетаданных, СтрокиДерева);
ЗначениеВДанныеФормы(СписокДерево, Дерево);
КонецПроцедуры
В процедуре «ДобавитьСтроки» обходим сначала Реквизиты, затем Табличные части, Макеты и Формы документа и заполняю СтрокиДерева, проверяю, относится ли текущий объект к ссылочному типу. Если да, обходим реквизиты с помощью рекурсии.
Долго мучилась с выводом результата на форму, пока не догадалась добавить колонку реквизиту «Дерево»
Задание выполнил.
1. Добавил в кофигурацию справочник Склады и реквизиты Склад в документах ПоступлениеТоваровИУслуг и РеализацияТоваровИУслуг (в табличную часть), реквизит «Вести учет по складам» в справочнике Организации. Создал функциональную опцию ВестиУчетПоСкладам с хранением в Справочник.Организации.Реквизит.ВестиУчетПоСкладам. В состав функциональной опции включил реквизиты Склад документов ПоступлениеТоваровИУслуг и РеализацияТоваровИУслуг. Добавил параметр функциональной опции Организация, в свойстве Использование указал объект Справочник.Организации.
В формах документов ПоступлениеТоваровИУслуг и РеализацияТоваровИУслуг в обработчиках событий при измении организации и при создании на сервере устанавливаются параметры функциональных опций. Пример:
<code>
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
ПараметрыФО = Новый Структура;
ПараметрыФО.Вставить(“Организация”, Объект.Организация);
УстановитьПараметрыФункциональныхОпцийФормы(ПараметрыФО);
КонецПроцедуры
</code>
2. Создал обработку «МетаданныеДокумента». В форме обработки добавил реквизиты ИмяДокумента (тип Строка) и МетаданныеДокумента (тип ДеревоЗначений). В обработчике формы ПриСозданииНаСервере заполняется список имеющихся в конфигурации документов:
<code>
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
Для каждого ВидДокумента Из Метаданные.Документы Цикл
Элементы.ИмяДокумента.СписокВыбора.Добавить(ВидДокумента.Имя, ВидДокумента.Синоним);
КонецЦикла;
КонецПроцедуры
</code>
При выборе вида документа в реквизите формы ИмяДокумента происходит заполнение дерева значений:
<code>
&НаКлиенте
Процедура ДокументПриИзменении(Элемент)
СформироватьДеревоДокумента();
КонецПроцедуры
&НаСервере
Процедура СформироватьДеревоДокумента()
Дерево = ДанныеФормыВЗначение(МетаданныеДокумента, Тип(“ДеревоЗначений”));
СтрокиДерева = Дерево.Строки;
СтрокиДерева.Очистить();
ПолноеИмя = “Документ.” + ИмяДокумента;
ОбъектМетаданных = Метаданные.НайтиПоПолномуИмени(ПолноеИмя);
ДобавитьОбъект(ОбъектМетаданных, СтрокиДерева);
ЗначениеВДанныеФормы(Дерево, МетаданныеДокумента);
КонецПроцедуры // СформироватьДеревоДокумента()
&НаСервере
Процедура ДобавитьОбъект(ОбъектМетаданных, СтрокиДерева)
//реквизиты
Если ОбъектМетаданных.Реквизиты.Количество() > 0 Тогда
НоваяСтрока = СтрокиДерева.Добавить();
НоваяСтрока.Имя = “Реквизиты”;
Для каждого Реквизит Из ОбъектМетаданных.Реквизиты Цикл
ДобавитьРеквизит(Реквизит, НоваяСтрока.Строки);
КонецЦикла;
КонецЕсли;
// табличные части
Если ОбъектМетаданных.ТабличныеЧасти.Количество() > 0 Тогда
НоваяСтрока = СтрокиДерева.Добавить();
НоваяСтрока.Имя = “Табличные части”;
Для каждого ТабличнаяЧасть Из ОбъектМетаданных.ТабличныеЧасти Цикл
НовыйТЧ = НоваяСтрока.Строки.Добавить();
НовыйТЧ.Имя = ТабличнаяЧасть.Синоним;
Если ТабличнаяЧасть.Реквизиты.Количество() > 0 Тогда
Для каждого Реквизит Из ТабличнаяЧасть.Реквизиты Цикл
ДобавитьРеквизит(Реквизит, НовыйТЧ.Строки);
КонецЦикла;
КонецЕсли;
КонецЦикла;
КонецЕсли;
// формы
Если ОбъектМетаданных.Формы.Количество() > 0 Тогда
НоваяСтрока = СтрокиДерева.Добавить();
НоваяСтрока.Имя = “Формы”;
Для каждого Форма Из ОбъектМетаданных.Формы Цикл
НоваяФорма = НоваяСтрока.Строки.Добавить();
НоваяФорма.Имя = Форма.Синоним;
КонецЦикла;
КонецЕсли;
// макеты
Если ОбъектМетаданных.Макеты.Количество() > 0 Тогда
НоваяСтрока = СтрокиДерева.Добавить();
НоваяСтрока.Имя = “Макеты”;
Для каждого Макет Из ОбъектМетаданных.Макеты Цикл
НовыйМакет = НоваяСтрока.Строки.Добавить();
НовыйМакет.Имя = Макет.Синоним;
КонецЦикла;
КонецЕсли;
КонецПроцедуры // ДобавитьОбъект()
Процедура ДобавитьРеквизит(Реквизит, СтрокиДерева)
НовыйРеквизит = СтрокиДерева.Добавить();
НовыйРеквизит.Имя = Реквизит.Синоним;
МассивТиповРеквизита = Реквизит.Тип.Типы();
Если МассивТиповРеквизита.Количество() > 1 Тогда
Возврат;
КонецЕсли;
ОбъектМетаданныхТипаРеквизита = Метаданные.НайтиПоТипу(МассивТиповРеквизита[0]);
ЭтоСсылочныйТип = Ложь;
Попытка
СтандартныеРеквизитСсылка = ОбъектМетаданныхТипаРеквизита.СтандартныеРеквизиты.Ссылка;
ЭтоСсылочныйТип = Истина;
Исключение
КонецПопытки;
Если ЭтоСсылочныйТип Тогда
ДобавитьОбъект(ОбъектМетаданныхТипаРеквизита, НовыйРеквизит.Строки);
КонецЕсли;
КонецПроцедуры
</code>
Задание выполнил. Первую часть задания реализовал через Функциональную опцию, которая привязана к реквизиту в справочнике “Организации” + Параметр Функциональной опции, который связан со спр. “Организации”. А в модуле формы документов добавил обработчики событий при изменении организации и ПриСозданииНаСервере, в которых устанавливаю параметр функциональной опции.
Для второй части задания создал обработку с полями для выбора документа и ДеревомЗначений. Для отображение реквизитов выбранной ссылки документа решил создавать след. структуру:
-наименование вида документа
–стандатные реквизиты
—…
–реквизиты
—…
–формы
—…
–макеты
—…
для этого реализовал рекурсивную функцию вывода результатов:
<code>
Процедура ЗаполнитьУзел(Родитель,МетаданныеДокумента)
//СтандартныеРеквизиты
ЗаполнитьВетку(Родитель,”СтандартныеРеквизиты”,МетаданныеДокумента);
ЗаполнитьВетку(Родитель,”Реквизиты”,МетаданныеДокумента);
ЗаполнитьВетку(Родитель,”Формы”,МетаданныеДокумента);
ЗаполнитьВетку(Родитель,”Макеты”,МетаданныеДокумента);
КонецПроцедуры
&НаСервере
Процедура ЗаполнитьВетку(Родитель,Ветка,МетаданныеДокумента)
Реквизиты=Родитель.Строки.Добавить();
Реквизиты.Реквизит=Ветка;
Для каждого МетаРеквизит Из МетаданныеДокумента[Ветка] Цикл
Строка=Реквизиты.Строки.Добавить();
Строка.Реквизит=МетаРеквизит.Имя;
Если (Ветка<>”Формы”) и (Ветка<>”Макеты”) Тогда
Если (МетаРеквизит.Имя<>”Ссылка”) и (МетаРеквизит.Имя<>”Родитель”) и (МетаРеквизит.Имя<>”Владелец”) Тогда
Если Метаданные.Справочники.Найти(Строка(Метареквизит.тип))<>Неопределено Тогда
ЗаполнитьУзел(Строка,Метаданные.Справочники.Найти(Строка(Метареквизит.тип)));
ИначеЕсли Метаданные.Документы.Найти(Строка(Метареквизит.тип))<>Неопределено Тогда
ЗаполнитьУзел(Строка,Метаданные.Документы.Найти(Строка(Метареквизит.тип)));
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЦикла;
КонецПроцедуры // ЗаполнитьВетку()
</code>
Выполнил…
По работе:
1.1.Создал справочник, добавил реквизиты, вывел реквизиты на “форму документа”
обоих документов, создал и настроил функциональную опцию, создал параметр
функциональной опции.
1.2.У документа “ПоступлениеТоваровИУслуг” на “форме документа” сделал процедуру
привязаную к событию изменения реквизит “Организация”, текст процедуры:
ОпцияФ = новый Структура(“Организация”,Объект.Организация);
УстановитьПараметрыФункциональныхОпцийФормы(ОпцияФ);
1.3.Создал процедуру “ПриСозданииНаСервере” и добавил в ней точно такой-же код.
1.4.Выполнил 1.2. и 1.3. Для документа “РеализацияТоваровИУслуг”
2.Сделал обработку с реквизитамии т.д. но это не самое интересное… по событию
выбора документа из списка выбора запускаю обход по метаданным документа (что-то
вроде того, что было на видеоуроке), если реквизит имеет на простой тип вызывается
процедура ДочерниеУзлыМетаданных, которая при необходимости деле сама себя
рекурсивно вызывает. Тут лучше привести сам код, иначе объяснить значительно
сложнее:
&НаСервереБезКонтекста
Процедура ДочерниеУзлыМетаданных(Объект,стр_маршрут,Строка)
и1=0;
НовыйОбъект=Метаданные.НайтиПоПолномуИмени(Объект);
Для Каждого Рекв Из НовыйОбъект.Реквизиты Цикл
Строка2 = Строка.Строки.Добавить();
Строка2.Наименование = Рекв.Имя;
Строка2.Описание = Рекв.Тип;
Попытка
полноеИмя=метаданные.НайтиПоТипу(НовыйОбъект.Реквизиты[и1].Тип.Типы()[0]).ПолноеИмя();
Если Найти(стр_маршрут,”>”+полноеИмя+”<” )=0 Тогда
стр_маршрут=стр_маршрут+полноеИмя+”<,>”;
ДочерниеУзлыМетаданных(ПолноеИмя,стр_маршрут,Строка2);
КонецЕсли;
Исключение
КонецПопытки;
и1=и1+1;
КонецЦикла;
КонецПроцедуры
Для полноценного теста добавил в документы реквизитов.
====================================
много сложностей вызвала работа с метаданными (т.к. в синтаксис помошнике описано мягко говоря не подробно, а может не привык) и немного сложностей с Деревом значений (т.к. ранее никогда им не пользовался и не сразу удалось его вывести на форму).
ДЗ выполнено.
1. Создал справочник Склады. В справочнике организации создал реквизит типа булево ВестиУчетПоСкладам. Создал функциональной опцию ВестиУчетПоСкладам, оставил для нее Привилегированный режим получения (надо использовать новшества платформы на полную :)).В документе “Реализация товаров и услуг” добавил реквизит Склад в табличную часть, в документе “Поступление товаров и услуг” в шапку. Включил эти реквизиты в состав функциональной опции. Создал параметр функциональных опций Организация, в поле использование выбрал справочник организаций. В обработчики документов ОрганизацияПриИзменении и ПриСозданииНаСервере добавил код
ПараметрыФО = Новый Структура(“Организация”, Объект.Организация);
УстановитьПараметрыФункциональныхОпцийФормы(ПараметрыФО)
2. Подобную обработку делал для 8.1, немного доработал под 8.2. Особых затруднений не было.
Уже после доработал алгоритм обработки “Метаданные документа” для избежания зацикливания при наличии циклических ссылок для этого использовал Массив в котором сохранял уже обработанный объект и если новый объект находил в этом массиве, то его дальнейший анализ не проводил.
После добавления необходимого справочника и реквизитов Склад в документы создал функциональную опцию ВестиУчетПоСкладам, с хранением в одноименном реквизите справочника Организации, также создал параметр ФО «Организация» с типом СпроавчникСсылка.Организации. Разместил реквизиты Склад на формах документов Поступление и Реализация, в модулях форм в процедурах ПриСозданииНаСервере и ОрганизацияПриИзменении с помощью команды УстановитьПараметрыФункциональныхОпцийФормы(Новый Структура(“Организация”, Объект.Организация)) .
При заполнении структуры метаданных документы в обработке «Метаданные документа» использовал рекурсивную процедуру, в которую передавал текущий объект метаданных и текущую строку дерева значений. При этом принял следующее решение, если анализируемый реквизит составного типа, то его дальнейший анализ не провожу.
При решении столкнулся с необходимостью определить относится ли текущий объект к ссылочному типу или нет. Эту задачу я решил от обратного, создал массив с не ссылочными типами данных (примитивные типы данных, ХранилищеЗначения, УникальныйИдентификатор) и искал в нем тип текущего объекта, если не находил значит ссылочный тип. Вторая особенность заключается в том, что структура метаданных перечисления отличаются от других ссылочных типов, у него нет реквизитов и табличных частей, но зато есть ЗначенияПеречисления. Это необходимо учитывать при обработке перечислений. Последняя особенность заключатся в том, что реквизит объекта это не от же самое, что объект метаданных тип которого имеет этот реквизит и хотя в отладчике тип у них одинаковый ОбъектМетаданных на самом деле реквизит имеет тип ОбъектМетаданных: Реквизит, а у его типа в зависимости от того какой это тип может быть ОбъектМетаданных: Справочник, ОбъектМетаданных: Документ и т.д. и для того, чтобы получить второй объект по реквизиту я использовал метод НайтиПоТипу объекта Метаданные следующим образом Метаданные.НайтипоТипу(Реквизит.Тип.Типы()[0]).
Задание выполнено.
1.Ввел функциональную опцию ВестиУчетПоСкладам с хранением в соответствующем реквизите справочника Организации. Ввел параметр ф.опции Организация с использованием соотв.справочника. В обработчиках документов при создании на сервере и ОрганизацияПриИзменении вызывается УстановитьПараметрыФОФормы.
В общем все как в уроках.
2.Алгоритм работы:
В обработчике формы ПриСозданииНаСервере в список выбора реквизита формы загружаются все документы из Метаданные.Документы.
При выборе документа запускается процедура ПостроитьДерево(Узел <СтрокаДереваЗначений>, СвойстваУзла <ОбъектМетаданных>).
В ней инициализируется структура Коллекции значениями типа “Реквизиты”, СвойстваУзла.Реквизиты; СтрЗаменить(“Табличные части”,” “,”_”), СвойстваУзла.ТабличныеЧасти и т.д.
Каждая вставка заключается в оператор попытка..исключение.
В начале рекурсии Узел – выбранный документ, а СвойстваУзла – Метаданные.Документы.Найти(ИмяДокумента).
Далее в цикле по Коллекциям вызывается процедура ПостроитьКоллекциюМетаданныхУзла (Узел <СтрокаДерева>, НазваниеКоллекции <Ключ>, КоллецияОбъектовМетаданных <Значение>).
Вот ее текст:
Коллекция = Узел.Строки.Добавить();
Коллекция.Имя = СтрЗаменить(НазваниеКоллекции,”_”,” “);
Для каждого Элемент Из КоллецияОбъектовМетаданных Цикл
Попытка
Типы = Элемент.Тип.Типы();
Для каждого Тип Из Типы Цикл
Строка = Коллекция.Строки.Добавить();
Строка.Имя = Элемент.Имя;
Строка.Имя = Строка.Имя+” (“+ Тип+”)”;
МетаОбъект = Метаданные.НайтиПоТипу(Тип);
Если МетаОбъект<>Неопределено И Строка.Уровень()<10 Тогда
ПостроитьДерево(Строка,МетаОбъект)
КонецЕсли;
КонецЦикла;
Исключение
Строка = Коллекция.Строки.Добавить();
Строка.Имя = Элемент.Имя;
Если Строка.Уровень()<10 Тогда
ПостроитьДерево(Строка,Элемент)
КонецЕсли;
КонецПопытки;
КонецЦикла.