첨부 실행 코드는 나눔고딕코딩 폰트를 사용합니다.
본 블로그는 광고를 포함하고 있습니다.
광고 클릭에서 발생하는 수익금은 모두 블로그 콘텐츠 향상을 위해 쓰여집니다.

728x90
반응형
728x170

TestProject.zip
다운로드

▶ CustomSummaryHelper.cs

using System;
using System.Collections.Generic;
using System.Linq;

using DevExpress.XtraPivotGrid;

namespace TestProject
{
    /// <summary>
    /// 커스텀 SUMMARY 헬퍼
    /// </summary>
    public static class CustomSummaryHelper
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Method
        ////////////////////////////////////////////////////////////////////////////////////////// Static
        //////////////////////////////////////////////////////////////////////////////// Public

        #region 그룹 SUMMARY 값 구하기 - GetGroupSummaryValue(groupingEnumerable, target, dataFieldName)

        /// <summary>
        /// 그룹 SUMMARY 값 구하기
        /// </summary>
        /// <param name="groupingEnumerable">그룹핑 열거 가능형</param>
        /// <param name="target">타겟</param>
        /// <param name="dataFieldName">데이터 필드명</param>
        /// <returns>그룹 SUMMARY 값</returns>
        public static decimal GetGroupSummaryValue
        (
            IEnumerable<IGrouping<object, PivotDrillDownDataRow>> groupingEnumerable,
            object                                                target,
            string                                                dataFieldName
        )
        {
            var targetGroup = groupingEnumerable.FirstOrDefault(g => object.Equals(g.Key, target));

            if(targetGroup == null)
            {
                return 0;
            }

            return targetGroup.Sum(r => Convert.ToDecimal(r[dataFieldName]));
        }

        #endregion
        #region 커스텀 값 계산 강제 여부 구하기 - ShouldCalculateCustomValue(groupField, e)

        /// <summary>
        /// 커스텀 값 계산 강제 여부 구하기
        /// </summary>
        /// <param name="groupField">그룹 필드</param>
        /// <param name="e">이벤트 인자</param>
        /// <returns>커스텀 값 계산 강제 여부</returns>
        public static bool ShouldCalculateCustomValue(PivotGridField groupField, PivotGridCustomSummaryEventArgs e)
        {
            if(!groupField.Visible || groupField.Area == PivotArea.FilterArea || groupField.Area == PivotArea.DataArea)
            {
                return true;
            }

            if(groupField.Area == PivotArea.RowArea && (e.RowField == null || e.RowField.AreaIndex < groupField.AreaIndex))
            {
                return true;
            }

            if(groupField.Area == PivotArea.ColumnArea && (e.ColumnField == null || e.ColumnField.AreaIndex < groupField.AreaIndex))
            {
                return true;
            }

            return false;
        }

        #endregion
    }
}

 

▶ MainForm.cs

using System;
using System.Linq;

using DevExpress.Data;
using DevExpress.Data.PivotGrid;
using DevExpress.XtraEditors;
using DevExpress.XtraPivotGrid;

namespace TestProject
{
    /// <summary>
    /// 메인 폼
    /// </summary>
    public partial class MainForm : XtraForm
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region 생성자 - MainForm()

        /// <summary>
        /// 생성자
        /// </summary>
        public MainForm()
        {
            InitializeComponent();

            SelectCustomSummaryApproach(this.pivotGridControl.OptionsData.DataProcessingEngine);

            this.optimizedModeToggleSwitch.Toggled      += optimizedModeToggleSwitch_Toggled;
            this.pivotGridControl.FieldValueDisplayText += pivotGridControl_FieldValueDisplayText;

            this.pivotGridControl.DataSource = TestData.GetTestDataList();

            this.pivotGridControl.BestFit();
        }

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Method
        ////////////////////////////////////////////////////////////////////////////////////////// Private
        //////////////////////////////////////////////////////////////////////////////// Event

        #region 최적화 모드 토글 스위치 토글시 처리하기 - optimizedModeToggleSwitch_Toggled(sender, e)

        /// <summary>
        /// 최적화 모드 토글 스위치 토글시 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private void optimizedModeToggleSwitch_Toggled(object sender, EventArgs e)
        {
            ToggleSwitch toggleSwitch = sender as ToggleSwitch;

            if(toggleSwitch.IsOn)
            {
                this.pivotGridControl.Fields["Value"].SummaryType = PivotSummaryType.Sum;

                this.pivotGridControl.CustomSummary -= pivotGridControl_CustomSummary;

                this.pivotGridControl.OptionsData.DataProcessingEngine = PivotDataProcessingEngine.Optimized;

                SelectCustomSummaryApproach(PivotDataProcessingEngine.Optimized);
            }
            else
            {
                this.pivotGridControl.OptionsData.DataProcessingEngine = PivotDataProcessingEngine.LegacyOptimized;

                SelectCustomSummaryApproach(PivotDataProcessingEngine.LegacyOptimized);
            };
        }

        #endregion
        #region 피벗 그리드 컨트롤 SUMMARY 커스텀 설정하기 - pivotGridControl_CustomSummary(sender, e)

        /// <summary>
        /// 피벗 그리드 컨트롤 SUMMARY 커스텀 설정하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private void pivotGridControl_CustomSummary(object sender, PivotGridCustomSummaryEventArgs e)
        {
            if(e.DataField.Name == "fieldValue")
            {
                if(CustomSummaryHelper.ShouldCalculateCustomValue(fieldType, e))
                {
                    var groupedDataSource = e.CreateDrillDownDataSource().Cast<PivotDrillDownDataRow>().GroupBy(r => r[fieldType]);

                    decimal incomeSummary = CustomSummaryHelper.GetGroupSummaryValue(groupedDataSource, "수입", e.FieldName);
                    decimal outlaySummary = CustomSummaryHelper.GetGroupSummaryValue(groupedDataSource, "지출", e.FieldName);

                    e.CustomValue = incomeSummary - outlaySummary;
                }
                else
                {
                    e.CustomValue = e.SummaryValue.Summary;
                }
            }
        }

        #endregion
        #region 피벗 그리드 컨트롤 필드 값 디스플레이 텍스트 설정하기 - pivotGridControl_FieldValueDisplayText(sender, e)

        /// <summary>
        /// 피벗 그리드 컨트롤 필드 값 디스플레이 텍스트 설정하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private void pivotGridControl_FieldValueDisplayText(object sender, PivotFieldDisplayTextEventArgs e)
        {
            if(e.ValueType == PivotGridValueType.GrandTotal)
            {
                if(e.IsColumn)
                {
                    e.DisplayText = "소계";
                }
                else
                {
                    e.DisplayText = "총계";
                }
            }

            if(e.ValueType == PivotGridValueType.Total)
            {
                if(e.IsColumn)
                {
                    e.DisplayText = e.DisplayText.Replace("Total", "계");
                }
            }
        }

        #endregion

        //////////////////////////////////////////////////////////////////////////////// Function

        #region 값 소계 필드 추가하기 - AddValueTotalField()

        /// <summary>
        /// 값 소계 필드 추가하기
        /// </summary>
        /// <returns>값 소계 필드</returns>
        private PivotGridField AddValueTotalField()
        {
            PivotGridField field = new PivotGridField
            {
                Name      = "fieldValueTotal",
                FieldName = "Savings",
                Caption   = "손익",
                Area      = PivotArea.DataArea,
                AreaIndex = 0,
            };

            field.Options.ShowValues = false;

            this.pivotGridControl.Fields.Add(field);

            return field;
        }

        #endregion
        #region 최적화 접근법 사용하기 - UseOptimizedApproach()

        /// <summary>
        /// 최적화 접근법 사용하기
        /// </summary>
        private void UseOptimizedApproach()
        {
            this.pivotGridControl.Fields["Value"].Options.ShowTotals     = false;
            this.pivotGridControl.Fields["Value"].Options.ShowGrandTotal = false;

            PivotGridField valueTotalField = this.pivotGridControl.Fields.GetFieldByName("fieldValueTotal");
            
            if(valueTotalField == null)
            {
                valueTotalField = AddValueTotalField();
            }

            ExpressionDataBinding savingsBinding = new ExpressionDataBinding("Sum(Iif([Type]='수입', [Value], -[Value]))");

            valueTotalField.DataBinding = savingsBinding;
        }

        #endregion
        #region 언바운드 수식 접근법 사용하기 - UseUnboundExpressionApproach()

        /// <summary>
        /// 언바운드 수식 접근법 사용하기
        /// </summary>
        private void UseUnboundExpressionApproach()
        {
            this.pivotGridControl.Fields["Value"].Options.ShowTotals     = false;
            this.pivotGridControl.Fields["Value"].Options.ShowGrandTotal = false;

            PivotGridField valueTotalField = this.pivotGridControl.Fields.GetFieldByName("fieldValueTotal");
            
            if(valueTotalField == null)
            {
                valueTotalField = AddValueTotalField();
            }

            valueTotalField.UnboundExpression     = "Sum(Iif([Type]='수입', [Value], -[Value]))";
            valueTotalField.UnboundType           = UnboundColumnType.Decimal;
            valueTotalField.UnboundExpressionMode = UnboundExpressionMode.UseAggregateFunctions;
        }

        #endregion
        #region 레거시 접근법 사용하기 - UseLegacyApproach()

        /// <summary>
        /// 레거시 접근법 사용하기
        /// </summary>
        private void UseLegacyApproach()
        {
            this.pivotGridControl.Fields["Value"].SummaryType = PivotSummaryType.Custom;

            this.pivotGridControl.CustomSummary += pivotGridControl_CustomSummary;
        }

        #endregion
        #region 커스텀 SUMMARY 접근법 선택하기 - SelectCustomSummaryApproach(processingEngine)

        /// <summary>
        /// 커스텀 SUMMARY 접근법 선택하기
        /// </summary>
        /// <param name="processingEngine">피벗 데이터 처리 엔진</param>
        private void SelectCustomSummaryApproach(PivotDataProcessingEngine processingEngine)
        {
            switch(processingEngine)
            {
                case PivotDataProcessingEngine.Optimized       : UseOptimizedApproach();         break;
                case PivotDataProcessingEngine.LegacyOptimized : UseUnboundExpressionApproach(); break;
                default                                        : UseLegacyApproach();            break;
            }
        }

        #endregion
    }
}
728x90
반응형
그리드형

'DevExpress > WinForm' 카테고리의 다른 글

[DEVEXPRESS/WINFORM] PivotGridField 클래스 : RunningTotal 속성을 사용해 누계 사용하기  (0) 2020.05.05
[DEVEXPRESS/WINFORM] PivotGridField 클래스 : CustomTotals 속성을 사용해 커스텀 총계 사용하기  (0) 2020.05.05
[DEVEXPRESS/WINFORM] PivotGridControl 클래스 : CreateDrillDownDataSource 메소드를 사용해 기본 데이터 구하기  (0) 2020.05.05
[DEVEXPRESS/WINFORM] PivotGridControl 클래스 : CustomSummary 이벤트를 사용해 커스텀 SUMMARY 사용하기  (0) 2020.05.05
[DEVEXPRESS/WINFORM] GridControl 클래스 : 데이터 주석 어트리뷰트를 갖는 데이터 소스 바인딩하기  (0) 2020.05.05
[DEVEXPRESS/WINFORM] PivotGridControl 클래스 : 커스텀 SUMMARY 계산하기  (0) 2020.05.04
[DEVEXPRESS/WINFORM] PivotGridControl 클래스 : SavePivotGridToFile 메소드를 사용해 지역 데이터 저장소 생성하기  (0) 2020.05.04
[DEVEXPRESS/WINFORM] PivotGridControl 클래스 : CustomUnboundFieldData 이벤트를 사용해 언바운드 필드 데이터 커스텀 설정하기  (0) 2020.05.03
[DEVEXPRESS/WINFORM] PivotGridField 클래스 : UnboundExpression 속성을 사용해 언바운드 필드 생성하기  (0) 2020.05.03
[DEVEXPRESS/WINFORM] PivotGridControl 클래스 : RetrieveFields 메소드를 사용해 필드 가져오기  (0) 2020.05.03
[DEVEXPRESS/WINFORM] PropertyGridControl 클래스 : CustomPropertyDescriptors 이벤트를 사용해 속성 정렬하기  (0) 2020.05.03
Posted by 사용자 icodebroker

댓글을 달아 주세요