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() | 
