diff options
-rw-r--r-- | calc.go | 48 | ||||
-rw-r--r-- | calc_test.go | 10 |
2 files changed, 56 insertions, 2 deletions
@@ -433,6 +433,8 @@ type formulaFuncs struct { // DELTA // DEVSQ // DISC +// DMAX +// DMIN // DOLLARDE // DOLLARFR // DURATION @@ -18098,7 +18100,7 @@ func (fn *formulaFuncs) dcount(name string, argsList *list.List) formulaArg { return newNumberFormulaArg(count) } -// DOUNT function returns the number of cells containing numeric values, in a +// DCOUNT function returns the number of cells containing numeric values, in a // field (column) of a database for selected records only. The records to be // included in the count are those that satisfy a set of one or more // user-specified criteria. The syntax of the function is: @@ -18119,3 +18121,47 @@ func (fn *formulaFuncs) DCOUNT(argsList *list.List) formulaArg { func (fn *formulaFuncs) DCOUNTA(argsList *list.List) formulaArg { return fn.dcount("DCOUNTA", argsList) } + +// dmaxmin is an implementation of the formula functions DMAX and DMIN. +func (fn *formulaFuncs) dmaxmin(name string, argsList *list.List) formulaArg { + if argsList.Len() != 3 { + return newErrorFormulaArg(formulaErrorVALUE, fmt.Sprintf("%s requires 3 arguments", name)) + } + database := argsList.Front().Value.(formulaArg) + field := argsList.Front().Next().Value.(formulaArg) + criteria := argsList.Back().Value.(formulaArg) + db := newCalcDatabase(database, field, criteria) + if db == nil { + return newErrorFormulaArg(formulaErrorVALUE, formulaErrorVALUE) + } + args := list.New() + for db.next() { + args.PushBack(db.value()) + } + if name == "DMAX" { + return fn.MAX(args) + } + return fn.MIN(args) +} + +// DMAX function finds the maximum value in a field (column) in a database for +// selected records only. The records to be included in the calculation are +// defined by a set of one or more user-specified criteria. The syntax of the +// function is: +// +// DMAX(database,field,criteria) +// +func (fn *formulaFuncs) DMAX(argsList *list.List) formulaArg { + return fn.dmaxmin("DMAX", argsList) +} + +// DMIN function finds the minimum value in a field (column) in a database for +// selected records only. The records to be included in the calculation are +// defined by a set of one or more user-specified criteria. The syntax of the +// function is: +// +// DMIN(database,field,criteria) +// +func (fn *formulaFuncs) DMIN(argsList *list.List) formulaArg { + return fn.dmaxmin("DMIN", argsList) +} diff --git a/calc_test.go b/calc_test.go index 7cf9e48..089bfd3 100644 --- a/calc_test.go +++ b/calc_test.go @@ -4603,7 +4603,7 @@ func TestCalcCOVAR(t *testing.T) { } } -func TestCalcDCOUNTandDCOUNTA(t *testing.T) { +func TestCalcDCOUNTandDCOUNTAandDMAXandDMIN(t *testing.T) { cellData := [][]interface{}{ {"Tree", "Height", "Age", "Yield", "Profit", "Height"}, {"=Apple", ">1000%", nil, nil, nil, "<16"}, @@ -4631,6 +4631,10 @@ func TestCalcDCOUNTandDCOUNTA(t *testing.T) { "=DCOUNTA(A4:E10,\"Profit\",A1:F2)": "2", "=DCOUNTA(A4:E10,\"Tree\",A1:F2)": "2", "=DCOUNTA(A4:E10,\"Age\",A2:F3)": "0", + "=DMAX(A4:E10,\"Tree\",A1:F3)": "0", + "=DMAX(A4:E10,\"Profit\",A1:F3)": "96", + "=DMIN(A4:E10,\"Tree\",A1:F3)": "0", + "=DMIN(A4:E10,\"Profit\",A1:F3)": "45", } for formula, expected := range formulaList { assert.NoError(t, f.SetCellFormula("Sheet1", "A11", formula)) @@ -4651,6 +4655,10 @@ func TestCalcDCOUNTandDCOUNTA(t *testing.T) { "=DCOUNTA(A4:E10,NA(),A1:F2)": "#VALUE!", "=DCOUNTA(A4:E4,,A1:F2)": "#VALUE!", "=DCOUNTA(A4:E10,\"x\",A2:F3)": "#VALUE!", + "=DMAX()": "DMAX requires 3 arguments", + "=DMAX(A4:E10,\"x\",A1:F3)": "#VALUE!", + "=DMIN()": "DMIN requires 3 arguments", + "=DMIN(A4:E10,\"x\",A1:F3)": "#VALUE!", } for formula, expected := range calcError { assert.NoError(t, f.SetCellFormula("Sheet1", "A11", formula)) |