Как реализовать что-то вроде SUMIF?

jonny3djonny3d Чебоксары
отредактировано 12:18 Раздел: FastReport 2.xx VCL
Как создать функцию SUMIF, чтобы считала сумму только по определенному условию?

К примеру, хочу в футер поместить SumIf(Query1."sum1", Query1."cond" > 0), т.е. что то вроде Sum(Query1."sum1"), но только для записей где Query1."cond" > 0. Как? Посмотрел в исходниках как устроен сам Sum, но там SumIf уже не воткнуть ибо второй и третий параметры уже заняты.. ;) А чтоб не хранить каждый раз значения всех полей, в момент расчета DetailBand'а нужно знать, что в его футере понадобится сумма по определенному полю.. Как сделать проще? ;)

Пока выхожу из положения кучей вычислений и учетом значения. НО... Большое НО: при количестве групп за 2-3 вычислений нерационально много, ибо для каждой группы необходимо будет хранить свою подумму, сбрасывающуюся в ноль при очередном начале группы.. В общем, труба.. ;) ((

Вот в Экселе есть функция СУММЕСЛИ, хорошая такая функция.. А здесь?

Комментарии

  • отредактировано 12:18
    Считайте сумму вручную, в скрипте. Пример - в отчете "subreports" в демке demos\reports.
  • jonny3djonny3d Чебоксары
    отредактировано 12:18
    Нет. В примере обычный пример работы с сабрепортом.. Причем в сабрепорте используется SUM по MasterDetail.

    Хорошо, описываю ситуацию подробнее применительно к данному примеру (demos\reports\subreports)..

    Генерируем отчет из примера и получаем результат. Но, к примеру, мне нужно получить в поле "Total in this order" две записи: "Всего с Qty<10" и "Всего с Qty>=10". Т.е. не просто [Sum([Part total])], а [SumIf([Part total], [Part qty]<10)] + [SumIf([Part total], [Part qty]>=10)] - посчитать отдельно сумму покупок, приобретенных в количестве до 10 и от 10. Так понятнее?

    Для одной группы это можно просчитать, используя имеющуюся математику. НО! Теперь пытаемся получить данные по аналогичной схеме для поля "Total sales this customer" (во внешнем сабрепорте): "Сумма покупок до 1 июля 1988" и "Сумма покупок после 1 июля 1988"... Наступает труба, ибо для каждой последующей записи данные будут суммироваться от предыдущей. В пределах одной группы, данные нужно обнулять, но по выходу их же нужно восстанавливать, ибо они понадобятся во внешней группе. А где их хранить? В переменных? Массивах? А если таких групп 5, как у меня?... ;) ((((((((((((

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

    Можно ли без существенного измененения кода внести новую функцию? В процедуре обработки агрегатных функций doAgreggate после
          if Visible or (s2 = '1') then
          case at of
            atSum, atAvg: v := v + d;
            atMin: if d < v then v := d;
            atMax: if d > v then v := d;
            atCount: v := v + 1;
          end;
    

    Добавить что то вроде:
    if Visible and (s1 = true) and (at = atSumIf) then
      v := v + d;
    

    Это просто пример. В общем, <span style='color:red'>помогите пожалуйста</span>.. Или как реализовать задачу на имеющейся математике или помощь разработчиков в добавлении новой функции..

    Ибо даже при введением пользовательской функции в onUserFunction в момент пробегания по MasterDetail необходимо знать, что в его MasterFooter (или даже GroupFooter) понадобится значение какого-либо поля...
  • jonny3djonny3d Чебоксары
    отредактировано 12:18
    Даже лучше приведите, пожалуйста, пример разделения сумм по условиям на примере "demos\reports\Nested groups", чтобы не усложнять subreport'ами..

    Здесь также попытаемся поделить "Total this order" по условию в количестве товара и "Total sales this customer" по условию совершенных покупок до определенной даты и после...

    Это не тривиальная и не выдуманная задача, которую мне необходимо решить.. А я все бьюсь в изобретении метода расчета..

    Надеюсь на квалифицированную помощь..
  • отредактировано 12:18
    написал:
    Нет. В примере обычный пример работы с сабрепортом.. Причем в сабрепорте используется SUM по MasterDetail.

    В примере есть и использование SUM, и подсчет суммы вручную. В subreport2 считается TotalSales, значение которого выводится в subreport1.
    В вашем случае достаточно при суммировании учитывать условие, например:
    if [Part qty] > 10 then
    TotalSales := TotalSales + [Part total]

    Файл с примером по группе прикреплен, открывать в демке demos\reports. Как сделать такое суммирование для даты, думаю разберетесь сами.

Оставить комментарий

Многофункциональный текстовый редактор. Чтобы отредактировать стиль параграфа, нажмите TAB, чтобы перейти к меню абзаца. Там вы можете выбрать стиль. По умолчанию не выбран ни один стиль. Когда вы выберете текст, появится встроенное меню форматирования. Нажмите TAB, чтобы войти в него. Некоторые элементы, такие как многофункциональные вставки ссылок, картинок, индикаторов загрузки и сообщений об ошибок могут быть вставлены в редактор. Вы можете перемещаться по ним, используя стрелки внутри редактора и удалять с помощью клавиш delete или backspace.