diff options
-rw-r--r-- | calc.go | 178 | ||||
-rw-r--r-- | calc_test.go | 43 |
2 files changed, 221 insertions, 0 deletions
@@ -2840,3 +2840,181 @@ func (fn *formulaFuncs) TRUNC(argsList *list.List) (result string, err error) { // Statistical functions // Information functions + +// ISBLANK function tests if a specified cell is blank (empty) and if so, +// returns TRUE; Otherwise the function returns FALSE. The syntax of the +// function is: +// +// ISBLANK(value) +// +func (fn *formulaFuncs) ISBLANK(argsList *list.List) (result string, err error) { + if argsList.Len() != 1 { + err = errors.New("ISBLANK requires 1 argument") + return + } + token := argsList.Front().Value.(formulaArg) + result = "FALSE" + switch token.Type { + case ArgUnknown: + result = "TRUE" + case ArgString: + if token.String == "" { + result = "TRUE" + } + } + return +} + +// ISERR function tests if an initial supplied expression (or value) returns +// any Excel Error, except the #N/A error. If so, the function returns the +// logical value TRUE; If the supplied value is not an error or is the #N/A +// error, the ISERR function returns FALSE. The syntax of the function is: +// +// ISERR(value) +// +func (fn *formulaFuncs) ISERR(argsList *list.List) (result string, err error) { + if argsList.Len() != 1 { + err = errors.New("ISERR requires 1 argument") + return + } + token := argsList.Front().Value.(formulaArg) + result = "FALSE" + if token.Type == ArgString { + for _, errType := range []string{formulaErrorDIV, formulaErrorNAME, formulaErrorNUM, formulaErrorVALUE, formulaErrorREF, formulaErrorNULL, formulaErrorSPILL, formulaErrorCALC, formulaErrorGETTINGDATA} { + if errType == token.String { + result = "TRUE" + } + } + } + return +} + +// ISERROR function tests if an initial supplied expression (or value) returns +// an Excel Error, and if so, returns the logical value TRUE; Otherwise the +// function returns FALSE. The syntax of the function is: +// +// ISERROR(value) +// +func (fn *formulaFuncs) ISERROR(argsList *list.List) (result string, err error) { + if argsList.Len() != 1 { + err = errors.New("ISERROR requires 1 argument") + return + } + token := argsList.Front().Value.(formulaArg) + result = "FALSE" + if token.Type == ArgString { + for _, errType := range []string{formulaErrorDIV, formulaErrorNAME, formulaErrorNA, formulaErrorNUM, formulaErrorVALUE, formulaErrorREF, formulaErrorNULL, formulaErrorSPILL, formulaErrorCALC, formulaErrorGETTINGDATA} { + if errType == token.String { + result = "TRUE" + } + } + } + return +} + +// ISEVEN function tests if a supplied number (or numeric expression) +// evaluates to an even number, and if so, returns TRUE; Otherwise, the +// function returns FALSE. The syntax of the function is: +// +// ISEVEN(value) +// +func (fn *formulaFuncs) ISEVEN(argsList *list.List) (result string, err error) { + if argsList.Len() != 1 { + err = errors.New("ISEVEN requires 1 argument") + return + } + token := argsList.Front().Value.(formulaArg) + result = "FALSE" + var numeric int + if token.Type == ArgString { + if numeric, err = strconv.Atoi(token.String); err != nil { + err = errors.New(formulaErrorVALUE) + return + } + if numeric == numeric/2*2 { + result = "TRUE" + return + } + } + return +} + +// ISNA function tests if an initial supplied expression (or value) returns +// the Excel #N/A Error, and if so, returns TRUE; Otherwise the function +// returns FALSE. The syntax of the function is: +// +// ISNA(value) +// +func (fn *formulaFuncs) ISNA(argsList *list.List) (result string, err error) { + if argsList.Len() != 1 { + err = errors.New("ISNA requires 1 argument") + return + } + token := argsList.Front().Value.(formulaArg) + result = "FALSE" + if token.Type == ArgString && token.String == formulaErrorNA { + result = "TRUE" + } + return +} + +// ISNONTEXT function function tests if a supplied value is text. If not, the +// function returns TRUE; If the supplied value is text, the function returns +// FALSE. The syntax of the function is: +// +// ISNONTEXT(value) +// +func (fn *formulaFuncs) ISNONTEXT(argsList *list.List) (result string, err error) { + if argsList.Len() != 1 { + err = errors.New("ISNONTEXT requires 1 argument") + return + } + token := argsList.Front().Value.(formulaArg) + result = "TRUE" + if token.Type == ArgString && token.String != "" { + result = "FALSE" + } + return +} + +// ISODD function tests if a supplied number (or numeric expression) evaluates +// to an odd number, and if so, returns TRUE; Otherwise, the function returns +// FALSE. The syntax of the function is: +// +// ISODD(value) +// +func (fn *formulaFuncs) ISODD(argsList *list.List) (result string, err error) { + if argsList.Len() != 1 { + err = errors.New("ISODD requires 1 argument") + return + } + token := argsList.Front().Value.(formulaArg) + result = "FALSE" + var numeric int + if token.Type == ArgString { + if numeric, err = strconv.Atoi(token.String); err != nil { + err = errors.New(formulaErrorVALUE) + return + } + if numeric != numeric/2*2 { + result = "TRUE" + return + } + } + return +} + +// NA function returns the Excel #N/A error. This error message has the +// meaning 'value not available' and is produced when an Excel Formula is +// unable to find a value that it needs. The syntax of the function is: +// +// NA() +// +func (fn *formulaFuncs) NA(argsList *list.List) (result string, err error) { + if argsList.Len() != 0 { + err = errors.New("NA accepts no arguments") + return + } + result = formulaErrorNA + return +} diff --git a/calc_test.go b/calc_test.go index 3639af7..4f2ca7b 100644 --- a/calc_test.go +++ b/calc_test.go @@ -384,6 +384,32 @@ func TestCalcCellValue(t *testing.T) { "=TRUNC(99.999,-1)": "90", "=TRUNC(-99.999,2)": "-99.99", "=TRUNC(-99.999,-1)": "-90", + // Information functions + // ISBLANK + "=ISBLANK(A1)": "FALSE", + "=ISBLANK(A5)": "TRUE", + // ISERR + "=ISERR(A1)": "FALSE", + "=ISERR(NA())": "FALSE", + // ISERROR + "=ISERROR(A1)": "FALSE", + "=ISERROR(NA())": "TRUE", + // ISEVEN + "=ISEVEN(A1)": "FALSE", + "=ISEVEN(A2)": "TRUE", + // ISNA + "=ISNA(A1)": "FALSE", + "=ISNA(NA())": "TRUE", + // ISNONTEXT + "=ISNONTEXT(A1)": "FALSE", + "=ISNONTEXT(A5)": "TRUE", + `=ISNONTEXT("Excelize")`: "FALSE", + "=ISNONTEXT(NA())": "FALSE", + // ISODD + "=ISODD(A1)": "TRUE", + "=ISODD(A2)": "FALSE", + // NA + "=NA()": "#N/A", } for formula, expected := range mathCalc { f := prepareData() @@ -659,6 +685,23 @@ func TestCalcCellValue(t *testing.T) { "=TRUNC()": "TRUNC requires at least 1 argument", `=TRUNC("X")`: "#VALUE!", `=TRUNC(1,"X")`: "#VALUE!", + // Information functions + // ISBLANK + "=ISBLANK(A1,A2)": "ISBLANK requires 1 argument", + // ISERR + "=ISERR()": "ISERR requires 1 argument", + // ISERROR + "=ISERROR()": "ISERROR requires 1 argument", + // ISEVEN + "=ISEVEN()": "ISEVEN requires 1 argument", + // ISNA + "=ISNA()": "ISNA requires 1 argument", + // ISNONTEXT + "=ISNONTEXT()": "ISNONTEXT requires 1 argument", + // ISODD + "=ISODD()": "ISODD requires 1 argument", + // NA + "=NA(1)": "NA accepts no arguments", } for formula, expected := range mathCalcError { f := prepareData() |