Имя: Пароль:
1C
1С v8
Настройки СКД взятие предыдущего ненулевого значения по месяцам
, ,
0 catharssiss
 
06.04.21
10:49
Добрый день, коллеги!
Давно бьюсь над проблемой красивого решения следующей задачи, пересмотрела уже кучу тем на форумах, но не нашла ничего похожего, а мои знания СКД сильно отличаются от идеала, поэтому скромно прошу тапками не кидать.

И так к сути:
Существует некий отчет на СКД, который показывает среднюю стоимость номенклатуры по месяцам относительно закупок (это важно, т.к. закупки идут не каждый месяц). Соответственно, средняя стоимость считается банально общей стоимостью поделенной на общее количество в рамках номенклатуры. Затем все это выводится в таблицу по месяцам. Соответственно, если в каком-то месяце не было закупки, то и данные будут пустые. Теперь к сути, необходимо посчитать отклонение средней стоимости от предыдущего НЕНУЛЕВОГО месяца. И вот тут начинаются танцы с бубном, т.к. предыдущее значение взять функцией ВычислитьВыражение не сложно, но что будет если встретится нулевое значение?
Приведу пример из моего отчета по расчету предыдущего значения в вычисляемом поле:
ВЫБОР КОГДА естьNULL(ВычислитьВыражение("МАКСИМУМ(СредняяСтоимость)","ПериодМесяц",,"Первая ","Предыдущая"),0) <> 0 Тогда ВычислитьВыражение("МАКСИМУМ(СредняяСтоимость)","ПериодМесяц",,"Первая","Предыдущая") Иначе 0 Конец

Однако тут есть заведомо ошибка, а именно в части применения функции МАКСИМУМ: ВычислитьВыражение("МАКСИМУМ(СредняяСтоимость)","ПериодМесяц",,"Первая ","Предыдущая"). Необходимо применять не функцию максимум к выборке, а именно организовать перебор до первого ненулевого значения в рамках одной номенклатуры.
Но мне не хватает опыта и навыков сделать подобную задачу, а также понять, вообще реально ли это сделать с помощью вычисляемого поля.

Буду рада любой помощи, заранее спасибо!
1 toypaul
 
гуру
06.04.21
11:06
Возможно поможет такой "лайфхак". ВВ вычисляет только те значения, которые есть в данных. то есть в отчете например колонка может быть пустой и там выводится (вроде как) 0, но на самом деле за этот месяц данных не было и ВВ вернет не это значение а предыдущее, которое есть в наборе данных.

Отсюда следует ...

Если в запросе отсечь строки с 0 значениями, то должно сработать просто ВВ(... "Предыдущая","Предыдущая")

если получится, напишите
2 catharssiss
 
06.04.21
11:18
Принимая то, что ВВ не берет нулевое значение, а просто пропускает его...
Попробовала сделать следующим образом:
Предыдущее значение: ВычислитьВыражение("СредняяСтоимость","ПериодМесяц",,"Предыдущая ","Предыдущая")
Отклонение: ВычислитьВыражение("СредняяСтоимость","ПериодМесяц",,"Предыдущая ","Предыдущая") - СредняяСтоимость

Однако получаю очень непонятную картину... а именно "погоду" в тех номенклатурах, в которых нет предыдущего значения вообще.
Подробнее на скриншоте.
https://prnt.sc/115jjju
3 catharssiss
 
06.04.21
11:26
Коллеги, картина в корне меняется, если вычисляемое выражение обернуть в любую агрегатную функцию...
ВычислитьВыражение("МАКСИМУМ(СредняяСтоимость)","ПериодМесяц",,"Предыдущая ","Предыдущая")
ВычислитьВыражение("МАКСИМУМ(СредняяСтоимость)","ПериодМесяц",,"Предыдущая ","Предыдущая") - СредняяСтоимость

Погода как в (2) уходит и вроде как все хорошо рассчитывается... сейчас еще раз перепроверю с калькулятором все и обязательно отпишусь по результату.

Однако я не совсем понимаю смысла в этом, может кто-то объяснить, почему именно так происходит и чем отличается "СредняяСтоимость" от "МАКСИМУМ(СредняяСтоимость)". Полагаю, что имею дело с выборкой, но почему в вычисляемое поле попадает именно список значений, а не конкретное текущее значение для расчета?...
4 catharssiss
 
06.04.21
11:29
К сожалению, преждевременная радость, в (3) варианте не работает перебор до ненулевого значения.
https://prnt.sc/115jx24
5 toypaul
 
гуру
06.04.21
11:39
очевидно что надо вычислять не МАКСИМУМ(СредняяСтоимость), а выражение ресурса заданное в СредняяСтоимость
6 catharssiss
 
06.04.21
11:50
(5) Переделала на выражение ресурса СредняяСтоимость, получилось так:

Предыдущее: ВычислитьВыражение("Сумма(СредняяСтоимость)","ПериодМесяц",,"Предыдущая ","Предыдущая")
Отклонение: ВычислитьВыражение("Сумма(СредняяСтоимость)","ПериодМесяц",,"Предыдущая ","Предыдущая") - СредняяСтоимость
Но это все равно не решает проблему (4)

Как только встречается нулевое значение, расчет предыдущего значения не происходит, т.е. поиск ненулевого значения все равно не работает.
7 toypaul
 
гуру
06.04.21
12:03
ну значит это нулевое значение есть в наборе. а его не должно быть
8 catharssiss
 
06.04.21
12:11
(7) Не совсем понимаю, каким образом исключать нулевое значение в наборе...
Если на уровне запроса, то там никак не избавится от поля вычисления средней стоимости:
    ВЫБОР
        КОГДА СУММА(ЗакупкиОбороты.КоличествоОборот) ЕСТЬ NULL
                ИЛИ СУММА(ЗакупкиОбороты.КоличествоОборот) = 0
            ТОГДА NULL
        ИНАЧЕ СУММА(ЗакупкиОбороты.СтоимостьОборот) / СУММА(ЗакупкиОбороты.КоличествоОборот)
    КОНЕЦ КАК СредняяСтоимость

Если на уровне отбора в самих настройках отчета, то поставила условие в отборе на обязательную заполненность поля "СредняяСтоимость", но результат не изменился.
Поэтому не совсем поняла, каким образом реализовать исключение нулевых значений в наборе.
Можете пояснить поподробнее?
9 catharssiss
 
06.04.21
12:15
(7)
Кажется поняла идею, на уровне запроса забрать результат в ВТ и попробовать почистить нулевые записи.
Сейчас попробую и отпишусь по результату.
10 catharssiss
 
06.04.21
12:24
К сожалению, результат не изменился, приведу на всякий случай текст запроса.
Верно я поняла то, что вы имели ввиду?

ВЫБРАТЬ
    НАЧАЛОПЕРИОДА(ЗакупкиОбороты.Период, МЕСЯЦ) КАК ПериодМесяц,
    ЗакупкиОбороты.Номенклатура КАК Номенклатура,
    СУММА(ЗакупкиОбороты.КоличествоОборот) КАК КоличествоОборот,
    СУММА(ЗакупкиОбороты.СтоимостьОборот) КАК СтоимостьОборот,
    ВЫБОР
        КОГДА СУММА(ЗакупкиОбороты.КоличествоОборот) ЕСТЬ NULL
                ИЛИ СУММА(ЗакупкиОбороты.КоличествоОборот) = 0
            ТОГДА NULL
        ИНАЧЕ СУММА(ЗакупкиОбороты.СтоимостьОборот) / СУММА(ЗакупкиОбороты.КоличествоОборот)
    КОНЕЦ КАК СредняяСтоимость,
    ЗакупкиОбороты.ХарактеристикаНоменклатуры КАК ХарактеристикаНоменклатуры,
    ЗакупкиОбороты.Номенклатура.Родитель КАК НоменклатураРодитель
ПОМЕСТИТЬ ВТ
ИЗ
    РегистрНакопления.Закупки.Обороты(&НачалоПериода, &КонецПериода, Регистратор, ) КАК ЗакупкиОбороты
ГДЕ
    ТИПЗНАЧЕНИЯ(ЗакупкиОбороты.Регистратор) <> ТИП(Документ.ПоступлениеДопРасходов)

СГРУППИРОВАТЬ ПО
    ЗакупкиОбороты.Номенклатура,
    ЗакупкиОбороты.ХарактеристикаНоменклатуры,
    НАЧАЛОПЕРИОДА(ЗакупкиОбороты.Период, МЕСЯЦ),
    ЗакупкиОбороты.Номенклатура.Родитель
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
    ВТ.ПериодМесяц КАК ПериодМесяц,
    ВТ.Номенклатура КАК Номенклатура,
    ВТ.КоличествоОборот КАК КоличествоОборот,
    ВТ.СтоимостьОборот КАК СтоимостьОборот,
    ВТ.СредняяСтоимость КАК СредняяСтоимость,
    ВТ.ХарактеристикаНоменклатуры КАК ХарактеристикаНоменклатуры,
    ВТ.НоменклатураРодитель КАК НоменклатураРодитель
ИЗ
    ВТ КАК ВТ
ГДЕ
    НЕ ВТ.СтоимостьОборот ЕСТЬ NULL
11 toypaul
 
гуру
06.04.21
12:26
нет не верно
12 Rollam
 
06.04.21
15:57
(11) а о чем речь тогда?
13 toypaul
 
гуру
06.04.21
16:11
речь ровно о том, что написано в (1)
14 Rollam
 
06.04.21
16:36
(13) представленный код запроса исключает пустые записи
15 fisher
 
06.04.21
16:49
Имея таблицу закупочных цен по месяцам и таблицу помесячных остатков (или чего там) задача сводится к банальной "получить срез последних на каждую дату в запросе" - это как загуглить методику получения таблицы закупочных цен на каждый месяц включая те, в которых закупок не было (ибо получается полная аналогия с периодическим регистром закупочных цен).
В итоге проблема решена еще в запросе и дополнительные танцы с бубном не нужны.