Проект

Общее

Профиль

Структура подчиненности (связанные объекты)

Добавление Структуры подчиненности (связанные документы) в расширение

При добавлении нового реквизита в объект (документ, справочник) может возникнуть задача вывода связанных документов.
Если добавлять в расширение КритерииОтбора.СвязанныеДокументы, тогда в расширение будут добавлены все участвующие объекты.
Можно решить иначе - добавлением кода:

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/