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

1. triviumfan 91 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 91 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 91 25.09.18 16:28 Сейчас в теме
(17) Нету там его и не было никогда)
20. Akuji 22 25.09.18 16:35 Сейчас в теме
(18)а вот тут ВычислитьВыражениеСГруппировкойМассив по идее массив, а не число...
21. triviumfan 91 25.09.18 16:40 Сейчас в теме
(20) Сумма(ВычислитьВыражениеСГруппировкойМассив("Выражение", "Группировка")
22. Akuji 22 25.09.18 16:46 Сейчас в теме
(21)
ВычислитьВыражениеСГруппировкойМассив

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

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

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

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

если вычисляемое поле (не в запросе), проверьте галочки (скрин)
Прикрепленные файлы:
32. triviumfan 91 26.09.18 13:58 Сейчас в теме
(31) Если бы там было ограничение, то оно бы вообще было недоступно в отборе :)
Отдельный регистр для таких целей лепить - шизофрения.
34. Ditron 183 26.09.18 14:10 Сейчас в теме
(32)Ну не лепите, я предложил, ваше дело. Шизофрения - нагружать отчет конструкциями "выбор когда"! И для каких целей тогда лепят регистры? Я вам предложил вариант для часто используемых механизмов, вы таким образом избавитесь от процессороемких вычислений в отчете, да и еще от написания сложных полей. Удачи!
П.С. работая с большими объемами данных, или сложно-вычисляемых, всегда есть смысл создавать статистические регистры (хоть накопления, хоть сведений)...
35. triviumfan 91 26.09.18 15:37 Сейчас в теме +0.5 $m
(34) Выбор когда - это не нагрузка, а смех. Все разработчики помимо 1с используют конструкцию "case" в запросах - ничего в этом криминального нет.
Статистический регистр в данном случае не нужен, это всего лишь модернизированный отчет "выручка и себестоимость продаж", где дополнительно наша собственная рентабельность рассчитывается в зависимости от неких наших затрат.
Единственное предложение, что мне в теме понравилось, так это реализация через набор данных "объект" - таблицу значений, предварительно рассчитав её как душе угодно, а затем запихать в компоновку и все будет работать как часы. Правда боюсь падения производительности. Задачу пока приостановил.
andreypahov; +1 Ответить
36. Ditron 183 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 91 12.03.19 20:19 Сейчас в теме
(38) Пробовал все это - не катит)
Оставьте свое сообщение
Вакансии
Программист 1С
Казань
зарплата от 150 000 руб.
Полный день

Разработчик 1С
Москва
зарплата от 200 000 руб. до 300 000 руб.
Полный день

Программист 1С (удаленно)
Самара
зарплата от 230 000 руб. до 230 000 руб.
Полный день

Руководитель группы разработки 1С
Москва
зарплата от 250 000 руб. до 250 000 руб.
Полный день

Специалист техподдержки
Санкт-Петербург
зарплата от 100 руб. до 150 руб.
Полный день