Две схемы СКД в одном отчете

1. user1030103 31.01.19 10:51 Сейчас в теме
Добрый день!

Помогите, пожалуйста, подскажите, что делаю не так?
Необходимо создать отчет, который бы выводил данные по всей имеющейся в базе номенклатуре или только по проданной (той, что встречается в реализациях) за определенный период.

Решила использовать для решения задачи два разных запроса. Отчет делаю в СКД, использую две схемы компоновки: одна для первого запроса, другая для второго.

Запрос для вывода проданной номенклатуры (этот макет назвала "ПроданнаяНоменклатура"):
ВЫБРАТЬ РАЗЛИЧНЫЕ
	Vetis_НаименованияПродукции.Предприятие.Ссылка КАК Предприятие,
	Vetis_НаименованияПродукции.Предприятие.guid КАК ГУИДПредприятия,
	Vetis_НаименованияПродукции.Ссылка КАК НоменклатураМеркурия,
	Vetis_НаименованияПродукции.GUID КАК ГУИДНоменклатуры,
	Vetis_НаименованияПродукции.ХСПроизводитель КАК ХозяйственныйСубъект,
	Vetis_НаименованияПродукции.ХСПроизводитель.guid КАК ГУИДХозяйственногоСубъекта,
	Vetis_НаименованияПродукции.ВидПродукции,
	Vetis_НаименованияПродукции.ВидПродукции.Владелец КАК Продукт,
	Vetis_МатрицаСоответствияПродукцииПроизводителя.Номенклатура.БазоваяЕдиницаИзмерения КАК ЕдиницаИзмерения,
	Vetis_МатрицаСоответствияПродукцииПроизводителя.Номенклатура.Сертификат.ТНВЭД КАК ТНВЭД,
	Vetis_НаименованияПродукции.ВидПродукции.Владелец.productType КАК ТипПродукции,
	Vetis_НоменклатураКонтрагентов.НоменклатураМеркурий.Наименование КАК НоменклатураКонтрагента,
	Vetis_НоменклатураКонтрагентов.НоменклатураМеркурий.Код КАК КодНоменклатурыКонтрагента,
	РеализацияТоваровУслугТовары.Номенклатура КАК Номенклатура
ИЗ
	Документ.РеализацияТоваровУслуг.Товары КАК РеализацияТоваровУслугТовары
		ЛЕВОЕ СОЕДИНЕНИЕ Документ.РеализацияТоваровУслуг КАК РеализацияТоваровУслуг
		ПО РеализацияТоваровУслугТовары.Ссылка = РеализацияТоваровУслуг.Ссылка
		ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.Vetis_МатрицаСоответствияПродукцииПроизводителя КАК Vetis_МатрицаСоответствияПродукцииПроизводителя
			ВНУТРЕННЕЕ СОЕДИНЕНИЕ Справочник.Vetis_НаименованияПродукции КАК Vetis_НаименованияПродукции
			ПО Vetis_МатрицаСоответствияПродукцииПроизводителя.НаименованиеМеркурий = Vetis_НаименованияПродукции.Ссылка
		ПО РеализацияТоваровУслугТовары.Номенклатура.Наименование = Vetis_МатрицаСоответствияПродукцииПроизводителя.Номенклатура.Наименование
		ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрСведений.Vetis_НоменклатураКонтрагентов КАК Vetis_НоменклатураКонтрагентов
		ПО РеализацияТоваровУслугТовары.Номенклатура.Наименование = Vetis_НоменклатураКонтрагентов.НоменклатураМеркурий.Наименование
			И (РеализацияТоваровУслуг.Контрагент.Ссылка = ВЫРАЗИТЬ(Vetis_НоменклатураКонтрагентов.ХС.ОрганизацияКонтрагент КАК Справочник.Контрагенты).Ссылка)
ГДЕ
	РеализацияТоваровУслуг.Дата МЕЖДУ &ДатаНачало И &ДатаОкончание
{ГДЕ
	(РеализацияТоваровУслуг.Контрагент = &Контрагент)
	И (РеализацияТоваровУслугТовары.Номенклатура В ИЕРАРХИИ(&Номенклатура))}
Показать


Запрос для всей номенклатуры в базе (макет -- "ВсяНоменклатура");
ВЫБРАТЬ РАЗЛИЧНЫЕ
	Vetis_НаименованияПродукции.Предприятие.Ссылка КАК Предприятие,
	Vetis_НаименованияПродукции.Предприятие.guid КАК ГУИДПредприятия,
	Vetis_НаименованияПродукции.Ссылка КАК НоменклатураМеркурия,
	Vetis_НаименованияПродукции.GUID КАК ГУИДНоменклатуры,
	Vetis_НаименованияПродукции.ХСПроизводитель КАК ХозяйственныйСубъект,
	Vetis_НаименованияПродукции.ХСПроизводитель.guid КАК ГУИДХозяйственногоСубъекта,
	Vetis_НаименованияПродукции.ВидПродукции,
	Vetis_НаименованияПродукции.ВидПродукции.Владелец КАК Продукт,
	Vetis_МатрицаСоответствияПродукцииПроизводителя.Номенклатура.БазоваяЕдиницаИзмерения КАК ЕдиницаИзмерения,
	Vetis_МатрицаСоответствияПродукцииПроизводителя.Номенклатура.Сертификат.ТНВЭД КАК ТНВЭД,
	Vetis_НаименованияПродукции.ВидПродукции.Владелец.productType КАК ТипПродукции,
	Vetis_НоменклатураКонтрагентов.НоменклатураМеркурий.Наименование КАК НоменклатураКонтрагента,
	Vetis_НоменклатураКонтрагентов.НоменклатураМеркурий.Код КАК КодНоменклатурыКонтрагента,
	Vetis_НаименованияПродукции.Наименование КАК Номенклатура
ИЗ
	РегистрСведений.Vetis_МатрицаСоответствияПродукцииПроизводителя КАК Vetis_МатрицаСоответствияПродукцииПроизводителя
		ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.Vetis_НоменклатураКонтрагентов КАК Vetis_НоменклатураКонтрагентов
		ПО (Vetis_НоменклатураКонтрагентов.НоменклатураМеркурийКонтрагента.Ссылка = Vetis_МатрицаСоответствияПродукцииПроизводителя.НаименованиеМеркурий.Ссылка)
		ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Vetis_НаименованияПродукции КАК Vetis_НаименованияПродукции
		ПО Vetis_МатрицаСоответствияПродукцииПроизводителя.НаименованиеМеркурий.Ссылка = Vetis_НаименованияПродукции.Ссылка
ГДЕ
	Vetis_МатрицаСоответствияПродукцииПроизводителя.Номенклатура В ИЕРАРХИИ(&Номенклатура)

УПОРЯДОЧИТЬ ПО
	Vetis_НаименованияПродукции.Наименование
Показать


На форме добавила реквизиты для назначения параметров (на примере Номенклатуры):

Процедура НоменклатураПриИзменении(Элемент)
	ПараметрНоменклатура = КомпоновщикНастроек.Настройки.ПараметрыДанных.Элементы.Найти("Номенклатура");
	Если ЗначениеЗаполнено(Номенклатура) Тогда 
		ПараметрНоменклатура.Использование = Истина;
		ПараметрНоменклатура.Значение = Номенклатура;
	Иначе 
		ПараметрНоменклатура.Использование = Ложь;
	КонецЕсли;
КонецПроцедуры
Показать


Аналогичный код для НачалоПериода, КонецПериода, Контрагент.

Реквизит ВидПоиска типа ПолеВыбора (код ниже). Этот реквизит использую для того, чтобы пользователь выбрал, какие данные ему нужны по всей номенклатуре или только по проданной.
Процедура ПередОткрытием(Отказ, СтандартнаяОбработка)
	ЭлементыФормы.ВидПоиска.СписокВыбора.Добавить(1, "Вся номенклатура");
    ЭлементыФормы.ВидПоиска.СписокВыбора.Добавить(2, "Проданная номенклатура");
КонецПроцедуры


Сначала хотела определять, какую схему использовать, по тому, какие поля на форме заполнены пользователем, например:
1. Если заполнена только номенклатура, выводить всю номенклатуру, содержащуюся в базе.
2. Если заполнен только период, выводить проданную номенклатуру за указанный период без учета контрагента.
3. Если заполнены период и контрагент, выводить проданную номенклатуру за указанный период с учетом контрагента.
Потом решила, что с полем выбора будет проще.

Нашла в Интернете код для выбора нужной схемы компоновки, скопировала в модуль формы, отредактировала под себя:
Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка)

	НеобходимаяСКД = Неопределено;
	Если ВидПоиска = 2 Тогда
		НеобходимаяСКД  = ЭтотОбъект.ПолучитьМакет("ПроданнаяНоменклатура");
	ИначеЕсли ВидПоиска = 1 Тогда 
		НеобходимаяСКД = ЭтотОбъект.ПолучитьМакет("ВсяНоменклатура");
	КонецЕсли;

	// Устанавливаем выбранную СКД как основную.
	ЭтотОбъект.СхемаКомпоновкиДанных = НеобходимаяСКД;

	// Загружаем настройки выбранной СКД в компоновщик настроек.
	ИсточникДоступныхНастроек = Новый ИсточникДоступныхНастроекКомпоновкиДанных(НеобходимаяСКД);
	ЭтотОбъект.КомпоновщикНастроек.Инициализировать(ИсточникДоступныхНастроек);
	ЭтотОбъект.КомпоновщикНастроек.ЗагрузитьНастройки(НеобходимаяСКД.НастройкиПоУмолчанию);

	// Устанавливаем настройки.
	ПараметрыДанных = ЭтотОбъект.КомпоновщикНастроек.Настройки.ПараметрыДанных;
	ПараметрДатаНач = Новый ПараметрКомпоновкиДанных("ДатаНачало");
	ЗначениеДатаНач = ПараметрыДанных.НайтиЗначениеПараметра(ПараметрДатаНач);
	Если ЗначениеДатаНач <> Неопределено Тогда
		ПараметрыДанных.УстановитьЗначениеПараметра(ПараметрДатаНач, ЭтотОбъект.НачалоПериода);
	КонецЕсли;
	
	ПараметрыДанных = ЭтотОбъект.КомпоновщикНастроек.Настройки.ПараметрыДанных;
	ПараметрДатаКон = Новый ПараметрКомпоновкиДанных("ДатаОкончание");
	ЗначениеДатаКон = ПараметрыДанных.НайтиЗначениеПараметра(ПараметрДатаКон);
	Если ЗначениеДатаКон <> Неопределено Тогда
		ПараметрыДанных.УстановитьЗначениеПараметра(ПараметрДатаКон, ЭтотОбъект.КонецПериода);
	КонецЕсли;

	ПараметрыДанных = ЭтотОбъект.КомпоновщикНастроек.Настройки.ПараметрыДанных;
	ПараметрКонтрагент = Новый ПараметрКомпоновкиДанных("Контрагент");
	ЗначениеКонтрагент = ПараметрыДанных.НайтиЗначениеПараметра(ПараметрКонтрагент);
	Если ЗначениеКонтрагент <> Неопределено Тогда
		ПараметрыДанных.УстановитьЗначениеПараметра(ПараметрКонтрагент, ЭтотОбъект.Контрагент);
	КонецЕсли;
	
	ПараметрыДанных = ЭтотОбъект.КомпоновщикНастроек.Настройки.ПараметрыДанных;
	ПараметрНоменклатура = Новый ПараметрКомпоновкиДанных("Номенклатура");
	ЗначениеНоменклатура = ПараметрыДанных.НайтиЗначениеПараметра(ПараметрНоменклатура);
	Если ЗначениеНоменклатура <> Неопределено Тогда
		ПараметрыДанных.УстановитьЗначениеПараметра(ПараметрНоменклатура, ЭтотОбъект.Номенклатура);
	КонецЕсли;

КонецПроцедуры
Показать


При всем этом очистила поле схемы компоновки данных.
При формировании отчета в режиме предприятия выдает ошибку:
Ошибка при исполнении запроса набора данных
по причине:
{(36, 60)}: Не задано значение параметра "Номенклатура"
И РеализацияТоваровУслугТовары.Номенклатура В ИЕРАРХИИ (<<?>>&Номенклатура)


Если указать основной схему для вывода проданной номенклатуры, ругается, что не заполнена номенклатура, хотя этот параметр в запросе задан как необязательный. Если заполнить все параметр, отрабатывает прекрасно. Если указать основной схему для вывода всей номенклатуры и заполнить в предприятии только период, тоже сработает.
Таким образом срабатывает только одна схема, и только если она задана основной. Реквизит "ВидПоиска", получается, вообще не используется. Значит, я не правильно написала Процедуру ПриКомпоновкеРезультата? Возможно не указано событие для срабатывания этой процедуры, тогда где это можно поправить?
Возможно, необходимо использовать и во втором отчете все используемые параметры? Тогда придется использовать документ РеализацияТоваровУслуг, а это очень сильно замедляет работу отчета...

В чем еще может быть загвоздка?
По теме из базы знаний
Найденные решения
15. toypaul 63 01.02.19 09:35 Сейчас в теме
Тут можно сделать все через один запрос и необязательные параметры.

Через объединение соединяете оба запрос в один. В обоих подзапросах добавляете поле "ВидПоиска" , со значением 1 и 2

Через необязательные параметры подключаете отбор по периоду и контрагенту. Отбор по реквизиту ВидПоиска можно настроить программно в ПриКомпоновкеРезультата анализируя параметры. И параметр этот можно сделать недоступным пользователю. Все\

Никаких 2х схем, никаких 2х наборов.
Остальные ответы
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
2. insurgut 207 31.01.19 10:59 Сейчас в теме
Все реализуется на СКД при помощи вложенных схем СКД и 2 вариантов отчета. Никакого программного кода даже не нужно.

И помимо объявления о необязательности параметра в настройках, нужно ещё и в запросе вместо:
ГДЕ
Номенклатура.Ссылка В ИЕРАРХИИ(&Номенклатура)


прописывать условие в зависимости от указания параметра
{ГДЕ Номенклатура.Ссылка В ИЕРАРХИИ(&Номенклатура)}
18. user1030103 05.02.19 05:49 Сейчас в теме
(2) Да, действительно, ошибка пропала, спасибо!
3. buganov 200 31.01.19 11:00 Сейчас в теме
Я бы сделал два независимых макета и программное выполнение в зависимости от переданных параметров. ОСВ, по-моему, так делает в типовых
4. soft_wind 31.01.19 11:00 Сейчас в теме
не заморачивайтесь, просто сделайте ДВА отдельных отчета
5. user1030103 31.01.19 11:03 Сейчас в теме
(4) Но пользователю нужно получать эти данные в одном отчете
8. soft_wind 31.01.19 11:17 Сейчас в теме
(5) одновременно данные из двух отчетов он все равно не получит
сделайте общую форму стартер, там две большие кнопки
"Отчет по номенклатуре" и "Отчет по продажам"
по кнопке просто запускайте нужный отчет.

вообще в меню пользователя выносятся отчеты, там они как-то группируются по темам
Нельзя пытаться все данные все расчеты поместить в один отчет.
Есть устаканившаяся технология, придерживайтесь ее, меньше проблем у вас самих будет (вроде этой)
6. insurgut 207 31.01.19 11:05 Сейчас в теме
7. user1030103 31.01.19 11:15 Сейчас в теме
(6) Лучше разбивать на временные таблицы?
9. insurgut 207 31.01.19 11:25 Сейчас в теме
(7) ну как минимум товары из реализаций с отбором по периоду и сгруппированные по номенклатуре я по в виртуальную таблицу поместил, затем бы уже её связывал с регистрами. Не знаю что там в регистрах, но делать одновременно внутренние соединения с левыми - так себе ход.
10. user1030103 31.01.19 11:29 Сейчас в теме
11. dhurricane 31.01.19 12:09 Сейчас в теме
А у Вас сильно разнится структура отчета в зависимости от вида поиска? Если нет, то можно поступить еще и следующим образом: добавить объединение двух наборов данных. В первом запрос по всей номенклатуре и условие "ГДЕ &ВидПоиска = 1", во втором - запрос по реализациям и условие "ГДЕ &ВидПоиска = 2". В этом случае не потребуется переключение СКД.
12. user1030103 01.02.19 06:38 Сейчас в теме
(11) Структура одинаковая, а вот запросы разные.
13. user1030103 01.02.19 06:39 Сейчас в теме
(11) Я или получаю всю номенклатуру из базы, или только проданную (в зависимости от того, какие поля заполнил пользователь)
14. user1030103 01.02.19 06:40 Сейчас в теме
(11) Можно, наверное, и так попробовать, как Вы посоветовали...
15. toypaul 63 01.02.19 09:35 Сейчас в теме
Тут можно сделать все через один запрос и необязательные параметры.

Через объединение соединяете оба запрос в один. В обоих подзапросах добавляете поле "ВидПоиска" , со значением 1 и 2

Через необязательные параметры подключаете отбор по периоду и контрагенту. Отбор по реквизиту ВидПоиска можно настроить программно в ПриКомпоновкеРезультата анализируя параметры. И параметр этот можно сделать недоступным пользователю. Все\

Никаких 2х схем, никаких 2х наборов.
17. dhurricane 01.02.19 10:04 Сейчас в теме
(15) (16) На счет 2-х наборов - дело вкуса. Да, можно все объединить в один запрос, но если состав колонок разнится, то нагляднее таки 2 набора, т.к. не придется в одном из наборов забивать недостающие колонки NULL-ами.

На счет анализа параметров и использования скрытого необязательного параметра "ВидПоиска" - мне такой подход кажется некорректным, ИМХО. Во-первых, появится возможность сформировать отчет с дублями (параметр выключен). Во-вторых, не очевидно будет поведение отчета. Что, если потребуется сформировать отчет без указания периода и контрагента, с какими-либо другими настройками (по договору?), но отчет именно о проданной номенклатуре? Кажется таки, что ВидПоиска скрывать не стоит. Если только не делать 2 варианта отчета, в каждом из которых устанавливается свое значение параметра, и сам параметр скрыт в настройках пользователя.
16. toypaul 63 01.02.19 09:40 Сейчас в теме
С точки зрения оптимизации совместной работы запроса и СКД нужно будет еще подумать как правильно передать отбор в запрос по полю ВидПоиска.

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

{ГДЕ 1 = &ВидПоиска} внутрь первого подзапроса и {ГДЕ 2 = &ВидПоиска} внутрь второго
19. user1030103 07.02.19 06:18 Сейчас в теме
Оставьте свое сообщение

Для получения уведомлений об ответах подключите телеграм бот:
Инфостарт бот