DevExpress MVC Pivotgrid: как суммировать/агрегировать по-разному на уровнях группировки

У меня есть DevExpress MVC PivotGrid. У него есть заголовок, который на самом высоком уровне — «Квартал», затем «Месяцы», затем «Недели». Данные, которые передаются в сетку, должны суммировать данные за неделю, но усреднять данные за неделю за месяц и усреднять данные (неделю или месяц) за квартал.

Вот скриншот сетки:

введите здесь описание изображения

Я хочу, чтобы недели 201632, 201633, 201634, 201635 были 0,1, но июль 2016 также должен быть 0,1 (так как это среднее значение) и то же самое для сентября. Тогда 2016 Q2, 2016 Q4 также должны иметь 0,1 (так как это среднее значение).

Вот код для полей сетки

settings.Fields.Add(field =>
{
    field.Area = PivotArea.ColumnArea;
    field.AreaIndex = 0;
    field.TotalsVisibility = PivotTotalsVisibility.None;
    field.CellStyle.Wrap = DefaultBoolean.False;
    field.Width = 150;
    field.Caption = "Quarter Year";
    field.FieldName = "YYYYQ";
    field.CellStyle.HorizontalAlign = System.Web.UI.WebControls.HorizontalAlign.Center;
    field.Options.AllowSort = DefaultBoolean.False;
    field.Options.AllowFilter = DefaultBoolean.False;
});

settings.Fields.Add(field =>
{
    field.Area = PivotArea.ColumnArea;
    field.AreaIndex = 1;
    field.TotalsVisibility = PivotTotalsVisibility.None;
    field.CellStyle.Wrap = DefaultBoolean.False;
    field.Width = 150;
    field.Caption = "Month Year";
    field.FieldName = "YYYYMM";
    field.CellStyle.HorizontalAlign = System.Web.UI.WebControls.HorizontalAlign.Center;
    field.Options.AllowSort = DefaultBoolean.False;
    field.Options.AllowFilter = DefaultBoolean.False;
});

settings.Fields.Add(field =>
{
    field.Area = PivotArea.ColumnArea;
    field.AreaIndex = 2;
    field.CellStyle.Wrap = DefaultBoolean.False;
    field.Width = 150;
    field.Caption = "Work Week";
    field.FieldName = "YYYYWW";
    field.Options.AllowSort = DefaultBoolean.False;
    field.Options.AllowFilter = DefaultBoolean.False;
});

settings.Fields.Add(field =>
{
    field.Area = PivotArea.DataArea;
    field.FieldName = summaryField;
    field.Caption = summaryField;
    field.CellFormat.FormatType = FormatType.Numeric;
    field.CellFormat.FormatString = format;
});

я пытался использовать

field.SummaryType = DevExpress.Data.PivotGrid.PivotSummaryType.Average;

в квартал и месяц, но это не имело никакого эффекта. Я пробовал кучу других вещей, но ничего не меняет расчеты.

Какие-либо предложения?


person Steve    schedule 17.03.2016    source источник


Ответы (1)


Я понял. Мне нужно было использовать тип Custom Summary

Вот код для PivotGrid

@using DevExpressPivotGridTest;

@{
    string summaryField = ViewBag.SummaryField;
    WWMMQ wwmmq = new WWMMQ();
}

@Html.DevExpress().PivotGrid(settings =>
{
    settings.Name = "PivotGridProject";
    settings.CallbackRouteValues = new { Controller = "PivotGrid", Action = "Project"};
    settings.OptionsPager.RowsPerPage = 100;
    settings.OptionsView.ShowFilterHeaders = false;

    settings.OptionsView.ColumnTotalsLocation = PivotTotalsLocation.Near;

    settings.CustomSummary = (sender, e) =>
    {
        int nbrWWs;
        string fieldName = "";

        if (e.ColumnField == null)
            fieldName = "";
        else
            fieldName = e.ColumnField.FieldName;


        switch (fieldName)
        {
            case "YYYYMM":
                nbrWWs = wwmmq.GetWorkWeeksInMonth(e.ColumnFieldValue.ToInt());
                e.CustomValue = e.SummaryValue.Summary.ToDecimal() / nbrWWs;
                break;

            case "YYYYQ":
                nbrWWs = wwmmq.GetWorkWeeksInQuarter(e.ColumnFieldValue.ToInt());
                e.CustomValue = e.SummaryValue.Summary.ToDecimal() / nbrWWs;
                break;

            case "YYYYWW":
            default:
                e.CustomValue = e.SummaryValue.Summary;
                break;
        }
    };

    settings.Fields.Add(field =>
    {
        field.Area = PivotArea.RowArea;
        field.AreaIndex = 0;
        field.FieldName = "ProjectName";
        field.Caption = "Project";
        field.Options.AllowFilter = DefaultBoolean.False;
    });

    settings.Fields.Add(field =>
    {
        field.Area = PivotArea.RowArea;
        field.AreaIndex = 2;
        field.FieldName = "SupplierName";
        field.Caption = "Supplier";
        field.Options.AllowFilter = DefaultBoolean.False;
    });

    settings.Fields.Add(field =>
    {
        field.Area = PivotArea.ColumnArea;
        field.AreaIndex = 0;
        field.TotalsVisibility = PivotTotalsVisibility.None;
        field.CellStyle.Wrap = DefaultBoolean.False;
        field.Width = 150;
        field.Caption = "Quarter Year";
        field.FieldName = "YYYYQ";
        field.CellStyle.HorizontalAlign = System.Web.UI.WebControls.HorizontalAlign.Center;
        field.Options.AllowSort = DefaultBoolean.False;
        field.Options.AllowFilter = DefaultBoolean.False;
    });

    settings.Fields.Add(field =>
    {
        field.Area = PivotArea.ColumnArea;
        field.AreaIndex = 1;
        field.TotalsVisibility = PivotTotalsVisibility.None;
        field.CellStyle.Wrap = DefaultBoolean.False;
        field.Width = 150;
        field.Caption = "Month Year";
        field.FieldName = "YYYYMM";
        field.CellStyle.HorizontalAlign = System.Web.UI.WebControls.HorizontalAlign.Center;
        field.Options.AllowSort = DefaultBoolean.False;
        field.Options.AllowFilter = DefaultBoolean.False;
    });

    settings.Fields.Add(field =>
    {
        field.Area = PivotArea.ColumnArea;
        field.AreaIndex = 2;
        field.CellStyle.Wrap = DefaultBoolean.False;
        field.Width = 150;
        field.Caption = "Work Week";
        field.FieldName = "YYYYWW";
        field.Options.AllowSort = DefaultBoolean.False;
        field.Options.AllowFilter = DefaultBoolean.False;
    });

    settings.Fields.Add(field =>
    {
        field.SummaryType = PivotSummaryType.Custom;

        field.Area = PivotArea.DataArea;
        field.FieldName = summaryField;
        field.Caption = summaryField;
        field.CellFormat.FormatType = FormatType.Numeric;
        field.CellFormat.FormatString = "n2";
    });
}).Bind(Model).GetHtml()

public class WWMMQ
{
    private List<MyDates> dates;   

    public WWMMQ()
    {
        dates = MyDates.Get();
    }

    public WWMMQ(string startDate, string endDate)
    {
        dates = MyDates.Get(startDate, endDate);
    }

    public int GetWorkWeeksInMonth(int month)
    {
        // some months have 4, some months have 5
        return dates.Count(d => d.YYYYMM == month);
    }

    public int GetWorkWeeksInQuarter(int quarter)
    {
        // most quarters have 13, some quarters have 14
        return dates.Count(d => d.YYYYQ == quarter);
    }

Хитрость заключалась в том, чтобы определить функцию Custom Summary. DevExpress уже вычисляет все агрегаты. Для сводки за неделю я просто использую значение суммы, как обычно, но для месяца и квартала я использую сумму, но делю ее на количество недель в месяце или квартале, чтобы получить среднее значение.

person Steve    schedule 21.03.2016