Привет, подскажите, пожалуйста, как Дополнительные реквизиты в запросе указывать, если их нужно 2шт вытащить для печатной формы?
Делаю во внешней обработке для УТ 11, никак не выходят доп реквизиты в форме печатной
сделала в запросе 2 временные таблицы с последующим объединением: с обычными реквизитами, и с доп реквизитами, мне кажется в них проблема....
мой шедевер:
подскажите что не так 😭
Функция СформироватьПечатнуюФормуТест(МассивОбъектов)
ДопРеквизитТЗ = ПланыВидовХарактеристик.ДополнительныеРеквизитыИСведения.НайтиПоНаименованию("Техническое задание");
ДопРеквизитКод = ПланыВидовХарактеристик.ДополнительныеРеквизитыИСведения.НайтиПоНаименованию("Код позиции КТРУ");
ТабДок = Новый ТабличныйДокумент;
Макет = ПолучитьМакет("ПФ_MXL_ТехническоеЗадание");
Область = Макет.ПолучитьОбласть("Шапка");
ТабДок.Вывести(Область);
Область = Макет.ПолучитьОбласть("ШапкаТаблицы");
ТабДок.Вывести(Область);
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| КоммерческоеПредложениеКлиентуТовары.НомерСтроки КАК ПорядковыйНомер,
| КоммерческоеПредложениеКлиентуТовары.Номенклатура.Наименование КАК НаименованиеНоменклатуры,
| КоммерческоеПредложениеКлиентуТовары.Количество КАК Количество,
| КоммерческоеПредложениеКлиентуТовары.Номенклатура.ЕдиницаИзмерения КАК ЕдИзм,
| КоммерческоеПредложениеКлиентуТовары.Ссылка КАК Ссылка
|ПОМЕСТИТЬ ВТ_ТЧНоменклатуры
|ИЗ
| Документ.КоммерческоеПредложениеКлиенту.Товары КАК КоммерческоеПредложениеКлиентуТовары
|ГДЕ
| КоммерческоеПредложениеКлиентуТовары.Ссылка В(&МассивОбъектов)
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| НоменклатураДополнительныеРеквизиты.Ссылка КАК Ссылка,
| НоменклатураДополнительныеРеквизиты.Свойство КАК Свойство,
| НоменклатураДополнительныеРеквизиты.Значение КАК Значение
|ПОМЕСТИТЬ ВТ_ДопРекв
|ИЗ
| Справочник.Номенклатура.ДополнительныеРеквизиты КАК НоменклатураДополнительныеРеквизиты
|ГДЕ
| НоменклатураДополнительныеРеквизиты.Свойство = &Свойство
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| ВТ_ТЧНоменклатуры.ПорядковыйНомер КАК ПорядковыйНомер,
| ВТ_ТЧНоменклатуры.НаименованиеНоменклатуры КАК НаименованиеНоменклатуры,
| ВТ_ТЧНоменклатуры.Количество КАК Количество,
| ВТ_ТЧНоменклатуры.ЕдИзм КАК ЕдИзм,
| ВТ_ТЧНоменклатуры.Ссылка КАК Ссылка,
| ВТ_ДопРекв.Значение КАК ОписаниеНоменклатуры,
| ВТ_ДопРекв.Значение КАК КодПозиции
|ИЗ
| ВТ_ТЧНоменклатуры КАК ВТ_ТЧНоменклатуры
| ЛЕВОЕ СОЕДИНЕНИЕ ВТ_ДопРекв КАК ВТ_ДопРекв
| ПО ВТ_ТЧНоменклатуры.Ссылка = ВТ_ДопРекв.Ссылка";
Запрос.УстановитьПараметр("Свойство", ДопРеквизитТЗ);
Запрос.УстановитьПараметр("Свойство", ДопРеквизитКод);
Запрос.УстановитьПараметр("МассивОбъектов", МассивОбъектов);
Строка = Макет.ПолучитьОбласть("СтрокаТаблицы");
РезультатЗапроса = Запрос.Выполнить().Выгрузить();
Для каждого Ссылка Из МассивОбъектов Цикл
Отбор = Новый Структура;
Отбор.Вставить("Ссылка", Ссылка);
Выборка = РезультатЗапроса.НайтиСтроки(Отбор);
Для каждого СтрокаТЧ Из Выборка Цикл
ЗаполнитьЗначенияСвойств(Строка.Параметры, СтрокаТЧ);
ТабДок.Вывести(Строка);
КонецЦикла;
КонецЦикла;
ТабДок.АвтоМасштаб = Истина;
ТабДок.ОтображатьСетку = Ложь;
ТабДок.ОтображатьЗаголовки = Ложь;
Возврат ТабДок;
"ВЫБРАТЬ
| КоммерческоеПредложениеКлиентуТовары.НомерСтроки КАК ПорядковыйНомер,
| КоммерческоеПредложениеКлиентуТовары.Номенклатура.Наименование КАК НаименованиеНоменклатуры,
| ЕСТЬNULL(ТехническиеЗадания.Значение, """") Как ТехническоеЗадание,
| ЕСТЬNULL(КодПозицийКТРУ.Значение, """") Как КодПозицииКТРУ,
| КоммерческоеПредложениеКлиентуТовары.Количество КАК Количество,
| КоммерческоеПредложениеКлиентуТовары.Номенклатура.ЕдиницаИзмерения КАК ЕдИзм,
| КоммерческоеПредложениеКлиентуТовары.Ссылка КАК Ссылка
|ПОМЕСТИТЬ ВТ_ТЧНоменклатуры
|ИЗ
| Документ.КоммерческоеПредложениеКлиенту.Товары КАК КоммерческоеПредложениеКлиентуТовары
| ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Номенклатура.ДополнительныеРеквизиты КАК ТехническиеЗадания
| ПО КоммерческоеПредложениеКлиентуТовары.Номенклатура = ТехническиеЗадания.Ссылка
| И ТехническиеЗадания.Свойство.Наименование = ""Техническое задание""
| ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Номенклатура.ДополнительныеРеквизиты КАК КодПозицийКТРУ
| ПО КоммерческоеПредложениеКлиентуТовары.Номенклатура = КодПозицийКТРУ.Ссылка
| И ТехническиеЗадания.Свойство.Наименование = ""Код позиции КТРУ""
|ГДЕ
| КоммерческоеПредложениеКлиентуТовары.Ссылка В(&МассивОбъектов)"
(7)как сказать, придется избавится от дублей записей, либо дополнительно искать нужное значение для вывода, что исходя из общего уровня ТС в качестве программиста 1С(нисколько не в упрек ТС) - решение для ТС может оказаться сильно сложнее предложенного работающего решения самим ТС.
(8) Каких дублей?
Сначала таблицу со свойствами разворачиваете из колонок в строки. И один раз цепляете.
В 1С нет PIVOT, поэтому разворачивать таблицы можно через объединение и группировку.
Когда собираются свойства, необходимо добавить ещё фильтр на номенклатуру из документов, которые в МассивОбъектов.
Номенклатуры может 50 000, а в документах только сотня другая. Зачем свойства для 50 000 собирать и потом ещё это всё присоединять?
Сначала таблицу со свойствами разворачиваете из колонок в строки. И один раз цепляете.
В 1С нет PIVOT, поэтому разворачивать таблицы можно через объединение и группировку.
Вы уверены, что ТС это сможет сделать? че-т я пока не уверен, что сходу смогу выполнить вот это все, потому что пока не совсем понимаю, как это "PIVOT через объединение и группировку"
(12) Если кратко суть, то развернуть таблицу свойств можно так:
IIF нет в 1С, но написал что бы короче было. Писать придется "выбор когда тогда иначе конец"
Выбрать
т.Номенклатура
,MAX(IIF(т.Свойство = Свойство1, тЗначение, NULL)) КАК ЗначениеСвойство1
,MAX(IIF(т.Свойство = Свойство2, тЗначение, NULL)) КАК ЗначениеСвойство2
,MAX(IIF(т.Свойство = Свойство3, тЗначение, NULL)) КАК ЗначениеСвойство3
...
,MAX(IIF(т.Свойство = СвойствоN, тЗначение, NULL)) КАК ЗначениеСвойствоN
ИЗ
Справочник.Номенклатура.ДополнительныеРеквизиты как т
ГДЕ
т.Свойство в (Свойство1, Свойство2, Свойство3, ... , СвойствоN)
И т.Номенклатура в (Выбрать Различные т1.Номенлатура
ИЗ Документ.КоммерческоеПредложениеКлиенту.Товары как т1
где т1.Ссылка В(&МассивОбъектов))
GROUP BY
т.Номенклатура
(15)А если нужны все 150?
Т.е. по вашему, 15 параметров = 15 неявных запросов к БД + итоговый запрос - это шибко лучше одного запроса пусть и с левыми соединениями? Хорошо, так и запишем.
Если понадобится большее количество доп. значений, решение должно быть явно другим, без "PIVOT через объединение и группировку".
Даже если понадобилось бы 15 свойств, то лично я решил бы задачу через пакет запросов, один из которых содержал бы все значения доп свойств по номенклатуре из документов, выгрузил бы его в ТЗ и тупо искал бы в ней значения свойств номенклатуры для вывода в ТабДок
(16) Все сделает запрос. Код короче.
Если понадобится добавить ещё одно свойство в печатную форму, то добавление одной строчки в запрос и у условие свойства, ещё одно значение, плюс строчка в установку параметра.
Такой код сопровождать проще.
15 соединений отработает медленнее чем одно. Это очевидно.
(17) У всего есть свои плюсы и минусы.
Использование апи БСП позволяет не задумываться о том, где хранятся значения доп. реквизитов, если структура данных вдруг изменится.
В чем проблема поиска в цикле? Индексируем таблицу по полям поиска и будет все быстро.
Для понимания, я не говорю, что это лучший вариант.
Это просто еще один вариант реализации задачи.
15 соединений отработает медленнее чем одно. Это очевидно.
Так никто и не предлагает делать 15 соединений, если до сих пор не понятно.
можно вообще без соединений как бы, но тогда нужна постобработка: поиск значения в ТЗ
можно с одним соединением, но нужна постобработка: избавление от дублей записей в полученной запросом ТЗ.
Смотрим требования. По сути выгрузка из результата запроса в ТЗ это ещё одна копия тех же самых данных.
(21) В вашем случае, тоже будет 150 проверок на свойство. И их придется по хорошему задавать в параметры, а не на наименование зашиваться. Завтра наименование поменяется и запрос ваш не работает. Есть ссылка, её и надо использовать.
И левых соединений у вас будет 150 штук. Сервер умрёт от счастья, которое на него свалилось.
(22)пффф....можно завязаться на неизменяемые данные для свойства, в БСП специально для этого выделили ажна целый реквизит и да, нужные значения можно передать с помощью ажна одного параметра.
Еще раз: никто не будет в здравом уме делать 150 соединений, даже 15 не будут делать, потому что подход к решению должен быть кардинально другим.
Согласно требованиям: докажите, что выгрузка в ТЗ значений свойств номенклатуры была без необходимости.
Согласно требованиям: докажите, что выгрузка в ТЗ значений свойств номенклатуры была без необходимости.
Поверь, никто ничего не доказывает. Увидели выгрузку результата запроса в ТЗ и потом обход результата - минус балл.
Так и 15-лет назад было. Те кто принимают платформу типовые конфигурации и не открывают. У них свои требования и они по сути не меняются.
(27) Требования абсолютно справедливые.
Перелевание из ТЗ в ТЗ это необоснованное использование лишней оперативной памяти памяти.
Поиск по ТЗ в цикле, это запрос в цикле. Это необоснованная загрузка сервера.
По времени работы это медленнее.
(31)да говорю ж: можно вообще без соединений, можно с одним соединением, но оба варианта нужно постобработать и оба требует выгрузки в ТЗ
Без этого будет "PIVOT через объединение и группировку" и N соединений, увы и ах.
(34)т.е. ради того, чтобы не выгружать в ТЗ мы будем городить стопицот запросов к БД, чтобы получить список нужных нам свойств и передавать каждый в качестве параметра итогового запроса - просто замечательная альтернатива, как по-мне
(36)Еще раз: специально, чтобы отвязаться от наименования, 1С ввела дополнительный реквизит и заполняет его значением, содержащим УИ, можете искать по его значению.
(40) В УТ11.4 это реквизит "Имя", при записи проверяется уникальность значения во всем справочнике, само значение формируется по Наименование(без пробелов) + "_" + новый УИ(не ссылки).
Попроще сформулированно, но все равно не работает, через таблицу свойств не очень понимаю как в одну таблицу все свести...
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| КоммерческоеПредложениеКлиентуТовары.НомерСтроки КАК ПорядковыйНомер,
| КоммерческоеПредложениеКлиентуТовары.Номенклатура.Наименование КАК НаименованиеНоменклатуры,
| КоммерческоеПредложениеКлиентуТовары.Количество КАК Количество,
| КоммерческоеПредложениеКлиентуТовары.Номенклатура.ЕдиницаИзмерения КАК ЕдИзм,
| КоммерческоеПредложениеКлиентуТовары.Ссылка КАК Ссылка
|ИЗ
| Документ.КоммерческоеПредложениеКлиенту.Товары КАК КоммерческоеПредложениеКлиентуТовары,
| Справочник.Номенклатура.ДополнительныеРеквизиты КАК НоменклатураДополнительныеРеквизиты
|ГДЕ
| КоммерческоеПредложениеКлиентуТовары.Ссылка В(&МассивОбъектов)";
|ИЗ
| Документ.КоммерческоеПредложениеКлиенту.Товары КАК КоммерческоеПредложениеКлиентуТовары,
| Справочник.Номенклатура.ДополнительныеРеквизиты КАК НоменклатураДополнительныеРеквизиты
Так точно делать не стОит от слова никогда.
Вариант решения, наиболее подходящее под ваш алгоритм вывода приведен в (2)
(43) убрано, не заметила
я (2) не совсем понимаю как вписать это решение, с ним код все равно не заработал
нет ли варианта связаться и может платно посмотрите как решить ошибки внешней обработки? на мой синтаксис в данный момент без слез не взглянуть, но я уже не знаю как с этой задачей справиться
Функция СформироватьПечатнуюФормуТест(МассивОбъектов)
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| КоммерческоеПредложениеКлиентуТовары.НомерСтроки КАК ПорядковыйНомер,
| КоммерческоеПредложениеКлиентуТовары.Номенклатура.Наименование КАК НаименованиеНоменклатуры,
| ЕСТЬNULL(ТехническиеЗадания.Значение, """") Как ТехническоеЗадание,
| ЕСТЬNULL(КодПозицийКТРУ.Значение, """") Как КодПозицииКТРУ,
| КоммерческоеПредложениеКлиентуТовары.Количество КАК Количество,
| КоммерческоеПредложениеКлиентуТовары.Номенклатура.ЕдиницаИзмерения КАК ЕдИзм,
| КоммерческоеПредложениеКлиентуТовары.Ссылка КАК Ссылка
|ПОМЕСТИТЬ ВТ_ТЧНоменклатуры
|ИЗ
| Документ.КоммерческоеПредложениеКлиенту.Товары КАК КоммерческоеПредложениеКлиентуТовары
| ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Номенклатура.ДополнительныеРеквизиты КАК ТехническиеЗадания
| ПО КоммерческоеПредложениеКлиентуТовары.Номенклатура = ТехническиеЗадания.Ссылка
| И ТехническиеЗадания.Свойство.Наименование = ""Техническое задание""
| ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Номенклатура.ДополнительныеРеквизиты КАК КодПозицийКТРУ
| ПО КоммерческоеПредложениеКлиентуТовары.Номенклатура = КодПозицийКТРУ.Ссылка
| И ТехническиеЗадания.Свойство.Наименование = ""Код позиции КТРУ""
|ГДЕ
| КоммерческоеПредложениеКлиентуТовары.Ссылка В(&МассивОбъектов)";
Запрос.УстановитьПараметр("МассивОбъектов", МассивОбъектов);
ТабДок = Новый ТабличныйДокумент;
Макет = ПолучитьМакет("ПФ_MXL_ТехническоеЗадание");
Область = Макет.ПолучитьОбласть("Шапка");
ТабДок.Вывести(Область);
Область = Макет.ПолучитьОбласть("ШапкаТаблицы");
ТабДок.Вывести(Область);
Результат = Запрос.Выполнить();
Если Результат.Пустой() Тогда
Возврат ТабДок;
КонецЕсли
ТаблицаДанных = Результат.Выгрузить();
СписокДокументов = ТаблицаДанных.Скопировать(,"Ссылка");
СписокДокументов.Свернуть("Ссылка");
СписокДокументов = СписокДокументов.ВыгрузитьКолонку("Ссылка");
Для каждого Документ Из СписокДокументов Цикл
Отбор = Новый Структура("Ссылка", Документ);
ДокументТЧ = РезультатЗапроса.НайтиСтроки(Отбор);
Для каждого СтрокаТЧ Из ДокументТЧ Цикл
Строка = Макет.ПолучитьОбласть("СтрокаТаблицы");
ЗаполнитьЗначенияСвойств(Строка.Параметры, СтрокаТЧ);
ТабДок.Вывести(Строка);
КонецЦикла;
КонецЦикла;
ТабДок.АвтоМасштаб = Истина;
ТабДок.ОтображатьСетку = Ложь;
ТабДок.ОтображатьЗаголовки = Ложь;
Возврат ТабДок;
КонецФункции
(46) По умолчанию 0 прописал, но надо поставить что надо. Я не знаю что это у вас такое.
Писал на коленке, поэтому синтаксис и запятые с кавычками проверяйте сами.
...
Запрос.УстановитьПараметр("Свойство1", ДопРеквизитТЗ);
Запрос.УстановитьПараметр("Свойство2", ДопРеквизитКод);
...
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| т.Ссылка КАК Ссылка,
| ЕстьNULL(Максимум(выбор когда т.Свойство = &Свойство1 тогда т.Значение иначе NULL конец), 0) КАК ЗначениеСвойство1,
| ЕстьNULL(Максимум(выбор когда т.Свойство = &Свойство2 тогда т.Значение иначе NULL конец), 0) КАК ЗначениеСвойство2
|ПОМЕСТИТЬ ВТ_ДопРекв
|ИЗ
| Справочник.Номенклатура.ДополнительныеРеквизиты КАК т
|ГДЕ
| т.Свойство в (&Свойство1, &Свойство2) // можно так т.Свойство = &Свойство1 ИЛИ т.Свойство = Свойство2
| И т.Ссылка в (выбрать различные т1.Номенклатура ИЗ ВТ_ТЧНоменклатуры как т1)
|СГРУППИРОВАТЬ ПО
| т.Ссылка КАК Ссылка
|;
Показать
Далее эту таблицу цепляйте к своей таблице ВТ_ТЧНоменклатуры.
Вместо вот этого:
РезультатЗапроса = Запрос.Выполнить().Выгрузить();
Для каждого Ссылка Из МассивОбъектов Цикл
Отбор = Новый Структура;
Отбор.Вставить("Ссылка", Ссылка);
Выборка = РезультатЗапроса.НайтиСтроки(Отбор);
Для каждого СтрокаТЧ Из Выборка Цикл
Показать
Добавьте итог по ссылке в итоговый запрос и сделайте одну выборку по итогу, а вторую по первой выборке. Что-то типа такого.
ВыборкаИтог = Запрос.Запрос.Выполнить().Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам);
Пока ВыборкаИтог.Следующий() Цикл
Выборка = ВыборкаИтог.Выбрать();
Пока Выборка.Следующий() Цикл
КонецЦикла;
КонецЦикла;