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

05.05.20

Разработка - Универсальные функции

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

Скачать файл

ВНИМАНИЕ: Файлы из Базы знаний - это исходный код разработки. Это примеры решения задач, шаблоны, заготовки, "строительные материалы" для учетной системы. Файлы ориентированы на специалистов 1С, которые могут разобраться в коде и оптимизировать программу для запуска в базе данных. Гарантии работоспособности нет. Возврата нет. Технической поддержки нет.

Наименование По подписке [?] Купить один файл
Универсальная функция получения дополнительных реквизитов и пример отображения на форме:
.epf 10,74Kb
17
17 Скачать (2 SM) Купить за 2 150 руб.

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

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

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

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

  • получим список дополнительных реквизитов, которые есть у переданных объектов. Так как для каждого вида метаданных (справочников, документов) есть свой набор дополнительных реквизитов, передаваемые объекты должны быть однородны (одного вида, т.е. только ссылки вида «Номенклатура» или «Контрагенты»). Для этого создадим функцию ПолучитьМассивДополнительныхРеквизитов(ПолноеИмяМетаданных)
  • Далее сформируем текст запроса, в котором в цикле будем делать левое соединение с таблицей объекта (справочника, документа и т.д.). На выходе получим искомые данные. Их и выгрузим в таблицу

 

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

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

КонецЕсли; 

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

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

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

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

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

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

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

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

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

И результат

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

 

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

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

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

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

        КонецЕсли; 

    КонецЕсли; 

КонецЕсли; 

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

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

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

        КонецЕсли; 

    КонецЦикла;     

КонецЕсли; 

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

 

Таким образом можно выбрать любую ссылку с дополнительными реквизитами или любой документ/справочник/ПВХ со ссылками, у которых есть ТЧ с дополнительными реквизитами.

Вот собственно и все, обработка - во вложении. Кому нужен функционал - качайте. Собственно функция - копируйте, если было полезно - ставьте лайки :)

PS Протестировано на УТ11.4.10.94, 1С:Предприятие 8.3.15.1830. Но довольно универсально для всех конфигураций с БСП самых старых версий.

Обработка универсальная дополнительные реквизиты

См. также

Универсальные функции Программист Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

Благодаря этим пяти строчкам можно больше не заморачиваться с загрузкой из внешних файлов. Пользуюсь везде, всегда и постоянно.

21.05.2024    20231    dimanich70    81    

145

Универсальные функции Программист Платформа 1С v8.3 Конфигурации 1cv8 Абонемент ($m)

Задача: вставить картинку из буфера обмена на форму средствами платформы 1С.

1 стартмани

18.03.2024    4100    3    John_d    11    

57

Универсальные функции Программист Стажер Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

Пришлось помучиться с GUID-ами немного, решил поделиться опытом, мало ли кому пригодится.

12.02.2024    18194    atdonya    24    

57

Универсальные функции Программист Платформа 1С v8.3 Бесплатно (free)

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

30.11.2023    5508    ke.92@mail.ru    16    

65

WEB-интеграция Универсальные функции Механизмы платформы 1С Программист Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

При работе с интеграциями рано или поздно придется столкнуться с получением JSON файлов. И, конечно же, жизнь заставит проверять файлы перед тем, как записывать данные в БД.

28.08.2023    14774    YA_418728146    7    

166

Пакетная печать Печатные формы Адаптация типовых решений Универсальные функции Платформа 1С v8.3 1С:ERP Управление предприятием 2 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х Россия Абонемент ($m)

Расширение для программ 1С:Управление торговлей, 1С:Комплексная автоматизация, 1С:ERP, которое позволяет распечатывать печатные формы для непроведенных документов. Можно настроить, каким пользователям, какие конкретные формы документов разрешено печатать без проведения документа.

2 стартмани

22.08.2023    3592    57    progmaster    8    

4

Инструментарий разработчика Универсальные функции Платформа 1С v8.3 Конфигурации 1cv8 1С:Розница 2 1С:ERP Управление предприятием 2 1С:Бухгалтерия 3.0 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х 1С:Зарплата и Управление Персоналом 3.x Абонемент ($m)

Копирует в буфер значения из списков, из ячеек отчетов, таблиц, настроек списков, других отборов и вставляет в выбранную настройку отбора. Работает с Объект не найден. Работает как в одной так и между разными базами 1С. Использует комбинации [Alt+C] Копировать список, [Alt+V] Вставить список. Также для копирования данных используется стандартная [Ctrl+C] (например из открытого xls, mxl, doc и т.п. файла скопировать список наименований)

1 стартмани

13.10.2022    18497    171    sapervodichka    112    

135
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. Ovrfox 14 06.05.20 12:36 Сейчас в теме
В принципе идея полезная, но не понятно, зачем для каждого реквизита делать отдельное соединение
Почему просто не сформировать запрос с одним соединением?
И текста меньше и итог тот же, еще и время как минимум на парсинг сэкономится
2. Ovrfox 14 06.05.20 12:47 Сейчас в теме
(1) Я понял - много соединений, чтобы преобразовать результат сразу в шахматку.
Но если сразу преобразовывать, а не через СКД, то пустые , незаполненные ни разу свойства тоже выведуться в виде пустых столбцов
ИМХО преобразовать в шахматку после выборки будет правильнее
3. papche 618 06.05.20 15:29 Сейчас в теме
(1)Одним соединением?! Это как?
Можете пример выдать, чтобы было понятно?
4. Cmapnep 19 11.05.20 23:07 Сейчас в теме
(3) Соглашусь с коллегой - по соединению на свойство это уж слишком не оптимально
Одним соединением это как-то так:
Запрос.Текст = СтрЗаменить(Запрос.Текст,
" &ТекстПолученияЗначенияСвойства КАК ТекстПолученияЗначенияСвойства,",
" МАКСИМУМ(ВЫБОР КОГДА ХДР.Свойство = &Свойство_" + ВыборкаСвойств.Имя + " ТОГДА ХДР.Значение ИНАЧЕ " + ПустоеЗначениеСвойства + " КОНЕЦ) КАК Значение_" + ВыборкаСвойств.Имя +
"," + Символы.ВК +
" &ТекстПолученияЗначенияСвойства КАК ТекстПолученияЗначенияСвойства,");

ХДР это ХарактеристикиНоменклатуры.ДополнительныеРеквизиты
ПустоеЗначениеСвойства нужно прежде всего для корректного заполнения типа БУЛЕВО в случае отсутствия значения в ТЧ
5. papche 618 14.05.20 11:09 Сейчас в теме
(4)
ТекстПолученияЗначенияСвойства

Я не понимаю данного примера. Можете готовый запрос привести? Можно не универсальный, например на 2-х доп реквизитах? И пример выборки на 2-х элементах?
У меня что-то предполагаемый результат совсем не вяжется с поставленной задачей...
6. Cmapnep 19 15.05.20 00:23 Сейчас в теме
(5) Ну смотрите, результирующий запрос может быть таким:
ВЫБРАТЬ
ХДР.Ссылка КАК Характеристика,
МАКСИМУМ(ВЫБОР КОГДА ХДР.Свойство.Имя = &ИмяСвойства1 ТОГДА ХДР.Значение ИНАЧЕ НЕОПРЕДЕЛЕНО КОНЕЦ) КАК ЗначениеСвойства1,
МАКСИМУМ(ВЫБОР КОГДА ХДР.Свойство.Имя = &ИмяСвойства2 ТОГДА ХДР.Значение ИНАЧЕ НЕОПРЕДЕЛЕНО КОНЕЦ) КАК ЗначениеСвойства2
ИЗ
Справочник.ХарактеристикиНоменклатуры.ДополнительныеРеквизиты КАК ХДР
ГДЕ
ХДР.Ссылка = &Ссылка
СГРУППИРОВАТЬ ПО
ХДР.Ссылка

Чтобы получить значения всех свойств по их именам можно использовать такой запрос:
ВЫБРАТЬ
&ТекстПолученияЗначенияСвойства КАК ТекстПолученияЗначенияСвойства,
ХДР.Ссылка КАК Характеристика
ИЗ
Справочник.ХарактеристикиНоменклатуры.ДополнительныеРеквизиты КАК ХДР
ГДЕ
ХДР.Ссылка = &Ссылка

СГРУППИРОВАТЬ ПО
ХДР.Ссылка

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

Надеюсь в этот раз понятно расписал
7. papche 618 15.05.20 11:20 Сейчас в теме
(6) Согласен, вполне рабочий вариант. И да, работать будет быстрее
8. papche 618 20.05.21 11:04 Сейчас в теме
(7)Кстати, протестировал на досуге оба метода - и удивительно - описанный в статье оказался способ немного быстрее
Оставьте свое сообщение