СКД отбор по сложному ресурсу
Доброго дня, коллеги.
Есть "навороченный" отчет "Рентабельность продаж".
Шапка такая:
Проблема в том, что отбор по полю "Рентабельность, % (Б)" вообще не работает! Любой отбор на любой группировке с любым условием по этому полю.
По регистратору оно вычисляется так:
Иначе так:
Вообще, стоит задача вывести клиентов с рентабельностью <= 3%, но ни один отбор не работает. СКД не понимает отбора по таким сложным ресурсам?!
В данном примере сложность состоит в параметре &УчитыватьСтоимостьОбслуживания. В зависимости от его включения вычисляется "Сумма обслуживания долга". Оно зависит от средней задолженности, процентной ставки и на разных группировках вычисляется по-разному. Отсюда такая борода!
Средний долг вычисляется в отдельном наборе данных и соединяется по ключу аналитики и соглашению:
Замечено, что если в отчете не использовать сей параметр (&УчитыватьСтоимостьОбслуживания), то отбор работает корректно.
Просьба помочь.
Есть "навороченный" отчет "Рентабельность продаж".
Шапка такая:
Проблема в том, что отбор по полю "Рентабельность, % (Б)" вообще не работает! Любой отбор на любой группировке с любым условием по этому полю.
По регистратору оно вычисляется так:
Выбор
Когда Сумма(Выручка) = 0
Тогда 0
Иначе (Сумма(ВаловаяПрибыль_А)
- Выбор
Когда &УчитыватьСтоимостьДоставки
Тогда Сумма(СтоимостьДоставки)
Иначе 0 Конец
- Выбор
Когда &УчитыватьСтоимостьЭкспедирования
Тогда Сумма(СтоимостьЭкспедирования)
Иначе 0 Конец
- Выбор
Когда &УчитыватьБонусы
Тогда Сумма(СуммаБонусов)
Иначе 0 Конец
- Выбор
Когда &УчитыватьСтоимостьОбслуживания
Тогда Выбор Когда ВычислитьВыражение("Сумма(СуммаДокумента)", "Соглашение") = 0 Тогда 0 Иначе Сумма(ВычислитьВыражениеСГруппировкойМассив("Максимум(СреднийДолг)", "Соглашение"))*&ПроцентнаяСтавкаОбслуживанияДолга/100*(РазностьДат(&НачалоПериода, &ОкончаниеПериода, "День")+1)/365*СуммаДокумента/ВычислитьВыражение("Сумма(СуммаДокумента)", "Соглашение") Конец
Иначе 0 Конец
- Выбор
Когда &УчитыватьНалоговуюНагрузку
Тогда Сумма(НалоговаяНагрузка) Иначе 0 Конец) / Сумма(Выручка) * 100
Конец
ПоказатьИначе так:
Выбор Когда Сумма(Выручка) = 0 Тогда 0 Иначе (Сумма(ВаловаяПрибыль_А)
- Выбор
Когда &УчитыватьСтоимостьДоставки
Тогда Сумма(СтоимостьДоставки)
Иначе 0 Конец
- Выбор
Когда &УчитыватьСтоимостьЭкспедирования
Тогда Сумма(СтоимостьЭкспедирования)
Иначе 0 Конец
- Выбор
Когда &УчитыватьБонусы
Тогда Сумма(СуммаБонусов)
Иначе 0 Конец
- Выбор
Когда &УчитыватьСтоимостьОбслуживания
Тогда Сумма(ВычислитьВыражениеСГруппировкойМассив("Максимум(СреднийДолг)", "Соглашение"))*&ПроцентнаяСтавкаОбслуживанияДолга/100*(РазностьДат(&НачалоПериода, &ОкончаниеПериода, "День")+1)/365
Иначе 0
Конец
- Выбор Когда &УчитыватьНалоговуюНагрузку
Тогда Сумма(НалоговаяНагрузка)
Иначе 0 Конец) / Сумма(Выручка) * 100
Конец
ПоказатьВообще, стоит задача вывести клиентов с рентабельностью <= 3%, но ни один отбор не работает. СКД не понимает отбора по таким сложным ресурсам?!
В данном примере сложность состоит в параметре &УчитыватьСтоимостьОбслуживания. В зависимости от его включения вычисляется "Сумма обслуживания долга". Оно зависит от средней задолженности, процентной ставки и на разных группировках вычисляется по-разному. Отсюда такая борода!
Средний долг вычисляется в отдельном наборе данных и соединяется по ключу аналитики и соглашению:
ВЫБРАТЬ
РасчетыСКлиентамиОстаткиИОбороты.АналитикаУчетаПоПартнерам,
РасчетыСКлиентамиОстаткиИОбороты.ЗаказКлиента.Соглашение КАК Соглашение,
СУММА(ВЫБОР
КОГДА РасчетыСКлиентамиОстаткиИОбороты.Период = &НачалоПериода
ТОГДА РасчетыСКлиентамиОстаткиИОбороты.СуммаКонечныйОстаток
ИНАЧЕ РасчетыСКлиентамиОстаткиИОбороты.СуммаОборот
КОНЕЦ * (РАЗНОСТЬДАТ(РасчетыСКлиентамиОстаткиИОбороты.Период, &ОкончаниеПериода, ДЕНЬ) + 1)) / (РАЗНОСТЬДАТ(&НачалоПериода, &ОкончаниеПериода, ДЕНЬ) + 1) КАК СреднийДолг
ИЗ
РегистрНакопления.РасчетыСКлиентами.ОстаткиИОбороты({(&НачалоПериода)}, {(&ОкончаниеПериода)}, День, , ) КАК РасчетыСКлиентамиОстаткиИОбороты
СГРУППИРОВАТЬ ПО
РасчетыСКлиентамиОстаткиИОбороты.ЗаказКлиента.Соглашение,
РасчетыСКлиентамиОстаткиИОбороты.АналитикаУчетаПоПартнерам
ПоказатьЗамечено, что если в отчете не использовать сей параметр (&УчитыватьСтоимостьОбслуживания), то отбор работает корректно.
Просьба помочь.
По теме из базы знаний
Найденные решения
(1)Альтернативный вариант)
Реализовать:
1) выгрузку из текущей СКД в таблицу значений, а не в отчет;
2) сделать новую СКД с набором данных - объект и воткнуть в него таблицу из п.1
3) собственно делать отбор в этой новой СКД и результат выводить в отчет.
Реализовать:
1) выгрузку из текущей СКД в таблицу значений, а не в отчет;
2) сделать новую СКД с набором данных - объект и воткнуть в него таблицу из п.1
3) собственно делать отбор в этой новой СКД и результат выводить в отчет.
Остальные ответы
В избранное
Подписаться на ответы
Сортировка:
Древо развёрнутое
Свернуть все
(1)Альтернативный вариант)
Реализовать:
1) выгрузку из текущей СКД в таблицу значений, а не в отчет;
2) сделать новую СКД с набором данных - объект и воткнуть в него таблицу из п.1
3) собственно делать отбор в этой новой СКД и результат выводить в отчет.
Реализовать:
1) выгрузку из текущей СКД в таблицу значений, а не в отчет;
2) сделать новую СКД с набором данных - объект и воткнуть в него таблицу из п.1
3) собственно делать отбор в этой новой СКД и результат выводить в отчет.
чтобы добраться до сути задачи необходимо пройти лес текста и ряд простыней, а хотелось, чтобы как в школе провели за ручку и на паре картинок показали вот тут не влетело.
чисто телепатически - чтобы работали отборы по агрегатным ресурсам или ресурсам со сложными формулами есть два пути:
1. поля с агрегатами или сложными формулами перенести на закладку вычисляемые поля и там же задать эти формулы.
В ресурсе по этому полю агрегаты и формулы убрать и указать в выражение просто имя поля, т.е. "замкнуть" ресурс сам на себя,
а агрегаты и формулы в вычисляемом поле. В некоторых ситуациях это решает задачу отбора.
2. поля с агрегатами или сложными формулами перенести в пользовательские поля или создать там новые поля с аналогичными выражениями и использовать эти пользовательские поля в отборах.
чисто телепатически - чтобы работали отборы по агрегатным ресурсам или ресурсам со сложными формулами есть два пути:
1. поля с агрегатами или сложными формулами перенести на закладку вычисляемые поля и там же задать эти формулы.
В ресурсе по этому полю агрегаты и формулы убрать и указать в выражение просто имя поля, т.е. "замкнуть" ресурс сам на себя,
а агрегаты и формулы в вычисляемом поле. В некоторых ситуациях это решает задачу отбора.
2. поля с агрегатами или сложными формулами перенести в пользовательские поля или создать там новые поля с аналогичными выражениями и использовать эти пользовательские поля в отборах.
(3) Спасибо за отклик!
2й вариант только что проверил - не работает.
Создал пользовательское поле с таким выражением:
Вычисляется также, но отбор по нему все равно не работает.
1й вариант давно ещё пробовал, слишком сложная формула ресурса, вычисляемые поля я также использую в них, но помню была ошибка вычисления при агрегировании агрегата, т.е. нельзя делать это дважды.
2й вариант только что проверил - не работает.
Создал пользовательское поле с таким выражением:
Выбор
Когда Сумма(Выручка) = 0
Тогда 0
Иначе (Сумма([Валовая прибыль]) - Выбор
Когда [Параметры.Учитывать стоимость доставки]
Тогда Сумма([Стоимость доставки])
Иначе 0
Конец - Выбор
Когда [Параметры.Учитывать стоимость экспедирования]
Тогда Сумма([Стоимость экспедирования])
Иначе 0
Конец - Выбор
Когда [Параметры.Учитывать бонусы]
Тогда Сумма([Сумма бонусов])
Иначе 0
Конец - Выбор
Когда [Параметры.Учитывать стоимость обслуживания]
Тогда Сумма(ВычислитьВыражениеСГруппировкойМассив("Максимум([Средний долг])", "Соглашение")) * [Параметры.Процентная ставка обслуживания долга] / 100 * (РазностьДат([Параметры.Начало периода], [Параметры.Окончание периода], "День") + 1) / 365
Иначе 0
Конец - Выбор
Когда [Параметры.Налоговая нагрузка]
Тогда Сумма([Налоговая нагрузка])
Иначе 0
Конец) / Сумма(Выручка) * 100
Конец
ПоказатьВычисляется также, но отбор по нему все равно не работает.
1й вариант давно ещё пробовал, слишком сложная формула ресурса, вычисляемые поля я также использую в них, но помню была ошибка вычисления при агрегировании агрегата, т.е. нельзя делать это дважды.
(4)
Пример рабочей формулы вложенных агрегатов:
Кавычки внутри вложенности должны быть двойными.
была ошибка вычисления при агрегировании агрегата, т.е. нельзя делать это дважды
Пример рабочей формулы вложенных агрегатов:
Сумма(Вычислить("Сумма(ВычислитьВыражениеСГруппировкойМассив(""Сумма(Показатель)"",""Ссылка""))+1"))
Кавычки внутри вложенности должны быть двойными.
(5) Сделал 2 вычисляемых поля с предварительным расчетом "суммы обслуживания долга":
Использовал их в текущих ресурсах:
и по регистратору:
Результаты отчета совпадают, но отбор все равно не накладывается.
Сумма(ВычислитьВыражениеСГруппировкойМассив("Максимум(СреднийДолг)", "Соглашение"))*&ПроцентнаяСтавкаОбслуживанияДолга/100*(РазностьДат(&НачалоПериода, &ОкончаниеПериода, "День")+1)/365
Выбор Когда
ВычислитьВыражение("Сумма(Выбор Когда Выразить(Регистратор, ""Документ.РеализацияТоваровУслуг"") ЕСТЬ NULL Тогда 0 Иначе Регистратор.СуммаДокумента Конец)", "Соглашение") = 0
Тогда 0
Иначе
Сумма(ВычислитьВыражениеСГруппировкойМассив("Максимум(СреднийДолг)", "Соглашение"))*&ПроцентнаяСтавкаОбслуживанияДолга/100*(РазностьДат(&НачалоПериода, &ОкончаниеПериода, "День")+1)/365*(Выбор Когда Выразить(Регистратор, "Документ.РеализацияТоваровУслуг") ЕСТЬ NULL Тогда 0 Иначе Регистратор.СуммаДокумента Конец)/ВычислитьВыражение("Сумма(Выбор Когда Выразить(Регистратор, ""Документ.РеализацияТоваровУслуг"") ЕСТЬ NULL Тогда 0 Иначе Регистратор.СуммаДокумента Конец)", "Соглашение")
Конец
Использовал их в текущих ресурсах:
Выбор Когда Сумма(Выручка) = 0 Тогда 0 Иначе (Сумма(ИТМ_ВаловаяПрибыль_А) - Выбор
Когда &УчитыватьСтоимостьДоставки
Тогда Сумма(СтоимостьДоставки)
Иначе 0
Конец - Выбор
Когда &УчитыватьСтоимостьЭкспедирования
Тогда Сумма(СтоимостьЭкспедирования)
Иначе 0
Конец - Выбор
Когда &УчитыватьБонусы
Тогда Сумма(СуммаБонусов)
Иначе 0
Конец - Выбор
Когда &УчитыватьСтоимостьОбслуживания
Тогда СуммаОбслуживанияДолгаРассчитанная
Иначе 0
Конец - Выбор Когда &УчитыватьНалоговуюНагрузку Тогда Сумма(НалоговаяНагрузка) Иначе 0 Конец) / Сумма(Выручка) * 100 Конец
Показатьи по регистратору:
Выбор Когда Сумма(Выручка) = 0 Тогда 0 Иначе (Сумма(ИТМ_ВаловаяПрибыль_А) - Выбор
Когда &УчитыватьСтоимостьДоставки
Тогда Сумма(СтоимостьДоставки)
Иначе 0
Конец - Выбор
Когда &УчитыватьСтоимостьЭкспедирования
Тогда Сумма(СтоимостьЭкспедирования)
Иначе 0
Конец - Выбор
Когда &УчитыватьБонусы
Тогда Сумма(СуммаБонусов)
Иначе 0
Конец - Выбор
Когда &УчитыватьСтоимостьОбслуживания
Тогда СуммаОбслуживанияДолгаРассчитаннаяПоРегистратору
Иначе 0
Конец - Выбор Когда &УчитыватьНалоговуюНагрузку Тогда Сумма(НалоговаяНагрузка) Иначе 0 Конец) / Сумма(Выручка) * 100 Конец
ПоказатьРезультаты отчета совпадают, но отбор все равно не накладывается.
если отбор накладывается на весь отчет, то с такими вычислениями он вряд ли сработает.
попробуйте установить отбор в группировке, отключив вывод отбора в настройках группировки - это конечно будет костыль, а для работы отбора на все случаи жизни в корне отчета необходимо глубоко погрузиться в ваш код и видеть настройки,что, честно говоря, лень.
попробуйте установить отбор в группировке, отключив вывод отбора в настройках группировки - это конечно будет костыль, а для работы отбора на все случаи жизни в корне отчета необходимо глубоко погрузиться в ваш код и видеть настройки,что, честно говоря, лень.
(9) Я пробовал везде его ставить - нигде он не работает, ни на группировках, ни просто так.
Интересно, но рентабельность в типовом отчете "ВыручкаИСебестоимостьПродаж" считается как в самом запросе
Так и в ресурсах
Для чего?! Мне, разумеется, это нереально сделать.
Интересно, но рентабельность в типовом отчете "ВыручкаИСебестоимостьПродаж" считается как в самом запросе
ВЫБОР
КОГДА &ДанныеОтчета = 1
ТОГДА ВЫРАЗИТЬ(ВЫБОР
КОГДА СУММА(Таблица.Выручка) <> 0
ТОГДА (СУММА(Таблица.Выручка) - СУММА(Таблица.Себестоимость) - СУММА(Таблица.ДопРасходы)) / СУММА(Таблица.Выручка)
ИНАЧЕ 0
КОНЕЦ * 100 КАК ЧИСЛО(15, 2))
КОГДА &ДанныеОтчета = 3
ТОГДА ВЫРАЗИТЬ(ВЫБОР
КОГДА СУММА(Таблица.ВыручкаРегл) <> 0
ТОГДА (СУММА(Таблица.ВыручкаРегл) - СУММА(Таблица.СебестоимостьРегл)) / СУММА(Таблица.ВыручкаРегл)
ИНАЧЕ 0
КОНЕЦ * 100 КАК ЧИСЛО(15, 2))
ИНАЧЕ ВЫРАЗИТЬ(ВЫБОР
КОГДА СУММА(Таблица.ВыручкаБезНДС) <> 0
ТОГДА (СУММА(Таблица.ВыручкаБезНДС) - СУММА(Таблица.СебестоимостьБезНДС) - СУММА(Таблица.ДопРасходыБезНДС)) / СУММА(Таблица.ВыручкаБезНДС)
ИНАЧЕ 0
КОНЕЦ * 100 КАК ЧИСЛО(15, 2))
КОНЕЦ КАК Рентабельность
ПоказатьТак и в ресурсах
ВЫРАЗИТЬ(
ВЫБОР КОГДА СУММА(Выручка) <> 0 ТОГДА
(СУММА(Выручка)- СУММА(Себестоимость) - СУММА(ДопРасходы))
/ СУММА(Выручка)
ИНАЧЕ
0
КОНЕЦ * 100, "ЧИСЛО(15,2)")
ПоказатьДля чего?! Мне, разумеется, это нереально сделать.
Я обычно для хитрых отборов (учитывающих значения с разных группировок и фильтрующих по значениям определенных группировок) делал отдельный параметр СКД и костыль в запросе (наложение фильтрующего данные нужным образом подзапроса).
ЗЫ. Хотя с использованием магии фигурных скобок возможно получится обойтись и без доп-параметра. В следующий раз попробую.
ЗЫ. Хотя с использованием магии фигурных скобок возможно получится обойтись и без доп-параметра. В следующий раз попробую.
(26) Рентабельность - вычисляемое поле. Данные берутся из основной таблицы + другого набора. (27) Null там нету.
При добавлении любого отбора по этому полю на любой группировке он работает некорректно - выводит значения <= 0 либо вообще ничего. В общем, неадекватный отбор.
При добавлении любого отбора по этому полю на любой группировке он работает некорректно - выводит значения <= 0 либо вообще ничего. В общем, неадекватный отбор.
Сумасшедшая конструкция полей для производительности отчета, если у вас так все плохо, заведите себе регистр накопления "Рентабельность..." (оборотный), сделайте подписку на событие "ПриЗаписиНабора" по регистру "Расчеты с клиентами" и записывайте свою рентабельность во всевозможных вариантах в ресурсы при записи расчетов с клиентами, а потом сделайте отчет "Рентабельность" по новому регистру. Что касается отбора - а условное условие пробовали добавлять в запрос?:
если вычисляемое поле (не в запросе), проверьте галочки (скрин)
{ГДЕ
Выбор
Когда Сумма(Выручка) = 0
Тогда 0
Иначе (Сумма(ВаловаяПрибыль_А)
- Выбор
Когда &УчитыватьСтоимостьДоставки
Тогда Сумма(СтоимостьДоставки)
Иначе 0 Конец
- Выбор
Когда &УчитыватьСтоимостьЭкспедирования
Тогда Сумма(СтоимостьЭкспедирования)
Иначе 0 Конец
- Выбор
Когда &УчитыватьБонусы
Тогда Сумма(СуммаБонусов)
Иначе 0 Конец
- Выбор
Когда &УчитыватьСтоимостьОбслуживания
Тогда Выбор Когда ВычислитьВыражение("Сумма(СуммаДокумента)", "Соглашение") = 0 Тогда 0 Иначе Сумма(ВычислитьВыражениеСГруппировкойМассив("Максимум(СреднийДолг)", "Соглашение"))*&ПроцентнаяСтавкаОбслуживанияДолга/100*(РазностьДат(&НачалоПериода, &ОкончаниеПериода, "День")+1)/365*СуммаДокумента/ВычислитьВыражение("Сумма(СуммаДокумента)", "Соглашение") Конец
Иначе 0 Конец
- Выбор
Когда &УчитыватьНалоговуюНагрузку
Тогда Сумма(НалоговаяНагрузка) Иначе 0 Конец) / Сумма(Выручка) * 100
Конец КАК РентбельностьПродаж}
Показатьесли вычисляемое поле (не в запросе), проверьте галочки (скрин)
Прикрепленные файлы:
(32)Ну не лепите, я предложил, ваше дело. Шизофрения - нагружать отчет конструкциями "выбор когда"! И для каких целей тогда лепят регистры? Я вам предложил вариант для часто используемых механизмов, вы таким образом избавитесь от процессороемких вычислений в отчете, да и еще от написания сложных полей. Удачи!
П.С. работая с большими объемами данных, или сложно-вычисляемых, всегда есть смысл создавать статистические регистры (хоть накопления, хоть сведений)...
П.С. работая с большими объемами данных, или сложно-вычисляемых, всегда есть смысл создавать статистические регистры (хоть накопления, хоть сведений)...
(34) Выбор когда - это не нагрузка, а смех. Все разработчики помимо 1с используют конструкцию "case" в запросах - ничего в этом криминального нет.
Статистический регистр в данном случае не нужен, это всего лишь модернизированный отчет "выручка и себестоимость продаж", где дополнительно наша собственная рентабельность рассчитывается в зависимости от неких наших затрат.
Единственное предложение, что мне в теме понравилось, так это реализация через набор данных "объект" - таблицу значений, предварительно рассчитав её как душе угодно, а затем запихать в компоновку и все будет работать как часы. Правда боюсь падения производительности. Задачу пока приостановил.
Статистический регистр в данном случае не нужен, это всего лишь модернизированный отчет "выручка и себестоимость продаж", где дополнительно наша собственная рентабельность рассчитывается в зависимости от неких наших затрат.
Единственное предложение, что мне в теме понравилось, так это реализация через набор данных "объект" - таблицу значений, предварительно рассчитав её как душе угодно, а затем запихать в компоновку и все будет работать как часы. Правда боюсь падения производительности. Задачу пока приостановил.