Не работает отбор в системе компоновки данных
Делаю отчет на СКД. Источник данных — запрос:
ВЫБРАТЬ
ибсВыданныеТалоныОстаткиИОбороты.Контрагент КАК Контрагент,
ибсВыданныеТалоныОстаткиИОбороты.ДоговорКонтрагента КАК Договор,
ибсВыданныеТалоныОстаткиИОбороты.Талон КАК Талон,
ибсРеквизитыДоговоровСрезПоследних.ибсРайон КАК Район,
ибсРеквизитыДоговоровСрезПоследних.ибсТипДоговора КАК ТипДоговора,
ибсВыданныеТалоныОстаткиИОбороты.КоличествоНачальныйОстаток КАК НачальныйОстаток,
ибсВыданныеТалоныОстаткиИОбороты.КоличествоПриход КАК Выдано,
ибсВыданныеТалоныОстаткиИОбороты.КоличествоРасход КАК Использовано,
ибсВыданныеТалоныОстаткиИОбороты.КоличествоКонечныйОстаток КАК КонечныйОстаток
ИЗ
РегистрНакопления.ибсВыданныеТалоны.ОстаткиИОбороты(&НачалоПериода, &КонецПериода, , , ) КАК ибсВыданныеТалоныОстаткиИОбороты
ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ибсРеквизитыДоговоров.СрезПоследних(&КонецПериода, ) КАК ибсРеквизитыДоговоровСрезПоследних
ПО ибсВыданныеТалоныОстаткиИОбороты.ДоговорКонтрагента = ибсРеквизитыДоговоровСрезПоследних.ДоговорКонтрагента
УПОРЯДОЧИТЬ ПО
Контрагент, Договор
В компоновке указываю ресурсы НачальныйОстаток, Выдано, Использовано, КонечныйОстаток. Создаю единственную группировку Контрагент, Договор, Талон, Договор, ТипДоговора и на закладке выбранные поля добавляю все 4 ресурса. Отчет формируется правильно, но при включении отбора по полям Район или ТипДоговора получаю пустой отчет. Что я делаю не так? Почему поля взяты из таблицы прикрепленной Левым соединением нельзя использовать в отборе?
Источник
Не работает отбор в СКД
(15) в качестве теста добавьте вычисляемое поле МенеджерПоле
и укажите выражение Менеджер.
если отбор на МенеджерПоле сработает, значит ваше предположение верно. Тогда в выбранных полях заменить Менеджер на МенеджерПоле и т.д.
(19) по этому фрагменту коду понятно, что стандартная компоновка отключена.
Значит есть вероятность, что в программной компоновке стандартное поведение отбора отключили.
Я бы еще в настройке компоновки создал в качестве теста новый вариант с нуля чтобы флажки Авто стали на свои места и проверил формирование с отборами
Посмотрите модуль объекта для отчета.
Там может быть процедура вроде этой:
Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка)
Если ее заремить, то отчет будет вести себя стандартно.
Ха-Ха! я тоже наткнулся на подобную проблему.
Было: отчет на СКД с кучей временных таблиц и разнообразными джойнами.
Отбор по контрагенту работал выборочно. по каким-то КА работает, по другим не работает. без отбора выводит всех .
Корень зла крылся в том, что при формировании одной из промежуточных временных таблиц был юнион одной таблицы с джойном пары других таблиц. В результате джойна могли появляться NULL значения.
Заменил левый джойн на полный, для того чтобы не получалось NULL значений в ссылочных колонках и isnull( ХЗ, 0) в числовых колонках.
В итоге, по всей цепочке временных таблиц и в итоговой выборке NULL пропали и отбор СКД заработал адекватно.
По логике моего отчета Контрагент должен быть заполнен какой-либо вменяемой ссылкой, не пустым значением.
Если по вашей логике допустимы пустые значения — то их можно заполнить через isNull( HZ , Значение(Справочник.какойто.пустаяссылка))
Мораль — СКД не любит NULL в колонках , по которым выполняется отбор.
Источник
Не работает отбор в системе компоновки данных
Делаю отчет на СКД. Источник данных — запрос:
ВЫБРАТЬ
ибсВыданныеТалоныОстаткиИОбороты.Контрагент КАК Контрагент,
ибсВыданныеТалоныОстаткиИОбороты.ДоговорКонтрагента КАК Договор,
ибсВыданныеТалоныОстаткиИОбороты.Талон КАК Талон,
ибсРеквизитыДоговоровСрезПоследних.ибсРайон КАК Район,
ибсРеквизитыДоговоровСрезПоследних.ибсТипДоговора КАК ТипДоговора,
ибсВыданныеТалоныОстаткиИОбороты.КоличествоНачальныйОстаток КАК НачальныйОстаток,
ибсВыданныеТалоныОстаткиИОбороты.КоличествоПриход КАК Выдано,
ибсВыданныеТалоныОстаткиИОбороты.КоличествоРасход КАК Использовано,
ибсВыданныеТалоныОстаткиИОбороты.КоличествоКонечныйОстаток КАК КонечныйОстаток
ИЗ
РегистрНакопления.ибсВыданныеТалоны.ОстаткиИОбороты(&НачалоПериода, &КонецПериода, , , ) КАК ибсВыданныеТалоныОстаткиИОбороты
ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ибсРеквизитыДоговоров.СрезПоследних(&КонецПериода, ) КАК ибсРеквизитыДоговоровСрезПоследних
ПО ибсВыданныеТалоныОстаткиИОбороты.ДоговорКонтрагента = ибсРеквизитыДоговоровСрезПоследних.ДоговорКонтрагента
УПОРЯДОЧИТЬ ПО
Контрагент, Договор
В компоновке указываю ресурсы НачальныйОстаток, Выдано, Использовано, КонечныйОстаток. Создаю единственную группировку Контрагент, Договор, Талон, Договор, ТипДоговора и на закладке выбранные поля добавляю все 4 ресурса. Отчет формируется правильно, но при включении отбора по полям Район или ТипДоговора получаю пустой отчет. Что я делаю не так? Почему поля взяты из таблицы прикрепленной Левым соединением нельзя использовать в отборе?
Источник
СКД — одна из проблем связи Наборов данных
Доброго времени суток.
Вступление
Собственно все началось с простого задания — есть номенклатура (список номенклатуры), собираемая по спецификации. Надо вывести сколько комплектующих надо для сборки, сколько есть на складах, чтобы принять решение о закупках, сборке, передачах. (Складов много)
Суть проблемы простая — пока в отчете нет отборов (список номенклатуры задается параметром) то схема из нескольких Наборов данных работает хорошо и правильно. Но стоит задать отбор по складу — можно получить пустой отчет. Итак по-порядку. (Конфигурация УПП, так что тексты запросов соответствующие)
1. Подготовка и демонстрация
НаборДанных1 (основная выборка) с полями Комплектующая, Продукция и КоличествоНа1 (среднее взял, потому что бардак в спецификации) — запрос:
ВЫБРАТЬ
СпецификацииНоменклатурыВыходныеИзделия.Номенклатура КАК Продукция,
СпецификацииНоменклатурыИсходныеКомплектующие.Номенклатура КАК Комплектующая,
СРЕДНЕЕ(СпецификацииНоменклатурыИсходныеКомплектующие.Количество / ВЫБОР
КОГДА СпецификацииНоменклатурыВыходныеИзделия.Количество <> 0
ТОГДА СпецификацииНоменклатурыВыходныеИзделия.Количество
ИНАЧЕ 1
КОНЕЦ) КАК КоличествоНа1
ИЗ
Справочник.СпецификацииНоменклатуры.ВыходныеИзделия КАК СпецификацииНоменклатурыВыходныеИзделия
ВНУТРЕННЕЕ СОЕДИНЕНИЕ Справочник.СпецификацииНоменклатуры.ИсходныеКомплектующие КАК СпецификацииНоменклатурыИсходныеКомплектующие
ПО СпецификацииНоменклатурыВыходныеИзделия.Ссылка = СпецификацииНоменклатурыИсходныеКомплектующие.Ссылка
ГДЕ
СпецификацииНоменклатурыВыходныеИзделия.Ссылка.Активная
И СпецификацииНоменклатурыВыходныеИзделия.Номенклатура В ИЕРАРХИИ(&Номенклатура)
СГРУППИРОВАТЬ ПО
СпецификацииНоменклатурыВыходныеИзделия.Номенклатура,
СпецификацииНоменклатурыИсходныеКомплектующие.Номенклатура
НаборДанных2 (остатки, зависимый) — запрос:
ВЫБРАТЬ
ТоварыНаСкладахОстатки.Склад КАК СкладКомплектующей,
ТоварыНаСкладахОстатки.Номенклатура КАК Комплектующая,
ТоварыНаСкладахОстатки.КоличествоОстаток КАК ОстатокКомплектующей
ИЗ
РегистрНакопления.ТоварыНаСкладах.Остатки(<(&КонецПериода)>, <(Склад).* КАК СкладОтбора, (Номенклатура).* КАК Комплектующая>) КАК ТоварыНаСкладахОстатки
Здесь немного поясню: я разделил Склад на поле «выборки» и поле «отбора», т.е. в отборах будет поле СкладОтбора, но его нельзя выбирать в Выбранные поля, хотя СкладКомплектующей тоже можно отбирать. Причина — в хотелке, но об этом ниже.
Связи наборов данных: Источник — НаборДанных1 (основной), Приемник — НаборДанных2 (зависимый), Выражения — Комплектующая.
Ресурсы пока простые: Сумма(КоличествоНа1) и Сумма(ОстатокКомлектующей).
Структура простенькая группировки: Комплектующая — Продукция — Детальные записи. Выбраны все поля.
Выполняю. Получаю ожидаемый результат — все есть, все хорошо:
Дальше была идея Склады в колонки, но тогда получается очень широко и почти не заполнено. Ну если одна комплектующая только на одном складе, то по всем остальным пусто. В общем не очень красиво выходит.
Проблема:
Но вот я задаю отбор «Склад отбора Равно Цех готовой продукции» и результат — только одна комплектующая:
Тогда я еще не знал про «замену Левого на Внутреннее, если есть отбор».
2. Попытка выкрутиться
В статье «СКД — наборы данных и связи между ними. » есть пункт «Некоторые особенности соединения наборов данных» с подпунктом «Отбор по полю подчиненного набора«, где сказано «если необходимо получить все данные из основного набора, нужно наложить отбор на уровне группировки отчета».
Но вот беда: в отборе по группировке, среди доступных полей, нет поля «СкладОтбора»:
Хорошо, попробую использовать СкладКомплектующей. Добавил отборы в каждую группировку, но выключенные и стал включать по очереди. Первым включаю у группировки Комплектующая. Результат такой же, как с отбором по отчету целиком. Отключаю.
Включаю следующий — отбор у группировки Продукции. Уже лучше — все Комплектующие появились, а вот продукции нет. Да и остатки комплектующих странные — по группировке остатки показаны, а из чего получились, откуда взялись?
Отключаю у Продукции. Включаю последний отбор — у детальных записей. Почти идеальный результат, по крайней мере продукция появилась. Но с Остатками по-прежнему: по складам 46, а у группировок — 107 с хвостом. По остальным и того хуже.
Итог: либо я не так понял, либо не то делаю. Но и это не работает. Да и пользователям пояснять в какой ветке нужно поставить отбор — тяжело (прибабахи толстого клиента, где проще дать возможность редактировать настройку, чем вытащить что-то из глубины структуры на форму)
3. Хотелки и их исполнение.
Кому интересно решение проблемы — этот пункт можно пропустить.
Хотелка 1 — а почему не добавить показ остатков по Продукции?
Хотелка 2 — как бы сделать отчет более смотребильным, а то складов много и увидеть остатки сразу в строке — значит надо склады в колонки, а тогда отчет получается «разряженным».
Хотелка 3 — если уж добавил остатки продукции, то отбор по складу должен работать и на это.
Первая решается просто: еще один набор данных. Вот спрашивается, ну почему в запросах можно сделать один запрос во временную таблицу и соединить его несколько раз, а вот тут увы — надо новый набор данных. Ну и чтобы данные не пересекались — колонки переименованы. Так родился НаборДанных3.
ВЫБРАТЬ
ТоварыНаСкладахОстатки.Склад КАК СкладПродукции,
ТоварыНаСкладахОстатки.Номенклатура КАК Продукция,
ТоварыНаСкладахОстатки.КоличествоОстаток КАК ОстатокПродукции
ИЗ
РегистрНакопления.ТоварыНаСкладах.Остатки(<(&КонецПериода)>, <(Склад).* КАК СкладОтбора, (Номенклатура).* КАК Продукция>) КАК ТоварыНаСкладахОстатки
Тут интересный эффект наблюдал, если поле Склад будет иметь одинаковое наименование в обоих подчиненных наборах, то в результате в остатках у продукции будет не правильный склад, потому что значение будет от первого набора. Поэтому — они разные. Одинаковыми могут быть только действительно одинаковые по смыслу поля, например те которые участвуют в связи. Так Номенклатура для НабораДанных2 называется Комплектующая, а в НабореДанных3 — Продукция. Ну а чтобы поле отбора было единым для обоих наборов: появился СкладОтбора — это решило хотелку 3.
Ну и добавляем еще одну связь.
Ну и в ресурсах определяем ОстатокПродукции.
Теперь вторая хотелка. Если выводить данные по складам списком — получим умножение строк остатков, например 5 складов по Комплектующей и 3 по Продукции итого 15 строк. Хорошо хоть итоги по группировкам правильные. Да и как «сложить» 2 одинаковых склада по комплектующей и по продукции? Поля называются по разному и как сделать по ним группировку — не придумал.
Тут на помощь пришла вторая статья Агрегатные функции СКД, о которых мало кто знает. Сначала использовал функцию ТаблицаЗначений. Но при простом повторении формирования отчета строки складов прыгают. Тогда добавил Упорядочить в итоге получилось так:
Для ОстаткаКомплектующих: Упорядочить(ТаблицаЗначений(Различные СкладКомплектующей Как Склад, ОстатокКомплектующей Как Остаток), «Склад Автоупорядочивание»)
Для ОстаткаПродукции: Упорядочить(ТаблицаЗначений(Различные СкладПродукции Как Склад, ОстатокПродукции Как Остаток), «Склад Автоупорядочивание»)
Дальше немного «причесал» структуру: выключил детальные записи, сгруппировал поля, отключил «Общие Итоги по вертикали».
В результате получил — строки группировки «пухнут» в зависимости от количества складов, но видно где, чего и сколько, просто посмотрев по строке. Поставил в ресурсах «Расчитывать по. » (как на картинке выше) и по крайне мере для Комплектующей убрались остатки по складам из колонки остатков продукции. Вот такой результат получил:
Теперь влючаю отбор по складу и вижу результат, опять исчезли строки (что в прочем уже ожидаемо):
4. Поиск решения
Сразу скажу: на мой взгляд не очень хорошее, но другого не нашел. Вопросы такого плана есть, а ответов увы не много. Потому думал сам и пришел к выводу — если связь вместо ЛЕВОЙ становится ВНУТРЕННЕЙ, значит необходимо сделать так, чтобы для каждой записи основного набора существовала запись зависимого, не взирая на отбор.
И тут у меня возникла сложность — я не очень хорошо понимаю в какой момент накладывается отбор при формировании. Потому решил пойти простым путем — эксперимента. Первое что попробовал — изменить запрос остатков: к справочнику номенклатуры Левым соединением добавил Остатки. На тот момент это выглядело так (не использовать, почему — ниже):
ВЫБРАТЬ
ТоварыНаСкладахОстатки.Склад КАК СкладКомплектующей,
СпрНоменклатура.Ссылка КАК Комплектующая,
ТоварыНаСкладахОстатки.КоличествоОстаток КАК ОстатокКомплектующей
ИЗ
Справочник.Номенклатура КАК СпрНоменклатура
ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ТоварыНаСкладах.Остатки(<(&КонецПериода)>, ) КАК ТоварыНаСкладахОстатки
ПО СпрНоменклатура.Ссылка = ТоварыНаСкладахОстатки.Номенклатура
<ГДЕ
ТоварыНаСкладахОстатки.Склад.* КАК СкладОтбора>
Дальше экспериментировал с настройками. Работало долго. На каком-то этапе вообще получил от сервера отлуп по памяти. Бросил.
Пробовал создать набор типа Объединение, где один набор — остатки, другой — опять же номенклатура. Но там надо было создавать сложные условия с ИЛИ, чтобы запись Номенклатуры выбиралась в любом случае. Не пошло.
День бодался. На следующий день пошел по второму кугу. Только все создавал с нуля.
5. Решение
И начал снова с Левого соединения в запросе. Получился такой запрос (правильный):
ВЫБРАТЬ
ТоварыНаСкладахОстатки.Склад КАК СкладКомплектующей,
СпрНоменклатура.Ссылка КАК Комплектующая,
ТоварыНаСкладахОстатки.КоличествоОстаток КАК ОстатокКомплектующей
ИЗ
Справочник.Номенклатура КАК СпрНоменклатура
ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ТоварыНаСкладах.Остатки(<(&КонецПериода)>, <(Склад).* КАК СкладОтбора, (Номенклатура).* КАК Комплектующая>) КАК ТоварыНаСкладахОстатки
ПО СпрНоменклатура.Ссылка = ТоварыНаСкладахОстатки.Номенклатура
Сформировал, посмотрел нормальный результат. Включил отбор и увидел это:
Стал сравнивать с предыдущими тестами и понял: <ГДЕ ТоварыНаСкладахОстатки.Склад.* КАК СкладОтбора>отрабатывала после соединения, а потому отсекало номенклатуру. А когда я перенес его в условия таблицы остатков, то и отбор сработал только на регистр остатков не затронув номенклатуру. Потому первый запрос — не правильный и не работает, а второй заработал (так я считаю).
Но самым удивительным для меня оказался такой результат (отбор по другому складу и еще одна продукция):
Чем удивило? А тем, что Левое соединение я делал только в одном наборе данных — во втором (по комплектующим), а в третьем — как было, так и осталось. Почему же группировка по Продукции не пропала? Почему остатки выдает правильные с учетом отбора? Вывод получился такой — а третий набор, несмотря на то что к нему был применен отбор, все-равно имеет ЛЕВОЕ соединение. Возможно свою лепту вносит тот факт, что для второго и третьего набора один и тот же отбор. Возможно третий слепили со вторым, а потом только с первым.
Правильный вывод или нет — я не знаю.
В общем дальше можно пытаться улучшить. Например, если основной запрос не сложный, то в НабореДанных2 связывать не со справочником номенклатуры, а поместить результат основного запроса во временную таблицу и связать с ним.
Конец
Прошу специалистов не смеяться над стилем изложения, я курсов не проходил. Общаюсь в большинстве своем с пользователями, которым надо объяснить понятно что, почему и как. Да и статья это первая, не потому что писать нечего, а потому, что большая часть уже написана Вами и надо только найти :).
Источник