示例#1
0
        public void CalculateEmptyValuesTest()
        {
            var totalFunctionHelper = new TotalsFunctionHelper();
            var result = totalFunctionHelper.Calculate(OfficeOpenXml.Table.PivotTable.DataFieldFunctions.Average, new List <object>());

            Assert.IsNull(result);
        }
示例#2
0
        public void CalculateStdDevDataFieldFunctionTest()
        {
            var totalFunctionHelper = new TotalsFunctionHelper();
            var values = new List <object>()
            {
                5, 2, 1, 6, 10, 22, 7
            };
            var result = totalFunctionHelper.Calculate(OfficeOpenXml.Table.PivotTable.DataFieldFunctions.StdDev, values);

            Assert.AreEqual(7.044078905, Math.Round((double)result, 9));
        }
示例#3
0
        public void CalculateProductDataFieldFunctionTest()
        {
            var totalFunctionHelper = new TotalsFunctionHelper();
            var values = new List <object>()
            {
                5, 2, 1, 6, 10, 22, 7
            };
            var result = totalFunctionHelper.Calculate(OfficeOpenXml.Table.PivotTable.DataFieldFunctions.Product, values);

            Assert.AreEqual(92400, (double)result);
        }
示例#4
0
 public void GetTokenNameValuesNullFormulaTest()
 {
     using (var helper = new TotalsFunctionHelper())
     {
         helper.AddNames(new HashSet <string> {
             "Count", "Item"
         });
         var tokens = helper.Tokenize(null);
         Assert.IsNull(tokens);
     }
 }
示例#5
0
        public void CalculateVarPDataFieldFunctionTest()
        {
            var totalFunctionHelper = new TotalsFunctionHelper();
            var values = new List <object>()
            {
                5, 2, 1, 6, 10, 22, 7
            };
            var result = totalFunctionHelper.Calculate(OfficeOpenXml.Table.PivotTable.DataFieldFunctions.VarP, values);

            Assert.AreEqual(42.53061224, Math.Round((double)result, 8));
        }
示例#6
0
 public void GetTokenNameValuesTest()
 {
     using (var helper = new TotalsFunctionHelper())
     {
         helper.AddNames(new HashSet <string> {
             "Cost", "Count"
         });
         var tokens = helper.Tokenize("Count*Cost");
         Assert.AreEqual("Count", tokens.ElementAt(0).Value);
         Assert.AreEqual("*", tokens.ElementAt(1).Value);
         Assert.AreEqual("Cost", tokens.ElementAt(2).Value);
     }
 }
示例#7
0
        /// <summary>
        /// Executes the GETPIVOTDATA function with the specified arguments.
        /// </summary>
        /// <param name="arguments">The arguments of the function to evaluate.</param>
        /// <param name="context">The context that the function is to be evaluated in.</param>
        /// <returns>The result of function evaluation as a <see cref="CompileResult"/>.</returns>
        public override CompileResult Execute(IEnumerable <FunctionArgument> arguments, ParsingContext context)
        {
            string fieldName         = arguments.ElementAt(0).Value?.ToString();
            var    pivotTableAddress = arguments.ElementAt(1).ValueAsRangeInfo?.Address;

            if (string.IsNullOrEmpty(fieldName) || pivotTableAddress == null)
            {
                return(new CompileResult(eErrorType.Ref));
            }
            var pivotTable = context.ExcelDataProvider.GetPivotTable(pivotTableAddress);

            if (pivotTable == null)
            {
                return(new CompileResult(eErrorType.Ref));
            }

            var fieldPairs = arguments.Skip(2).ToList();

            if (fieldPairs.Count % 2 == 1)
            {
                return(new CompileResult(eErrorType.Ref));
            }
            // Convert arguments 2...n into field/value pairs.
            var fieldValueIndices = this.ResolveFieldValuePairs(fieldPairs, pivotTable.CacheDefinition);

            int fieldIndex = this.GetFieldIndex(fieldName, pivotTable);

            // The field/value pairs or field was not found in the pivot table.
            if (fieldValueIndices == null || fieldIndex == -1)
            {
                return(new CompileResult(eErrorType.Ref));
            }

            using (var totalsCalculator = new TotalsFunctionHelper())
            {
                var pageFieldIndices = pivotTable.GetPageFieldIndices();
                var matchingValues   = pivotTable.CacheDefinition.CacheRecords.FindMatchingValues(fieldValueIndices, null, pageFieldIndices, fieldIndex);
                var dataField        = pivotTable.DataFields.FirstOrDefault(d => d.Index == fieldIndex);
                var subtotal         = totalsCalculator.Calculate(dataField.Function, matchingValues);
                if (subtotal == null)
                {
                    return(new CompileResult(eErrorType.Ref));
                }
                return(new CompileResult(subtotal, DataType.Decimal));
            }
        }
示例#8
0
 public void EvaluateCalculatedFieldFormulaNullValue()
 {
     using (var helper = new TotalsFunctionHelper())
     {
         var fieldValues = new Dictionary <string, List <object> >
         {
             { "Count", new List <object> {
                   1, 2, 3, 4
               } },
             { "Cost", new List <object> {
                   5, 6, 7, 8
               } }
         };
         helper.AddNames(new HashSet <string>(fieldValues.Keys));
         var result = helper.EvaluateCalculatedFieldFormula(fieldValues, null);
         Assert.AreEqual(null, result);
     }
 }
示例#9
0
        private double?GetCalculatedFieldTotal(PivotItemTreeNode node, ExcelPivotTable pivotTable, CacheFieldNode cacheField)
        {
            var totalsFunction   = new TotalsFunctionHelper();
            var calculatedFields = pivotTable.CacheDefinition.CacheFields.Where(f => !string.IsNullOrEmpty(f.Formula));

            PivotTableDataManager.ConfigureCalculatedFields(calculatedFields, totalsFunction, pivotTable);
            var fieldNameToValues = new Dictionary <string, List <object> >();

            foreach (var cacheFieldName in cacheField.ReferencedCacheFieldsToIndex.Keys)
            {
                var values = pivotTable.CacheDefinition.CacheRecords.GetChildDataFieldValues(node.CacheRecordIndices, cacheField.ReferencedCacheFieldsToIndex[cacheFieldName]);
                fieldNameToValues.Add(cacheFieldName, values);
            }
            var total = totalsFunction.EvaluateCalculatedFieldFormula(fieldNameToValues, cacheField.ResolvedFormula);

            if (double.TryParse(total.ToString(), out var result))
            {
                return(result);
            }
            return(null);
        }
示例#10
0
 public void GetTokenNameValuesWithFunctionTest()
 {
     using (var helper = new TotalsFunctionHelper())
     {
         helper.AddNames(new HashSet <string> {
             "Cost", "Count", "Item"
         });
         var tokens = helper.Tokenize("SUM(Count)*COUNT(Cost) - Item");
         Assert.AreEqual("SUM", tokens.ElementAt(0).Value);
         Assert.AreEqual("(", tokens.ElementAt(1).Value);
         Assert.AreEqual("Count", tokens.ElementAt(2).Value);
         Assert.AreEqual(")", tokens.ElementAt(3).Value);
         Assert.AreEqual("*", tokens.ElementAt(4).Value);
         Assert.AreEqual("COUNT", tokens.ElementAt(5).Value);
         Assert.AreEqual("(", tokens.ElementAt(6).Value);
         Assert.AreEqual("Cost", tokens.ElementAt(7).Value);
         Assert.AreEqual(")", tokens.ElementAt(8).Value);
         Assert.AreEqual("-", tokens.ElementAt(9).Value);
         Assert.AreEqual("Item", tokens.ElementAt(10).Value);
     }
 }
 /// <summary>
 /// Constructs the calculator.
 /// </summary>
 /// <param name="pivotTable">The pivot table to calculate against.</param>
 /// <param name="dataFieldCollectionIndex">The index of the data field that the calculator is calculating.</param>
 /// <param name="totalsCalculator">A <see cref="TotalsFunctionHelper"/> to calculate values with.</param>
 public PercentOfParentCalculatorBase(ExcelPivotTable pivotTable, int dataFieldCollectionIndex, TotalsFunctionHelper totalsCalculator)
     : base(pivotTable, dataFieldCollectionIndex, totalsCalculator)
 {
 }
示例#12
0
 /// <summary>
 /// Create a new <see cref="RowGrandTotalHelper"/> object.
 /// </summary>
 /// <param name="pivotTable">The <see cref="ExcelPivotTable"/>.</param>
 /// <param name="backingData">The data backing the pivot table.</param>
 /// <param name="totalsCalculator">The calculation helper.</param>
 internal RowGrandTotalHelper(ExcelPivotTable pivotTable, PivotCellBackingData[,] backingData, TotalsFunctionHelper totalsCalculator)
     : base(pivotTable, backingData, totalsCalculator)
 {
     this.MajorHeaderCollection = this.PivotTable.ColumnHeaders;
     this.MinorHeaderCollection = this.PivotTable.RowHeaders;
 }
示例#13
0
 /// <summary>
 /// Constructs the calculator.
 /// </summary>
 /// <param name="pivotTable">The pivot table to calculate against.</param>
 /// <param name="dataFieldCollectionIndex">The index of the data field that the calculator is calculating.</param>
 /// <param name="totalsCalculator">A <see cref="TotalsFunctionHelper"/> to calculate values with.</param>
 public NoCalculationCalcutor(ExcelPivotTable pivotTable, int dataFieldCollectionIndex, TotalsFunctionHelper totalsCalculator)
     : base(pivotTable, dataFieldCollectionIndex, totalsCalculator)
 {
 }
示例#14
0
        /// <summary>
        /// Factory method to get the appropriate class to calculate ShowDataAs values.
        /// </summary>
        /// <param name="showDataAs">The <see cref="ShowDataAs"/> type to get a calculator class for.</param>
        /// <param name="pivotTable">The pivot table that the calculator is calculating against.</param>
        /// <param name="dataFieldCollectionIndex">The index of the data field that the calculator is calculating.</param>
        /// <param name="totalsCalculator">The <see cref="TotalsFunctionHelper"/> to calculate totals.</param>
        /// <returns>The appropriate calculator class for the ShowDataAs value.</returns>
        public static ShowDataAsCalculatorBase GetShowDataAsCalculator(ShowDataAs showDataAs, ExcelPivotTable pivotTable, int dataFieldCollectionIndex, TotalsFunctionHelper totalsCalculator)
        {
            switch (showDataAs)
            {
            case ShowDataAs.NoCalculation:
                return(new NoCalculationCalcutor(pivotTable, dataFieldCollectionIndex, totalsCalculator));

            case ShowDataAs.PercentOfTotal:
                return(new PercentOfTotalCalculator(pivotTable, dataFieldCollectionIndex, totalsCalculator));

            case ShowDataAs.PercentOfRow:
                return(new PercentOfRowCalculator(pivotTable, dataFieldCollectionIndex, totalsCalculator));

            case ShowDataAs.PercentOfCol:
                return(new PercentOfColCalculator(pivotTable, dataFieldCollectionIndex, totalsCalculator));

            case ShowDataAs.Percent:
                return(new PercentOfCalculator(pivotTable, dataFieldCollectionIndex, totalsCalculator));

            case ShowDataAs.PercentOfParentRow:
                return(new PercentOfParentRowCalculator(pivotTable, dataFieldCollectionIndex, totalsCalculator));

            case ShowDataAs.PercentOfParentCol:
                return(new PercentOfParentColumnCalculator(pivotTable, dataFieldCollectionIndex, totalsCalculator));

            case ShowDataAs.PercentOfParent:
                return(new PercentOfParentCalculator(pivotTable, dataFieldCollectionIndex, totalsCalculator));

            case ShowDataAs.PercentDiff:
            case ShowDataAs.PercentOfRunningTotal:
            case ShowDataAs.RankAscending:
            case ShowDataAs.RankDescending:
            case ShowDataAs.RunTotal:
            case ShowDataAs.Index:
            case ShowDataAs.Difference:
                // TODO: Implement the rest of these settings. See user stories 11882..11890
                throw new InvalidOperationException($"Unsupported dataField ShowDataAs setting '{showDataAs}'");

            default:
                throw new InvalidOperationException($"Unknown dataField ShowDataAs setting '{showDataAs}'");
            }
        }
示例#15
0
 /// <summary>
 /// Base calculator constructor.
 /// </summary>
 /// <param name="pivotTable">The pivot table to calculate against.</param>
 /// <param name="dataFieldCollectionIndex">The index of the data field that the calculator is calculating.</param>
 public ShowDataAsCalculatorBase(ExcelPivotTable pivotTable, int dataFieldCollectionIndex, TotalsFunctionHelper totalsCalculator)
 {
     this.PivotTable = pivotTable;
     this.DataFieldCollectionIndex = dataFieldCollectionIndex;
     this.TotalsCalculator         = totalsCalculator;
 }