From d74adcbb159280be962918125d20ec8ac67a3f93 Mon Sep 17 00:00:00 2001 From: xuri Date: Sun, 3 Jul 2022 15:31:24 +0800 Subject: [PATCH] ref #65, new formula function: DGET --- calc.go | 27 +++++++++++++++++++++++++++ calc_test.go | 4 ++++ 2 files changed, 31 insertions(+) diff --git a/calc.go b/calc.go index 25c2e180..83885dc6 100644 --- a/calc.go +++ b/calc.go @@ -433,6 +433,7 @@ type formulaFuncs struct { // DEGREES // DELTA // DEVSQ +// DGET // DISC // DMAX // DMIN @@ -18173,6 +18174,32 @@ func (fn *formulaFuncs) DCOUNTA(argsList *list.List) formulaArg { return fn.dcount("DCOUNTA", argsList) } +// DGET function returns a single value from a column of a database. The record +// is selected via a set of one or more user-specified criteria. The syntax of +// the function is: +// +// DGET(database,field,criteria) +// +func (fn *formulaFuncs) DGET(argsList *list.List) formulaArg { + if argsList.Len() != 3 { + return newErrorFormulaArg(formulaErrorVALUE, "DGET requires 3 arguments") + } + 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) + } + value := newErrorFormulaArg(formulaErrorVALUE, formulaErrorVALUE) + if db.next() { + if value = db.value(); db.next() { + return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM) + } + } + return value +} + // 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 diff --git a/calc_test.go b/calc_test.go index 4436b608..b8efd619 100644 --- a/calc_test.go +++ b/calc_test.go @@ -4632,6 +4632,7 @@ func TestCalcDatabase(t *testing.T) { "=DCOUNTA(A4:E10,\"Profit\",A1:F2)": "2", "=DCOUNTA(A4:E10,\"Tree\",A1:F2)": "2", "=DCOUNTA(A4:E10,\"Age\",A2:F3)": "0", + "=DGET(A4:E6,\"Profit\",A1:F3)": "96", "=DMAX(A4:E10,\"Tree\",A1:F3)": "0", "=DMAX(A4:E10,\"Profit\",A1:F3)": "96", "=DMIN(A4:E10,\"Tree\",A1:F3)": "0", @@ -4665,6 +4666,9 @@ func TestCalcDatabase(t *testing.T) { "=DCOUNTA(A4:E10,NA(),A1:F2)": "#VALUE!", "=DCOUNTA(A4:E4,,A1:F2)": "#VALUE!", "=DCOUNTA(A4:E10,\"x\",A2:F3)": "#VALUE!", + "=DGET()": "DGET requires 3 arguments", + "=DGET(A4:E5,\"Profit\",A1:F3)": "#VALUE!", + "=DGET(A4:E10,\"Profit\",A1:F3)": "#NUM!", "=DMAX()": "DMAX requires 3 arguments", "=DMAX(A4:E10,\"x\",A1:F3)": "#VALUE!", "=DMIN()": "DMIN requires 3 arguments",