Универсальная функция получения дополнительных реквизитов

Решаем следующую задачу. Например, в справочнике «Номенклатура» — 10 дополнительных реквизитов: Материал, Наименование на английском, Наименование на французском и т.д., и 20 дополнительных реквизитов в справочнике «Характеристики номенклатуры». Необходимо вывести все характеристики по списку, так называемую «Спецификацию» по «Заказу клиента» или «Заказу поставщика»

Если задачу решать классически — пишем запрос, делаем левое соединение к нашим справочникам и получаем нужную нам выборку. Довольно скучная, муторная и повторяющаяся задача.

Поэтому, решим эту задачу другим путем:

  1. Разработаем универсальную функцию для получения таблицы значений для всех ссылок (строки) и со всеми реквизитами (в колонках). ПолучитьТаблицуЗначенийДополнительныхРеквизитов(МассивСсылок, МассивИменРеквизитов = Неопределено).
    Массив имен будем передавать, если нужен лишь определенный список реквизитов
  2. Готовую таблицу значений будем выводить на печать или передавать в запрос, если далее это будет нужно

Если с п2 — никакой проблемы нет, то п1 — задача вполне интересная. Делать будем так:

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

    МассивИменРеквизитов = ПолучитьМассивДополнительныхРеквизитов(
ПолноеИмяМетаданных);     

КонецЕсли; 

Запрос = Новый Запрос;
Текст = "ВЫБРАТЬ
        |   Таблица.Ссылка КАК Ссылка
        |ПОМЕСТИТЬ Таблица
        |ИЗ
        |   ИмяВидаОбъектаМетаданных.ИмяОбъектаМетаданных КАК Таблица
        |ГДЕ
        |   Таблица.Ссылка В(&МассивСсылок);
        |";

Запрос.УстановитьПараметр("МассивСсылок", МассивСсылок);
Текст = Текст + "ВЫБРАТЬ
    |   Таблица.Ссылка КАК Ссылка";
Текст = СтрЗаменить(Текст, "ИмяВидаОбъектаМетаданных.ИмяОбъектаМетаданных", 
ПолноеИмяМетаданных); 
ТекстСоединение = "";
Для каждого ИмяРеквизита Из МассивИменРеквизитов Цикл
    Текст = Текст + ",
                    |   НоменклатураДополнительныеРеквизиты.Значение 
 КАК ЗначениеСвойства";
    ТекстСоединение = ТекстСоединение + "
                    |       ЛЕВОЕ СОЕДИНЕНИЕ
 ИмяВидаОбъектаМетаданных.ИмяОбъектаМетаданных.ДополнительныеРеквизиты
 КАК НоменклатураДополнительныеРеквизиты
                    |       ПО Таблица.Ссылка =
 НоменклатураДополнительныеРеквизиты.Ссылка
                    |           И
 (НоменклатураДополнительныеРеквизиты.Свойство.Имя
 = &ИмяРеквизита)";

    Текст = СтрЗаменить(Текст, "ЗначениеСвойства", ИмяРеквизита); 
    Текст = СтрЗаменить(Текст, "НоменклатураДополнительныеРеквизиты", 
"ДополнительныеРеквизиты_" + ИмяРеквизита); 

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

В результате, получаем очень компактный код и универсальные функции, в которые легко передавать параметры. К примеру, так будет выглядеть вызов печати всех реквизитов одного элемента справочника Номенклатура.

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

И вот результат

А вот вызов печати всех товаров из табличной части Товары выбранного документа, причем любого вида:

МассивСсылок = ПолучитьМассивСсылокПоТЧ(Документ, "Товары", "Номенклатура");
Таблица = ПолучитьТабличныйДокументЗначенийДополнительныхРеквизитов(МассивСсылок);
Таблица.Показать();

И результат

Для формирования ссылок с товарами пришлось добавить универсальную функцию ПолучитьМассивСсылокПоТЧ(Документ, ИмяТЧ, ИмяРеквизита), куда передаем ссылку на документ, имя табличной части «Товары» и имя реквизита «Номенклатура»

&НаСервереБезКонтекста
Функция ПолучитьМассивСсылокПоТЧ(Документ, ИмяТЧ, ИмяРеквизита)
МассивСсылок = Новый Массив();
ЕстьРеквизит = Ложь;

МетаданныеДок = Метаданные.НайтиПоТипу(ТипЗнч(Документ));
Если не МетаданныеДок = Неопределено Тогда

    ТЧТовары = МетаданныеДок.ТабличныеЧасти.Найти(ИмяТЧ);
    Если не ТЧТовары = Неопределено Тогда
        Если не ТЧТовары.Реквизиты.Найти(ИмяРеквизита) = Неопределено Тогда

            ЕстьРеквизит = Истина;  

        КонецЕсли; 

    КонецЕсли; 

КонецЕсли; 

Если ЕстьРеквизит Тогда

    Для каждого Строка Из Документ[ИмяТЧ] Цикл
        Если МассивСсылок.Найти(Строка[ИмяРеквизита]) = Неопределено Тогда

            МассивСсылок.Добавить(Строка[ИмяРеквизита]);    

        КонецЕсли; 

    КонецЦикла;     

КонецЕсли; 

Возврат МассивСсылок;
КонецФункции

И вот как выглядит универсальная обработка, которая опирается на данный функционал. В форме выбираем что смотреть — ссылку или табличную часть (Тип ссылки), выбираем ссылку, имя табличной части, имя реквизита — и готово!

Ну все, саму обработку выкладываю на Инфостарт
https://infostart.ru/public/download.php?file=1232165&pub=1232160

Вам также может понравиться

About the Author: Павел Пчелинцев