СКД отбор по сложному ресурсу

1. triviumfan 93 25.09.18 10:19 Сейчас в теме
Доброго дня, коллеги.

Есть "навороченный" отчет "Рентабельность продаж".
Шапка такая:
Проблема в том, что отбор по полю "Рентабельность, % (Б)" вообще не работает! Любой отбор на любой группировке с любым условием по этому полю.

По регистратору оно вычисляется так:
Выбор 
  Когда Сумма(Выручка) = 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) КАК СреднийДолг
ИЗ
	РегистрНакопления.РасчетыСКлиентами.ОстаткиИОбороты({(&НачалоПериода)}, {(&ОкончаниеПериода)}, День, , ) КАК РасчетыСКлиентамиОстаткиИОбороты

СГРУППИРОВАТЬ ПО
	РасчетыСКлиентамиОстаткиИОбороты.ЗаказКлиента.Соглашение,
	РасчетыСКлиентамиОстаткиИОбороты.АналитикаУчетаПоПартнерам
Показать


Замечено, что если в отчете не использовать сей параметр (&УчитыватьСтоимостьОбслуживания), то отбор работает корректно.
Просьба помочь.
По теме из базы знаний
Вознаграждение за ответ
Показать полностью
Найденные решения
12. Sashares 34 25.09.18 14:33 Сейчас в теме +0.5 $m
(1)Альтернативный вариант)
Реализовать:
1) выгрузку из текущей СКД в таблицу значений, а не в отчет;
2) сделать новую СКД с набором данных - объект и воткнуть в него таблицу из п.1
3) собственно делать отбор в этой новой СКД и результат выводить в отчет.
triviumfan; +1 Ответить
Остальные ответы
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
12. Sashares 34 25.09.18 14:33 Сейчас в теме +0.5 $m
(1)Альтернативный вариант)
Реализовать:
1) выгрузку из текущей СКД в таблицу значений, а не в отчет;
2) сделать новую СКД с набором данных - объект и воткнуть в него таблицу из п.1
3) собственно делать отбор в этой новой СКД и результат выводить в отчет.
triviumfan; +1 Ответить
14. triviumfan 93 25.09.18 14:57 Сейчас в теме
(12) Ох ты боже мой... идея ясна, насколько время выполнения увеличится?)
16. Sashares 34 25.09.18 15:16 Сейчас в теме
(14)Да ктож его знает)
Зависит от объема данных.
Но имхо, вряд ли сильно.
17. Akuji 22 25.09.18 15:57 Сейчас в теме
(1)
Там Null наверное где то прячется...
18. triviumfan 93 25.09.18 16:28 Сейчас в теме
(17) Нету там его и не было никогда)
20. Akuji 22 25.09.18 16:35 Сейчас в теме
(18)а вот тут ВычислитьВыражениеСГруппировкойМассив по идее массив, а не число...
21. triviumfan 93 25.09.18 16:40 Сейчас в теме
(20) Сумма(ВычислитьВыражениеСГруппировкойМассив("Выражение", "Группировка")
22. Akuji 22 25.09.18 16:46 Сейчас в теме
(21)
ВычислитьВыражениеСГруппировкойМассив

а сумма массива что дает?

Функция возвращает массив, каждый элемент которого содержит результат вычисления выражения для группировки по указанному полю.
2. triviumfan 93 25.09.18 10:20 Сейчас в теме
Шапка
Прикрепленные файлы:
3. VmvLer 25.09.18 10:45 Сейчас в теме
чтобы добраться до сути задачи необходимо пройти лес текста и ряд простыней, а хотелось, чтобы как в школе провели за ручку и на паре картинок показали вот тут не влетело.

чисто телепатически - чтобы работали отборы по агрегатным ресурсам или ресурсам со сложными формулами есть два пути:

1. поля с агрегатами или сложными формулами перенести на закладку вычисляемые поля и там же задать эти формулы.
В ресурсе по этому полю агрегаты и формулы убрать и указать в выражение просто имя поля, т.е. "замкнуть" ресурс сам на себя,
а агрегаты и формулы в вычисляемом поле. В некоторых ситуациях это решает задачу отбора.
2. поля с агрегатами или сложными формулами перенести в пользовательские поля или создать там новые поля с аналогичными выражениями и использовать эти пользовательские поля в отборах.
4. triviumfan 93 25.09.18 11:14 Сейчас в теме
(3) Спасибо за отклик!
2й вариант только что проверил - не работает.
Создал пользовательское поле с таким выражением:
Выбор
	Когда Сумма(Выручка) = 0
		Тогда 0
	Иначе (Сумма([Валовая прибыль]) - Выбор
			Когда [Параметры.Учитывать стоимость доставки]
				Тогда Сумма([Стоимость доставки])
			Иначе 0
		Конец - Выбор
			Когда [Параметры.Учитывать стоимость экспедирования]
				Тогда Сумма([Стоимость экспедирования])
			Иначе 0
		Конец - Выбор
			Когда [Параметры.Учитывать бонусы]
				Тогда Сумма([Сумма бонусов])
			Иначе 0
		Конец - Выбор
			Когда [Параметры.Учитывать стоимость обслуживания]
				Тогда Сумма(ВычислитьВыражениеСГруппировкойМассив("Максимум([Средний долг])", "Соглашение")) * [Параметры.Процентная ставка обслуживания долга] / 100 * (РазностьДат([Параметры.Начало периода], [Параметры.Окончание периода], "День") + 1) / 365
			Иначе 0
		Конец - Выбор
			Когда [Параметры.Налоговая нагрузка]
				Тогда Сумма([Налоговая нагрузка])
			Иначе 0
		Конец) / Сумма(Выручка) * 100
Конец
Показать

Вычисляется также, но отбор по нему все равно не работает.
1й вариант давно ещё пробовал, слишком сложная формула ресурса, вычисляемые поля я также использую в них, но помню была ошибка вычисления при агрегировании агрегата, т.е. нельзя делать это дважды.
5. VmvLer 25.09.18 11:18 Сейчас в теме
(4)
была ошибка вычисления при агрегировании агрегата, т.е. нельзя делать это дважды


Пример рабочей формулы вложенных агрегатов:
Сумма(Вычислить("Сумма(ВычислитьВыражениеСГруппировкойМассив(""Сумма(Показатель)"",""Ссылка""))+1"))

Кавычки внутри вложенности должны быть двойными.
6. triviumfan 93 25.09.18 11:22 Сейчас в теме
(5) Но рентабельность у меня на разных группировках по разному рассчитывается. Я же не могу 2 ресурса в одно вычисляемое поле запихать.
7. triviumfan 93 25.09.18 11:24 Сейчас в теме
(5) Сейчас попробую сумму обслуживания долга так рассчитать, ведь из-за неё трабл, а в итоговом ресурсе использовать уже рассчитаное вычисляемое поле.
8. triviumfan 93 25.09.18 12:31 Сейчас в теме
(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. VmvLer 25.09.18 14:00 Сейчас в теме
если отбор накладывается на весь отчет, то с такими вычислениями он вряд ли сработает.

попробуйте установить отбор в группировке, отключив вывод отбора в настройках группировки - это конечно будет костыль, а для работы отбора на все случаи жизни в корне отчета необходимо глубоко погрузиться в ваш код и видеть настройки,что, честно говоря, лень.
10. triviumfan 93 25.09.18 14:16 Сейчас в теме
(9) Я пробовал везде его ставить - нигде он не работает, ни на группировках, ни просто так.
Интересно, но рентабельность в типовом отчете "ВыручкаИСебестоимостьПродаж" считается как в самом запросе
ВЫБОР
		КОГДА &ДанныеОтчета = 1
			ТОГДА ВЫРАЗИТЬ(ВЫБОР
						КОГДА СУММА(Таблица.Выручка) <> 0
							ТОГДА (СУММА(Таблица.Выручка) - СУММА(Таблица.Себестоимость) - СУММА(Таблица.ДопРасходы)) / СУММА(Таблица.Выручка)
						ИНАЧЕ 0
					КОНЕЦ * 100 КАК ЧИСЛО(15, 2))
		КОГДА &ДанныеОтчета = 3
			ТОГДА ВЫРАЗИТЬ(ВЫБОР
						КОГДА СУММА(Таблица.ВыручкаРегл) <> 0
							ТОГДА (СУММА(Таблица.ВыручкаРегл) - СУММА(Таблица.СебестоимостьРегл)) / СУММА(Таблица.ВыручкаРегл)
						ИНАЧЕ 0
					КОНЕЦ * 100 КАК ЧИСЛО(15, 2))
		ИНАЧЕ ВЫРАЗИТЬ(ВЫБОР
					КОГДА СУММА(Таблица.ВыручкаБезНДС) <> 0
						ТОГДА (СУММА(Таблица.ВыручкаБезНДС) - СУММА(Таблица.СебестоимостьБезНДС) - СУММА(Таблица.ДопРасходыБезНДС)) / СУММА(Таблица.ВыручкаБезНДС)
					ИНАЧЕ 0
				КОНЕЦ * 100 КАК ЧИСЛО(15, 2))
	КОНЕЦ КАК Рентабельность
Показать

Так и в ресурсах
ВЫРАЗИТЬ(
    ВЫБОР КОГДА СУММА(Выручка) <> 0 ТОГДА
            (СУММА(Выручка)- СУММА(Себестоимость) - СУММА(ДопРасходы))
            / СУММА(Выручка)
    ИНАЧЕ
        0
    КОНЕЦ * 100, "ЧИСЛО(15,2)")
Показать

Для чего?! Мне, разумеется, это нереально сделать.
11. Fox-trot 158 25.09.18 14:27 Сейчас в теме
19. triviumfan 93 25.09.18 16:29 Сейчас в теме
(11) Версию конфы? Она тут не причём, УТ 11.3 перепаханная вдоль и поперёк.
13. herfis 499 25.09.18 14:47 Сейчас в теме
Я обычно для хитрых отборов (учитывающих значения с разных группировок и фильтрующих по значениям определенных группировок) делал отдельный параметр СКД и костыль в запросе (наложение фильтрующего данные нужным образом подзапроса).
ЗЫ. Хотя с использованием магии фигурных скобок возможно получится обойтись и без доп-параметра. В следующий раз попробую.
15. JohnGalt 57 25.09.18 14:59 Сейчас в теме
Если в запросе используется объединение, и нужное поле не во всех таблицах, отбор для тех таблиц не будет работать.
26. VmvLer 26.09.18 08:44 Сейчас в теме
(15) по-моему это верный ответ на поставленную задачу, а все остальные рассуждения тут ведут не туда
28. triviumfan 93 26.09.18 09:25 Сейчас в теме
(26) Рентабельность - вычисляемое поле. Данные берутся из основной таблицы + другого набора. (27) Null там нету.
При добавлении любого отбора по этому полю на любой группировке он работает некорректно - выводит значения <= 0 либо вообще ничего. В общем, неадекватный отбор.
23. triviumfan 93 25.09.18 16:57 Сейчас в теме
Ещё прикол в том, что условное оформление работает корректно, а отбор - дело хитрое.
24. Fox-trot 158 25.09.18 18:31 Сейчас в теме
значит при оформлении все рассчитывается заново, а в отбор берется уже готовые результаты
25. mao_san 26.09.18 01:00 Сейчас в теме
А может быть где то в готовых вычислениях имеет место быть null? когда в строках отчета, имеет место значение, отличное от остальных в этой колонке по типу, поле отбор перестает работать
27. triviumfan 93 26.09.18 09:17 Сейчас в теме
(25) я внимательно посмотрел результат сего поля, вывел доп. поле с типом значения рентабельности - все говорит о том, что там исключительно число, все рассчитывается верно, но очень сложно.
29. Ramzay82 26.09.18 09:28 Сейчас в теме
Оба варианта не работают
user1057077; +1 Ответить
30. JohnGalt 57 26.09.18 11:55 Сейчас в теме
А эту Рентабельность в ресурсы добавили? Можно еще рассчитать не в вычисляемых полях а формулу прописать на закладке Ресурсы.
33. triviumfan 93 26.09.18 13:59 Сейчас в теме
(30) В шапке формулы ресурсов сей рентабельности. В вычисляемых полях лишь инициализация и предварительные расчеты переменных, участвующих в сей формуле.
31. Ditron 185 26.09.18 13:10 Сейчас в теме
Сумасшедшая конструкция полей для производительности отчета, если у вас так все плохо, заведите себе регистр накопления "Рентабельность..." (оборотный), сделайте подписку на событие "ПриЗаписиНабора" по регистру "Расчеты с клиентами" и записывайте свою рентабельность во всевозможных вариантах в ресурсы при записи расчетов с клиентами, а потом сделайте отчет "Рентабельность" по новому регистру. Что касается отбора - а условное условие пробовали добавлять в запрос?:
{ГДЕ
   Выбор 
  Когда Сумма(Выручка) = 0 
    Тогда 0 
    Иначе (Сумма(ВаловаяПрибыль_А) 
- Выбор
    Когда &УчитыватьСтоимостьДоставки
        Тогда Сумма(СтоимостьДоставки)
    Иначе 0 Конец 
- Выбор
    Когда &УчитыватьСтоимостьЭкспедирования
        Тогда Сумма(СтоимостьЭкспедирования)
    Иначе 0 Конец 
- Выбор
    Когда &УчитыватьБонусы
        Тогда Сумма(СуммаБонусов)
    Иначе 0 Конец 
- Выбор
    Когда &УчитыватьСтоимостьОбслуживания
        Тогда Выбор Когда ВычислитьВыражение("Сумма(СуммаДокумента)", "Соглашение") = 0 Тогда 0 Иначе Сумма(ВычислитьВыражениеСГруппировкойМассив("Максимум(СреднийДолг)", "Соглашение"))*&ПроцентнаяСтавкаОбслуживанияДолга/100*(РазностьДат(&НачалоПериода, &ОкончаниеПериода, "День")+1)/365*СуммаДокумента/ВычислитьВыражение("Сумма(СуммаДокумента)", "Соглашение") Конец
    Иначе 0 Конец 
- Выбор 
  Когда &УчитыватьНалоговуюНагрузку 
    Тогда Сумма(НалоговаяНагрузка) Иначе 0 Конец) / Сумма(Выручка) * 100 
Конец КАК РентбельностьПродаж}
Показать

если вычисляемое поле (не в запросе), проверьте галочки (скрин)
Прикрепленные файлы:
32. triviumfan 93 26.09.18 13:58 Сейчас в теме
(31) Если бы там было ограничение, то оно бы вообще было недоступно в отборе :)
Отдельный регистр для таких целей лепить - шизофрения.
34. Ditron 185 26.09.18 14:10 Сейчас в теме
(32)Ну не лепите, я предложил, ваше дело. Шизофрения - нагружать отчет конструкциями "выбор когда"! И для каких целей тогда лепят регистры? Я вам предложил вариант для часто используемых механизмов, вы таким образом избавитесь от процессороемких вычислений в отчете, да и еще от написания сложных полей. Удачи!
П.С. работая с большими объемами данных, или сложно-вычисляемых, всегда есть смысл создавать статистические регистры (хоть накопления, хоть сведений)...
35. triviumfan 93 26.09.18 15:37 Сейчас в теме +0.5 $m
(34) Выбор когда - это не нагрузка, а смех. Все разработчики помимо 1с используют конструкцию "case" в запросах - ничего в этом криминального нет.
Статистический регистр в данном случае не нужен, это всего лишь модернизированный отчет "выручка и себестоимость продаж", где дополнительно наша собственная рентабельность рассчитывается в зависимости от неких наших затрат.
Единственное предложение, что мне в теме понравилось, так это реализация через набор данных "объект" - таблицу значений, предварительно рассчитав её как душе угодно, а затем запихать в компоновку и все будет работать как часы. Правда боюсь падения производительности. Задачу пока приостановил.
andreypahov; +1 Ответить
36. Ditron 185 26.09.18 16:12 Сейчас в теме
(35)на счет ВЫБОР КОГДА вы не правы, почитайте мат часть, и работы с датой тоже (ДОБАВИТЬКДАТЕ, РАЗНОСТЬДАТ), а предложение набор данных объект - хорошее, и не факт что он будет медленнее...
37. Sashares 34 26.09.18 21:42 Сейчас в теме
(35)Жаль, было бы интересно узнать результат)
38. Duber_man 27.09.18 15:39 Сейчас в теме
а не проверял ли какие типы у разных строк записей для рентабельности? попробуй явно указать тип (набор данных или вичисляемое поле - > тип значения -> число(15,2) или в коде выразить() как число(15,2)
39. triviumfan 93 12.03.19 20:19 Сейчас в теме
(38) Пробовал все это - не катит)
Оставьте свое сообщение

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