Доброго дня, коллеги.

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

По регистратору оно вычисляется так:

```1c
    Выбор
    Когда Сумма(Выручка) = 0
    Тогда 0
    Иначе (Сумма(ВаловаяПрибыль_А)
    - Выбор
    Когда &УчитыватьСтоимостьДоставки
    Тогда Сумма(СтоимостьДоставки)
    Иначе 0 Конец
    - Выбор
    Когда &УчитыватьСтоимостьЭкспедирования
    Тогда Сумма(СтоимостьЭкспедирования)
    Иначе 0 Конец
    - Выбор
    Когда &УчитыватьБонусы
    Тогда Сумма(СуммаБонусов)
    Иначе 0 Конец
    - Выбор
    Когда &УчитыватьСтоимостьОбслуживания
    Тогда Выбор Когда ВычислитьВыражение("Сумма(СуммаДокумента)", "Соглашение") = 0 Тогда 0 Иначе Сумма(ВычислитьВыражениеСГруппировкойМассив("Максимум(СреднийДолг)", "Соглашение"))*&ПроцентнаяСтавкаОбслуживанияДолга/100*(РазностьДат(&НачалоПериода, &ОкончаниеПериода, "День")+1)/365*СуммаДокумента/ВычислитьВыражение("Сумма(СуммаДокумента)", "Соглашение") Конец
    Иначе 0 Конец
    - Выбор
    Когда &УчитыватьНалоговуюНагрузку
    Тогда Сумма(НалоговаяНагрузка) Иначе 0 Конец) / Сумма(Выручка) * 100
    Конец
```

Иначе так:

```1c
    Выбор Когда Сумма(Выручка) = 0 Тогда 0 Иначе (Сумма(ВаловаяПрибыль_А)
    - Выбор
    Когда &УчитыватьСтоимостьДоставки
    Тогда Сумма(СтоимостьДоставки)
    Иначе 0 Конец
    - Выбор
    Когда &УчитыватьСтоимостьЭкспедирования
    Тогда Сумма(СтоимостьЭкспедирования)
    Иначе 0 Конец
    - Выбор
    Когда &УчитыватьБонусы
    Тогда Сумма(СуммаБонусов)
    Иначе 0 Конец
    - Выбор
    Когда &УчитыватьСтоимостьОбслуживания
    Тогда Сумма(ВычислитьВыражениеСГруппировкойМассив("Максимум(СреднийДолг)", "Соглашение"))*&ПроцентнаяСтавкаОбслуживанияДолга/100*(РазностьДат(&НачалоПериода, &ОкончаниеПериода, "День")+1)/365
    Иначе 0
    Конец
    - Выбор Когда &УчитыватьНалоговуюНагрузку
    Тогда Сумма(НалоговаяНагрузка)
    Иначе 0 Конец) / Сумма(Выручка) * 100
    Конец
```

Вообще, стоит задача вывести клиентов с рентабельностью <= 3%, но ни один отбор не работает. СКД не понимает отбора по таким сложным ресурсам?!
В данном примере сложность состоит в параметре &УчитыватьСтоимостьОбслуживания. В зависимости от его включения вычисляется "Сумма обслуживания долга". Оно зависит от средней задолженности, процентной ставки и на разных группировках вычисляется по-разному. Отсюда такая борода!
Средний долг вычисляется в отдельном наборе данных и соединяется по ключу аналитики и соглашению:

```1c
    ВЫБРАТЬ
    РасчетыСКлиентамиОстаткиИОбороты.АналитикаУчетаПоПартнерам,
    РасчетыСКлиентамиОстаткиИОбороты.ЗаказКлиента.Соглашение КАК Соглашение,
    СУММА(ВЫБОР
    КОГДА РасчетыСКлиентамиОстаткиИОбороты.Период = &НачалоПериода
    ТОГДА РасчетыСКлиентамиОстаткиИОбороты.СуммаКонечныйОстаток
    ИНАЧЕ РасчетыСКлиентамиОстаткиИОбороты.СуммаОборот
    КОНЕЦ * (РАЗНОСТЬДАТ(РасчетыСКлиентамиОстаткиИОбороты.Период, &ОкончаниеПериода, ДЕНЬ) + 1)) / (РАЗНОСТЬДАТ(&НачалоПериода, &ОкончаниеПериода, ДЕНЬ) + 1) КАК СреднийДолг
    ИЗ
    РегистрНакопления.РасчетыСКлиентами.ОстаткиИОбороты({(&НачалоПериода)}, {(&ОкончаниеПериода)}, День, , ) КАК РасчетыСКлиентамиОстаткиИОбороты

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

Замечено, что если в отчете не использовать сей параметр (&УчитыватьСтоимостьОбслуживания), то отбор работает корректно.
Просьба помочь.
---
Альтернативный вариант)
Реализовать:
1) выгрузку из текущей СКД в таблицу значений, а не в отчет;
2) сделать новую СКД с набором данных - объект и воткнуть в него таблицу из п.1
3) собственно делать отбор в этой новой СКД и результат выводить в отчет.
---
Альтернативный вариант)
Реализовать:
1) выгрузку из текущей СКД в таблицу значений, а не в отчет;
2) сделать новую СКД с набором данных - объект и воткнуть в него таблицу из п.1
3) собственно делать отбор в этой новой СКД и результат выводить в отчет.
---
Ох ты боже мой... идея ясна, насколько время выполнения увеличится?)
---
Да ктож его знает)
Зависит от объема данных.
Но имхо, вряд ли сильно.
---
Там Null наверное где то прячется...
---
Нету там его и не было никогда)
---
а вот тут ВычислитьВыражениеСГруппировкойМассив по идее массив, а не число...
---
Сумма(ВычислитьВыражениеСГруппировкойМассив("Выражение", "Группировка")
---
ВычислитьВыражениеСГруппировкойМассив
а сумма массива что дает?

Функция возвращает массив, каждый элемент которого содержит результат вычисления выражения для группировки по указанному полю.
---
Шапка
---
чтобы добраться до сути задачи необходимо пройти лес текста и ряд простыней, а хотелось, чтобы как в школе провели за ручку и на паре картинок показали вот тут не влетело.

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

1. поля с агрегатами или сложными формулами перенести на закладку вычисляемые поля и там же задать эти формулы.
    В ресурсе по этому полю агрегаты и формулы убрать и указать в выражение просто имя поля, т.е. "замкнуть" ресурс сам на себя,
    а агрегаты и формулы в вычисляемом поле. В некоторых ситуациях это решает задачу отбора.
2. поля с агрегатами или сложными формулами перенести в пользовательские поля или создать там новые поля с аналогичными выражениями и использовать эти пользовательские поля в отборах.
---
Спасибо за отклик!
2й вариант только что проверил - не работает.
Создал пользовательское поле с таким выражением:

```1c
    Выбор
    Когда Сумма(Выручка) = 0
    Тогда 0
    Иначе (Сумма([Валовая прибыль]) - Выбор
    Когда [Параметры.Учитывать стоимость доставки]
    Тогда Сумма([Стоимость доставки])
    Иначе 0
    Конец - Выбор
    Когда [Параметры.Учитывать стоимость экспедирования]
    Тогда Сумма([Стоимость экспедирования])
    Иначе 0
    Конец - Выбор
    Когда [Параметры.Учитывать бонусы]
    Тогда Сумма([Сумма бонусов])
    Иначе 0
    Конец - Выбор
    Когда [Параметры.Учитывать стоимость обслуживания]
    Тогда Сумма(ВычислитьВыражениеСГруппировкойМассив("Максимум([Средний долг])", "Соглашение")) * [Параметры.Процентная ставка обслуживания долга] / 100 * (РазностьДат([Параметры.Начало периода], [Параметры.Окончание периода], "День") + 1) / 365
    Иначе 0
    Конец - Выбор
    Когда [Параметры.Налоговая нагрузка]
    Тогда Сумма([Налоговая нагрузка])
    Иначе 0
    Конец) / Сумма(Выручка) * 100
    Конец
```

Вычисляется также, но отбор по нему все равно не работает.
1й вариант давно ещё пробовал, слишком сложная формула ресурса, вычисляемые поля я также использую в них, но помню была ошибка вычисления при агрегировании агрегата, т.е. нельзя делать это дважды.
---
была ошибка вычисления при агрегировании агрегата, т.е. нельзя делать это дважды

Пример рабочей формулы вложенных агрегатов:

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

Кавычки внутри вложенности должны быть двойными.
---
Но рентабельность у меня на разных группировках по разному рассчитывается. Я же не могу 2 ресурса в одно вычисляемое поле запихать.
---
Сейчас попробую сумму обслуживания долга так рассчитать, ведь из-за неё трабл, а в итоговом ресурсе использовать уже рассчитаное вычисляемое поле.
---
Сделал 2 вычисляемых поля с предварительным расчетом "суммы обслуживания долга":

```1c
    Сумма(ВычислитьВыражениеСГруппировкойМассив("Максимум(СреднийДолг)", "Соглашение"))*&ПроцентнаяСтавкаОбслуживанияДолга/100*(РазностьДат(&НачалоПериода, &ОкончаниеПериода, "День")+1)/365
```

```1c
    Выбор Когда
    ВычислитьВыражение("Сумма(Выбор Когда Выразить(Регистратор, "Документ.РеализацияТоваровУслуг") ЕСТЬ NULL Тогда 0 Иначе Регистратор.СуммаДокумента Конец)", "Соглашение") = 0
    Тогда 0
    Иначе
    Сумма(ВычислитьВыражениеСГруппировкойМассив("Максимум(СреднийДолг)", "Соглашение"))*&ПроцентнаяСтавкаОбслуживанияДолга/100*(РазностьДат(&НачалоПериода, &ОкончаниеПериода, "День")+1)/365*(Выбор Когда Выразить(Регистратор, "Документ.РеализацияТоваровУслуг") ЕСТЬ NULL Тогда 0 Иначе Регистратор.СуммаДокумента Конец)/ВычислитьВыражение("Сумма(Выбор Когда Выразить(Регистратор, "Документ.РеализацияТоваровУслуг") ЕСТЬ NULL Тогда 0 Иначе Регистратор.СуммаДокумента Конец)", "Соглашение")
    Конец
```

Использовал их в текущих ресурсах:

```1c
    Выбор Когда Сумма(Выручка) = 0 Тогда 0 Иначе (Сумма(ИТМ_ВаловаяПрибыль_А) - Выбор
    Когда &УчитыватьСтоимостьДоставки
    Тогда Сумма(СтоимостьДоставки)
    Иначе 0
    Конец - Выбор
    Когда &УчитыватьСтоимостьЭкспедирования
    Тогда Сумма(СтоимостьЭкспедирования)
    Иначе 0
    Конец - Выбор
    Когда &УчитыватьБонусы
    Тогда Сумма(СуммаБонусов)
    Иначе 0
    Конец - Выбор
    Когда &УчитыватьСтоимостьОбслуживания
    Тогда СуммаОбслуживанияДолгаРассчитанная
    Иначе 0
    Конец - Выбор Когда &УчитыватьНалоговуюНагрузку Тогда Сумма(НалоговаяНагрузка) Иначе 0 Конец) / Сумма(Выручка) * 100 Конец
```

и по регистратору:

```1c
    Выбор Когда Сумма(Выручка) = 0 Тогда 0 Иначе (Сумма(ИТМ_ВаловаяПрибыль_А) - Выбор
    Когда &УчитыватьСтоимостьДоставки
    Тогда Сумма(СтоимостьДоставки)
    Иначе 0
    Конец - Выбор
    Когда &УчитыватьСтоимостьЭкспедирования
    Тогда Сумма(СтоимостьЭкспедирования)
    Иначе 0
    Конец - Выбор
    Когда &УчитыватьБонусы
    Тогда Сумма(СуммаБонусов)
    Иначе 0
    Конец - Выбор
    Когда &УчитыватьСтоимостьОбслуживания
    Тогда СуммаОбслуживанияДолгаРассчитаннаяПоРегистратору
    Иначе 0
    Конец - Выбор Когда &УчитыватьНалоговуюНагрузку Тогда Сумма(НалоговаяНагрузка) Иначе 0 Конец) / Сумма(Выручка) * 100 Конец
```

Результаты отчета совпадают, но отбор все равно не накладывается.
---
если отбор накладывается на весь отчет, то с такими вычислениями он вряд ли сработает.

попробуйте установить отбор в группировке, отключив вывод отбора в настройках группировки - это конечно будет костыль, а для работы отбора на все случаи жизни в корне отчета необходимо глубоко погрузиться в ваш код и видеть настройки,что, честно говоря, лень.
---
Я пробовал везде его ставить - нигде он не работает, ни на группировках, ни просто так.
Интересно, но рентабельность в типовом отчете "ВыручкаИСебестоимостьПродаж" считается как в самом запросе

```1c
    ВЫБОР
    КОГДА &ДанныеОтчета = 1
    ТОГДА ВЫРАЗИТЬ(ВЫБОР
    КОГДА СУММА(Таблица.Выручка) <> 0
    ТОГДА (СУММА(Таблица.Выручка) - СУММА(Таблица.Себестоимость) - СУММА(Таблица.ДопРасходы)) / СУММА(Таблица.Выручка)
    ИНАЧЕ 0
    КОНЕЦ * 100 КАК ЧИСЛО(15, 2))
    КОГДА &ДанныеОтчета = 3
    ТОГДА ВЫРАЗИТЬ(ВЫБОР
    КОГДА СУММА(Таблица.ВыручкаРегл) <> 0
    ТОГДА (СУММА(Таблица.ВыручкаРегл) - СУММА(Таблица.СебестоимостьРегл)) / СУММА(Таблица.ВыручкаРегл)
    ИНАЧЕ 0
    КОНЕЦ * 100 КАК ЧИСЛО(15, 2))
    ИНАЧЕ ВЫРАЗИТЬ(ВЫБОР
    КОГДА СУММА(Таблица.ВыручкаБезНДС) <> 0
    ТОГДА (СУММА(Таблица.ВыручкаБезНДС) - СУММА(Таблица.СебестоимостьБезНДС) - СУММА(Таблица.ДопРасходыБезНДС)) / СУММА(Таблица.ВыручкаБезНДС)
    ИНАЧЕ 0
    КОНЕЦ * 100 КАК ЧИСЛО(15, 2))
    КОНЕЦ КАК Рентабельность
```

Так и в ресурсах

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

Для чего?! Мне, разумеется, это нереально сделать.
---
версию свою скажи
---
Версию конфы? Она тут не причём, УТ 11.3 перепаханная вдоль и поперёк.
---
Я обычно для хитрых отборов (учитывающих значения с разных группировок и фильтрующих по значениям определенных группировок) делал отдельный параметр СКД и костыль в запросе (наложение фильтрующего данные нужным образом подзапроса).
ЗЫ. Хотя с использованием магии фигурных скобок возможно получится обойтись и без доп-параметра. В следующий раз попробую.
---
Если в запросе используется объединение, и нужное поле не во всех таблицах, отбор для тех таблиц не будет работать.
---
по-моему это верный ответ на поставленную задачу, а все остальные рассуждения тут ведут не туда
---
Рентабельность - вычисляемое поле. Данные берутся из основной таблицы + другого набора. (27) Null там нету.
При добавлении любого отбора по этому полю на любой группировке он работает некорректно - выводит значения <= 0 либо вообще ничего. В общем, неадекватный отбор.
---
Ещё прикол в том, что условное оформление работает корректно, а отбор - дело хитрое.
---
значит при оформлении все рассчитывается заново, а в отбор берется уже готовые результаты
---
А может быть где то в готовых вычислениях имеет место быть null? когда в строках отчета, имеет место значение, отличное от остальных в этой колонке по типу, поле отбор перестает работать
---
я внимательно посмотрел результат сего поля, вывел доп. поле с типом значения рентабельности - все говорит о том, что там исключительно число, все рассчитывается верно, но очень сложно.
---
Оба варианта не работают
---
А эту Рентабельность в ресурсы добавили? Можно еще рассчитать не в вычисляемых полях а формулу прописать на закладке Ресурсы.
---
В шапке формулы ресурсов сей рентабельности. В вычисляемых полях лишь инициализация и предварительные расчеты переменных, участвующих в сей формуле.
---
Сумасшедшая конструкция полей для производительности отчета, если у вас так все плохо, заведите себе регистр накопления "Рентабельность..." (оборотный), сделайте подписку на событие "ПриЗаписиНабора" по регистру "Расчеты с клиентами" и записывайте свою рентабельность во всевозможных вариантах в ресурсы при записи расчетов с клиентами, а потом сделайте отчет "Рентабельность" по новому регистру. Что касается отбора - а условное условие пробовали добавлять в запрос?:

```1c
    {ГДЕ
    Выбор
    Когда Сумма(Выручка) = 0
    Тогда 0
    Иначе (Сумма(ВаловаяПрибыль_А)
    - Выбор
    Когда &УчитыватьСтоимостьДоставки
    Тогда Сумма(СтоимостьДоставки)
    Иначе 0 Конец
    - Выбор
    Когда &УчитыватьСтоимостьЭкспедирования
    Тогда Сумма(СтоимостьЭкспедирования)
    Иначе 0 Конец
    - Выбор
    Когда &УчитыватьБонусы
    Тогда Сумма(СуммаБонусов)
    Иначе 0 Конец
    - Выбор
    Когда &УчитыватьСтоимостьОбслуживания
    Тогда Выбор Когда ВычислитьВыражение("Сумма(СуммаДокумента)", "Соглашение") = 0 Тогда 0 Иначе Сумма(ВычислитьВыражениеСГруппировкойМассив("Максимум(СреднийДолг)", "Соглашение"))*&ПроцентнаяСтавкаОбслуживанияДолга/100*(РазностьДат(&НачалоПериода, &ОкончаниеПериода, "День")+1)/365*СуммаДокумента/ВычислитьВыражение("Сумма(СуммаДокумента)", "Соглашение") Конец
    Иначе 0 Конец
    - Выбор
    Когда &УчитыватьНалоговуюНагрузку
    Тогда Сумма(НалоговаяНагрузка) Иначе 0 Конец) / Сумма(Выручка) * 100
    Конец КАК РентбельностьПродаж}
```

если вычисляемое поле (не в запросе), проверьте галочки (скрин)
---
Если бы там было ограничение, то оно бы вообще было недоступно в отборе :)
Отдельный регистр для таких целей лепить - шизофрения.
---
Ну не лепите, я предложил, ваше дело. Шизофрения - нагружать отчет конструкциями "выбор когда"! И для каких целей тогда лепят регистры? Я вам предложил вариант для часто используемых механизмов, вы таким образом избавитесь от процессороемких вычислений в отчете, да и еще от написания сложных полей. Удачи!
П.С. работая с большими объемами данных, или сложно-вычисляемых, всегда есть смысл создавать статистические регистры (хоть накопления, хоть сведений)...
---
Выбор когда - это не нагрузка, а смех. Все разработчики помимо 1с используют конструкцию "case" в запросах - ничего в этом криминального нет.
Статистический регистр в данном случае не нужен, это всего лишь модернизированный отчет "выручка и себестоимость продаж", где дополнительно наша собственная рентабельность рассчитывается в зависимости от неких наших затрат.
Единственное предложение, что мне в теме понравилось, так это реализация через набор данных "объект" - таблицу значений, предварительно рассчитав её как душе угодно, а затем запихать в компоновку и все будет работать как часы. Правда боюсь падения производительности. Задачу пока приостановил.
---
на счет ВЫБОР КОГДА вы не правы, почитайте мат часть, и работы с датой тоже (ДОБАВИТЬКДАТЕ, РАЗНОСТЬДАТ), а предложение набор данных объект - хорошее, и не факт что он будет медленнее...
---
Жаль, было бы интересно узнать результат)
---
а не проверял ли какие типы у разных строк записей для рентабельности? попробуй явно указать тип (набор данных или вичисляемое поле - > тип значения -> число(15,2) или в коде выразить() как число(15,2)
---
Пробовал все это - не катит)