Структура подчиненности (связанные объекты)¶
Добавление Структуры подчиненности (связанные документы) в расширение¶
При добавлении нового реквизита в объект (документ, справочник) может возникнуть задача вывода связанных документов.
Если добавлять в расширение КритерииОтбора.СвязанныеДокументы, тогда в расширение будут добавлены все участвующие объекты.
Можно решить иначе - добавлением кода:
1. Добавляем в расширение процедуру ОбщийМодуль.ВариантыОтчетовПереопределяемый.ОпределитьОбъектыСКомандамиОтчетов
&После("ОпределитьОбъектыСКомандамиОтчетов") Процедура мн_ОпределитьОбъектыСКомандамиОтчетов(Объекты) Объекты.Добавить(Метаданные.Документы.ОрдерНаОтражениеИзлишковТоваров); Объекты.Добавить(Метаданные.Документы.ОрдерНаОтражениеНедостачТоваров); КонецПроцедуры
2. Добавляем в расширение ОбщийМодуль.СтруктураПодчиненностиСлужебный.ИндексТиповСвязанныхОбъектов
&ИзменениеИКонтроль("ИндексТиповСвязанныхОбъектов") Функция мн_ИндексТиповСвязанныхОбъектов() Индекс = Новый Соответствие; МетаданныеСвязанныхОбъектов = Метаданные.КритерииОтбора.СвязанныеДокументы; ТипыСвязанныхОбъектов = МетаданныеСвязанныхОбъектов.Тип.Типы(); ТипПараметраКоманды = Метаданные.ОбщиеКоманды.СвязанныеДокументы.ТипПараметраКоманды; Для Каждого ТипСвязанногоОбъекта Из ТипыСвязанныхОбъектов Цикл Если Не ТипПараметраКоманды.СодержитТип(ТипСвязанногоОбъекта) Тогда Индекс.Вставить(ТипСвязанногоОбъекта, Истина); КонецЕсли; КонецЦикла; #Вставка //{Проект Индекс.Вставить(Тип("ДокументСсылка.ОрдерНаОтражениеНедостачТоваров"), Истина); Индекс.Вставить(Тип("ДокументСсылка.ОрдерНаОтражениеИзлишковТоваров"), Истина); // } Проект . #КонецВставки Возврат Индекс; КонецФункции3. Добавляем в расширение ОбщиеФормы.СвязанныеДокументы:
- ОбъектыПоКритериюОтбора
- ВывестиРодительскиеОбъекты
&НаСервере &ИзменениеИКонтроль("ОбъектыПоКритериюОтбора") Функция пл_ОбъектыПоКритериюОтбора(ЗначениеКритерияОтбора) ШаблонЗапроса = "ВЫБРАТЬ РАЗРЕШЕННЫЕ | ПредставлениеТаблицы.Ссылка КАК Ссылка |ИЗ | ИмяТаблицы КАК ПредставлениеТаблицы |ГДЕ | ПредставлениеТаблицы.ИмяРеквизита = &ЗначениеКритерияОтбора"; ШаблонЗапросаОбъединения = "ВЫБРАТЬ | ПредставлениеТаблицы.Ссылка КАК Ссылка |ИЗ | ИмяТаблицы КАК ПредставлениеТаблицы |ГДЕ | ПредставлениеТаблицы.ИмяРеквизита = &ЗначениеКритерияОтбора"; ЧастиЗапроса = Новый Массив; ТекстЧастиЗапроса = ""; Для Каждого ЭлементСостава Из Метаданные.КритерииОтбора.СвязанныеДокументы.Состав Цикл Если НЕ ЭлементСостава.Тип.СодержитТип(ТипЗнч(ЗначениеКритерияОтбора)) Тогда Продолжить; КонецЕсли; ПутьКДанным = ЭлементСостава.ПолноеИмя(); Если СтрНайти(ПутьКДанным, "ТабличнаяЧасть") Тогда ОбъектМетаданных = ЭлементСостава.Родитель().Родитель(); Иначе ОбъектМетаданных = ЭлементСостава.Родитель(); КонецЕсли; Если НЕ ПравоДоступа("Чтение", ОбъектМетаданных) Тогда Продолжить; КонецЕсли; Точка = СтрНайти(ПутьКДанным, ".", НаправлениеПоиска.СКонца); ИмяРеквизита = Сред(ПутьКДанным, Точка + 1); ИмяТаблицы = ЭлементСостава.Родитель().ПолноеИмя(); ИмяТаблицы = СтрЗаменить(ИмяТаблицы, "ТабличнаяЧасть.", ""); Точка = СтрНайти(ИмяТаблицы, ".", НаправлениеПоиска.СКонца); ПредставлениеТаблицы = Сред(ИмяТаблицы, Точка + 1); ТекстЧастиЗапроса = ?(ТекстЧастиЗапроса = "", ШаблонЗапроса, ШаблонЗапросаОбъединения); ТекстЧастиЗапроса = СтрЗаменить(ТекстЧастиЗапроса, "ИмяТаблицы", ИмяТаблицы); ТекстЧастиЗапроса = СтрЗаменить(ТекстЧастиЗапроса, "ПредставлениеТаблицы", ПредставлениеТаблицы); ТекстЧастиЗапроса = СтрЗаменить(ТекстЧастиЗапроса, "ИмяРеквизита", ИмяРеквизита); ЧастиЗапроса.Добавить(ТекстЧастиЗапроса); КонецЦикла; #Вставка //Проект Всеволод ТекстЧастиЗапроса = ?(ТекстЧастиЗапроса = "", ШаблонЗапроса, ШаблонЗапросаОбъединения); ТекстЧастиЗапроса = СтрЗаменить(ТекстЧастиЗапроса, "ИмяТаблицы", "Документ.ОрдерНаОтражениеИзлишковТоваров"); ТекстЧастиЗапроса = СтрЗаменить(ТекстЧастиЗапроса, "ПредставлениеТаблицы", "ОрдерНаОтражениеИзлишковТоваров"); ТекстЧастиЗапроса = СтрЗаменить(ТекстЧастиЗапроса, "ИмяРеквизита", "пл_ДокументОснование"); ЧастиЗапроса.Добавить(ТекстЧастиЗапроса); ТекстЧастиЗапроса = ?(ТекстЧастиЗапроса = "", ШаблонЗапроса, ШаблонЗапросаОбъединения); ТекстЧастиЗапроса = СтрЗаменить(ТекстЧастиЗапроса, "ИмяТаблицы", "Документ.ОрдерНаОтражениеНедостачТоваров"); ТекстЧастиЗапроса = СтрЗаменить(ТекстЧастиЗапроса, "ПредставлениеТаблицы", "ОрдерНаОтражениеНедостачТоваров"); ТекстЧастиЗапроса = СтрЗаменить(ТекстЧастиЗапроса, "ИмяРеквизита", "пл_ДокументОснование"); ЧастиЗапроса.Добавить(ТекстЧастиЗапроса); // } Проект . #КонецВставки Если ЧастиЗапроса.Количество() > 0 Тогда Запрос = Новый Запрос; Разделитель = Символы.ПС + "ОБЪЕДИНИТЬ" + Символы.ПС; Запрос.Текст = СтрСоединить(ЧастиЗапроса, Разделитель); Запрос.УстановитьПараметр("ЗначениеКритерияОтбора", ЗначениеКритерияОтбора); Возврат Запрос.Выполнить().Выгрузить(); Иначе Возврат Новый ТаблицаЗначений; КонецЕсли; КонецФункции &НаСервере &ИзменениеИКонтроль("ВывестиРодительскиеОбъекты") Процедура пл_ВывестиРодительскиеОбъекты(ТекущийОбъект, ДеревоРодитель, ВыведенныеОбъекты, СлужебныеОбъекты, ИндексСвязейОбъектов) МетаданныеОбъекта = ТекущийОбъект.Метаданные(); СписокРеквизитов = Новый Массив; Если СлужебныеОбъекты = Неопределено Тогда СлужебныеОбъекты = Новый Соответствие; КонецЕсли; Если ИндексСвязейОбъектов = Неопределено Тогда ИндексСвязейОбъектов = Новый Соответствие; КонецЕсли; Для Каждого Реквизит Из МетаданныеОбъекта.Реквизиты Цикл Если Не Метаданные.КритерииОтбора.СвязанныеДокументы.Состав.Содержит(Реквизит) Тогда Продолжить; КонецЕсли; Для Каждого ТекущийТип Из Реквизит.Тип.Типы() Цикл МетаданныеРеквизита = МетаданныеТипаРеквизита(ТекущийТип); Если МетаданныеРеквизита.Метаданные = Неопределено Тогда Продолжить; КонецЕсли; ЗначениеРеквизита = ТекущийОбъект[Реквизит.Имя]; Если ЗначениеЗаполнено(ЗначениеРеквизита) И ТипЗнч(ЗначениеРеквизита) = ТекущийТип И ЗначениеРеквизита <> ТекущийОбъект И СписокРеквизитов.Найти(ЗначениеРеквизита) = Неопределено Тогда СписокРеквизитов.Добавить(ЗначениеРеквизита); КонецЕсли; КонецЦикла; КонецЦикла; #Вставка //Проект Всеволод Попытка Если ТипЗнч(ТекущийОбъект) = Тип("ДокументСсылка.ОрдерНаОтражениеНедостачТоваров") или ТипЗнч(ТекущийОбъект) = Тип("ДокументСсылка.ОрдерНаОтражениеИзлишковТоваров") Тогда СписокРеквизитов.Добавить(ТекущийОбъект.пл_ДокументОснование); КонецЕсли; Исключение КонецПопытки; // } Проект . #КонецВставки Для Каждого ТабличнаяЧасть Из МетаданныеОбъекта.ТабличныеЧасти Цикл ИменаРеквизитов = ""; СодержимоеТЧ = ТекущийОбъект[ТабличнаяЧасть.Имя].Выгрузить(); // ТаблицаЗначений Для Каждого Реквизит Из ТабличнаяЧасть.Реквизиты Цикл Если Не Метаданные.КритерииОтбора.СвязанныеДокументы.Состав.Содержит(Реквизит) Тогда Продолжить; КонецЕсли; Для Каждого ТекущийТип Из Реквизит.Тип.Типы() Цикл МетаданныеРеквизита = МетаданныеТипаРеквизита(ТекущийТип); Если МетаданныеРеквизита.Метаданные = Неопределено Тогда Продолжить; КонецЕсли; ИменаРеквизитов = ИменаРеквизитов + ?(ИменаРеквизитов = "", "", ", ") + Реквизит.Имя; Прервать; КонецЦикла; КонецЦикла; СодержимоеТЧ.Свернуть(ИменаРеквизитов); Для Каждого КолонкаТЧ Из СодержимоеТЧ.Колонки Цикл Для Каждого СтрокаТЧ Из СодержимоеТЧ Цикл ЗначениеРеквизита = СтрокаТЧ[КолонкаТЧ.Имя]; МетаданныеЗначения = МетаданныеТипаРеквизита(ТипЗнч(ЗначениеРеквизита)); Если МетаданныеЗначения.Метаданные = Неопределено Тогда Продолжить; КонецЕсли; Если ЗначениеРеквизита = ТекущийОбъект Или СписокРеквизитов.Найти(ЗначениеРеквизита) <> Неопределено Тогда Продолжить; КонецЕсли; СписокРеквизитов.Добавить(ЗначениеРеквизита); КонецЦикла; КонецЦикла; КонецЦикла; Если СписокРеквизитов.Количество() > 0 Тогда ВыводимыеОбъекты = ЗапросПоРеквизитамОбъектов(СписокРеквизитов).Выполнить().Выгрузить(); ВыводимыеОбъекты.Сортировать("Дата"); Для каждого ВыводимыйОбъект Из ВыводимыеОбъекты Цикл Если ИндексСвязейОбъектов[ТекущийОбъект] = ВыводимыйОбъект.Ссылка Тогда Продолжить; КонецЕсли; ИндексСвязейОбъектов[ТекущийОбъект] = ВыводимыйОбъект.Ссылка; НоваяСтрока = ДобавитьСтрокуВДерево(ДеревоРодитель, ВыводимыйОбъект, ВыведенныеОбъекты); Если НоваяСтрока <> Неопределено И Не ДобавляемыйОбъектИмеетсяСредиРодителей(ДеревоРодитель, ВыводимыйОбъект.Ссылка) Тогда a // @skip-check query-in-loop - Рекурсивный алгоритм обработки дерева. ВывестиРодительскиеОбъекты(ВыводимыйОбъект.Ссылка, НоваяСтрока, ВыведенныеОбъекты, СлужебныеОбъекты, ИндексСвязейОбъектов); ИначеЕсли СлужебныеОбъекты[ВыводимыйОбъект.Ссылка] = Неопределено Тогда СлужебныеОбъекты[ВыводимыйОбъект.Ссылка] = Истина; // @skip-check query-in-loop - Рекурсивный алгоритм обработки дерева. ВывестиРодительскиеОбъекты(ВыводимыйОбъект.Ссылка, ДеревоРодитель, ВыведенныеОбъекты, СлужебныеОбъекты, ИндексСвязейОбъектов); КонецЕсли; КонецЦикла; КонецЕсли; КонецПроцедуры
4. Добавляем в расширение Документы.ОрдерНаОтражениеНедостачТоваров.МодульМенеджера.ДобавитьКомандыОтчетов
&После("ДобавитьКомандыОтчетов") Процедура пл_ДобавитьКомандыОтчетов(КомандыОтчетов, Параметры) ИнтеграцияИСПереопределяемый.ДобавитьКомандуСтруктураПодчиненности(КомандыОтчетов); //Всеволод КонецПроцедуры
Более универсальное решение с добавлением своего настраиваемого КритерияОтбора:
https://infostart.ru/1c/articles/1653703/