summaryrefslogtreecommitdiff
path: root/calc.go
diff options
context:
space:
mode:
Diffstat (limited to 'calc.go')
-rw-r--r--calc.go211
1 files changed, 143 insertions, 68 deletions
diff --git a/calc.go b/calc.go
index 7da2493..d2bab1d 100644
--- a/calc.go
+++ b/calc.go
@@ -24,6 +24,7 @@ import (
"strconv"
"strings"
"time"
+ "unicode"
"github.com/xuri/efp"
)
@@ -123,14 +124,15 @@ var tokenPriority = map[string]int{
// Supported formulas:
//
// ABS, ACOS, ACOSH, ACOT, ACOTH, AND, ARABIC, ASIN, ASINH, ATAN2, ATANH,
-// BASE, CEILING, CEILING.MATH, CEILING.PRECISE, COMBIN, COMBINA, COS,
-// COSH, COT, COTH, COUNTA, CSC, CSCH, DATE, DECIMAL, DEGREES, EVEN, EXP,
-// FACT, FACTDOUBLE, FLOOR, FLOOR.MATH, FLOOR.PRECISE, GCD, INT, ISBLANK,
-// ISERR, ISERROR, ISEVEN, ISNA, ISNONTEXT, ISNUMBER, ISO.CEILING, ISODD,
-// LCM, LN, LOG, LOG10, MDETERM, MEDIAN, MOD, MROUND, MULTINOMIAL, MUNIT,
-// NA, ODD, OR, PI, POWER, PRODUCT, QUOTIENT, RADIANS, RAND, RANDBETWEEN,
-// ROUND, ROUNDDOWN, ROUNDUP, SEC, SECH, SIGN, SIN, SINH, SQRT, SQRTPI,
-// SUM, SUMIF, SUMSQ, TAN, TANH, TRUNC
+// BASE, CEILING, CEILING.MATH, CEILING.PRECISE, CLEAN, COMBIN, COMBINA,
+// COS, COSH, COT, COTH, COUNTA, CSC, CSCH, DATE, DECIMAL, DEGREES, EVEN,
+// EXP, FACT, FACTDOUBLE, FLOOR, FLOOR.MATH, FLOOR.PRECISE, GCD, INT,
+// ISBLANK, ISERR, ISERROR, ISEVEN, ISNA, ISNONTEXT, ISNUMBER, ISO.CEILING,
+// ISODD, LCM, LN, LOG, LOG10, LOWER, MDETERM, MEDIAN, MOD, MROUND,
+// MULTINOMIAL, MUNIT, NA, ODD, OR, PI, POWER, PRODUCT, PROPER, QUOTIENT,
+// RADIANS, RAND, RANDBETWEEN, ROUND, ROUNDDOWN, ROUNDUP, SEC, SECH, SIGN,
+// SIN, SINH, SQRT, SQRTPI, SUM, SUMIF, SUMSQ, TAN, TANH, TRIM, TRUNC,
+// UPPER
//
func (f *File) CalcCellValue(sheet, cell string) (result string, err error) {
var (
@@ -869,7 +871,7 @@ func formulaCriteriaEval(val string, criteria *formulaCriteria) (result bool, er
// ABS function returns the absolute value of any supplied number. The syntax
// of the function is:
//
-// ABS(number)
+// ABS(number)
//
func (fn *formulaFuncs) ABS(argsList *list.List) (result string, err error) {
if argsList.Len() != 1 {
@@ -889,7 +891,7 @@ func (fn *formulaFuncs) ABS(argsList *list.List) (result string, err error) {
// number, and returns an angle, in radians, between 0 and π. The syntax of
// the function is:
//
-// ACOS(number)
+// ACOS(number)
//
func (fn *formulaFuncs) ACOS(argsList *list.List) (result string, err error) {
if argsList.Len() != 1 {
@@ -908,7 +910,7 @@ func (fn *formulaFuncs) ACOS(argsList *list.List) (result string, err error) {
// ACOSH function calculates the inverse hyperbolic cosine of a supplied number.
// of the function is:
//
-// ACOSH(number)
+// ACOSH(number)
//
func (fn *formulaFuncs) ACOSH(argsList *list.List) (result string, err error) {
if argsList.Len() != 1 {
@@ -928,7 +930,7 @@ func (fn *formulaFuncs) ACOSH(argsList *list.List) (result string, err error) {
// given number, and returns an angle, in radians, between 0 and π. The syntax
// of the function is:
//
-// ACOT(number)
+// ACOT(number)
//
func (fn *formulaFuncs) ACOT(argsList *list.List) (result string, err error) {
if argsList.Len() != 1 {
@@ -947,7 +949,7 @@ func (fn *formulaFuncs) ACOT(argsList *list.List) (result string, err error) {
// ACOTH function calculates the hyperbolic arccotangent (coth) of a supplied
// value. The syntax of the function is:
//
-// ACOTH(number)
+// ACOTH(number)
//
func (fn *formulaFuncs) ACOTH(argsList *list.List) (result string, err error) {
if argsList.Len() != 1 {
@@ -966,7 +968,7 @@ func (fn *formulaFuncs) ACOTH(argsList *list.List) (result string, err error) {
// ARABIC function converts a Roman numeral into an Arabic numeral. The syntax
// of the function is:
//
-// ARABIC(text)
+// ARABIC(text)
//
func (fn *formulaFuncs) ARABIC(argsList *list.List) (result string, err error) {
if argsList.Len() != 1 {
@@ -1004,7 +1006,7 @@ func (fn *formulaFuncs) ARABIC(argsList *list.List) (result string, err error) {
// number, and returns an angle, in radians, between -π/2 and π/2. The syntax
// of the function is:
//
-// ASIN(number)
+// ASIN(number)
//
func (fn *formulaFuncs) ASIN(argsList *list.List) (result string, err error) {
if argsList.Len() != 1 {
@@ -1023,7 +1025,7 @@ func (fn *formulaFuncs) ASIN(argsList *list.List) (result string, err error) {
// ASINH function calculates the inverse hyperbolic sine of a supplied number.
// The syntax of the function is:
//
-// ASINH(number)
+// ASINH(number)
//
func (fn *formulaFuncs) ASINH(argsList *list.List) (result string, err error) {
if argsList.Len() != 1 {
@@ -1043,7 +1045,7 @@ func (fn *formulaFuncs) ASINH(argsList *list.List) (result string, err error) {
// given number, and returns an angle, in radians, between -π/2 and +π/2. The
// syntax of the function is:
//
-// ATAN(number)
+// ATAN(number)
//
func (fn *formulaFuncs) ATAN(argsList *list.List) (result string, err error) {
if argsList.Len() != 1 {
@@ -1062,7 +1064,7 @@ func (fn *formulaFuncs) ATAN(argsList *list.List) (result string, err error) {
// ATANH function calculates the inverse hyperbolic tangent of a supplied
// number. The syntax of the function is:
//
-// ATANH(number)
+// ATANH(number)
//
func (fn *formulaFuncs) ATANH(argsList *list.List) (result string, err error) {
if argsList.Len() != 1 {
@@ -1082,7 +1084,7 @@ func (fn *formulaFuncs) ATANH(argsList *list.List) (result string, err error) {
// given set of x and y coordinates, and returns an angle, in radians, between
// -π/2 and +π/2. The syntax of the function is:
//
-// ATAN2(x_num,y_num)
+// ATAN2(x_num,y_num)
//
func (fn *formulaFuncs) ATAN2(argsList *list.List) (result string, err error) {
if argsList.Len() != 2 {
@@ -1105,7 +1107,7 @@ func (fn *formulaFuncs) ATAN2(argsList *list.List) (result string, err error) {
// BASE function converts a number into a supplied base (radix), and returns a
// text representation of the calculated value. The syntax of the function is:
//
-// BASE(number,radix,[min_length])
+// BASE(number,radix,[min_length])
//
func (fn *formulaFuncs) BASE(argsList *list.List) (result string, err error) {
if argsList.Len() < 2 {
@@ -1147,7 +1149,7 @@ func (fn *formulaFuncs) BASE(argsList *list.List) (result string, err error) {
// CEILING function rounds a supplied number away from zero, to the nearest
// multiple of a given number. The syntax of the function is:
//
-// CEILING(number,significance)
+// CEILING(number,significance)
//
func (fn *formulaFuncs) CEILING(argsList *list.List) (result string, err error) {
if argsList.Len() == 0 {
@@ -1191,7 +1193,7 @@ func (fn *formulaFuncs) CEILING(argsList *list.List) (result string, err error)
// CEILINGMATH function rounds a supplied number up to a supplied multiple of
// significance. The syntax of the function is:
//
-// CEILING.MATH(number,[significance],[mode])
+// CEILING.MATH(number,[significance],[mode])
//
func (fn *formulaFuncs) CEILINGMATH(argsList *list.List) (result string, err error) {
if argsList.Len() == 0 {
@@ -1242,7 +1244,7 @@ func (fn *formulaFuncs) CEILINGMATH(argsList *list.List) (result string, err err
// number's sign), to the nearest multiple of a given number. The syntax of
// the function is:
//
-// CEILING.PRECISE(number,[significance])
+// CEILING.PRECISE(number,[significance])
//
func (fn *formulaFuncs) CEILINGPRECISE(argsList *list.List) (result string, err error) {
if argsList.Len() == 0 {
@@ -1289,7 +1291,7 @@ func (fn *formulaFuncs) CEILINGPRECISE(argsList *list.List) (result string, err
// COMBIN function calculates the number of combinations (in any order) of a
// given number objects from a set. The syntax of the function is:
//
-// COMBIN(number,number_chosen)
+// COMBIN(number,number_chosen)
//
func (fn *formulaFuncs) COMBIN(argsList *list.List) (result string, err error) {
if argsList.Len() != 2 {
@@ -1324,7 +1326,7 @@ func (fn *formulaFuncs) COMBIN(argsList *list.List) (result string, err error) {
// COMBINA function calculates the number of combinations, with repetitions,
// of a given number objects from a set. The syntax of the function is:
//
-// COMBINA(number,number_chosen)
+// COMBINA(number,number_chosen)
//
func (fn *formulaFuncs) COMBINA(argsList *list.List) (result string, err error) {
if argsList.Len() != 2 {
@@ -1364,7 +1366,7 @@ func (fn *formulaFuncs) COMBINA(argsList *list.List) (result string, err error)
// COS function calculates the cosine of a given angle. The syntax of the
// function is:
//
-// COS(number)
+// COS(number)
//
func (fn *formulaFuncs) COS(argsList *list.List) (result string, err error) {
if argsList.Len() != 1 {
@@ -1383,7 +1385,7 @@ func (fn *formulaFuncs) COS(argsList *list.List) (result string, err error) {
// COSH function calculates the hyperbolic cosine (cosh) of a supplied number.
// The syntax of the function is:
//
-// COSH(number)
+// COSH(number)
//
func (fn *formulaFuncs) COSH(argsList *list.List) (result string, err error) {
if argsList.Len() != 1 {
@@ -1402,7 +1404,7 @@ func (fn *formulaFuncs) COSH(argsList *list.List) (result string, err error) {
// COT function calculates the cotangent of a given angle. The syntax of the
// function is:
//
-// COT(number)
+// COT(number)
//
func (fn *formulaFuncs) COT(argsList *list.List) (result string, err error) {
if argsList.Len() != 1 {
@@ -1425,7 +1427,7 @@ func (fn *formulaFuncs) COT(argsList *list.List) (result string, err error) {
// COTH function calculates the hyperbolic cotangent (coth) of a supplied
// angle. The syntax of the function is:
//
-// COTH(number)
+// COTH(number)
//
func (fn *formulaFuncs) COTH(argsList *list.List) (result string, err error) {
if argsList.Len() != 1 {
@@ -1448,7 +1450,7 @@ func (fn *formulaFuncs) COTH(argsList *list.List) (result string, err error) {
// CSC function calculates the cosecant of a given angle. The syntax of the
// function is:
//
-// CSC(number)
+// CSC(number)
//
func (fn *formulaFuncs) CSC(argsList *list.List) (result string, err error) {
if argsList.Len() != 1 {
@@ -1471,7 +1473,7 @@ func (fn *formulaFuncs) CSC(argsList *list.List) (result string, err error) {
// CSCH function calculates the hyperbolic cosecant (csch) of a supplied
// angle. The syntax of the function is:
//
-// CSCH(number)
+// CSCH(number)
//
func (fn *formulaFuncs) CSCH(argsList *list.List) (result string, err error) {
if argsList.Len() != 1 {
@@ -1494,7 +1496,7 @@ func (fn *formulaFuncs) CSCH(argsList *list.List) (result string, err error) {
// DECIMAL function converts a text representation of a number in a specified
// base, into a decimal value. The syntax of the function is:
//
-// DECIMAL(text,radix)
+// DECIMAL(text,radix)
//
func (fn *formulaFuncs) DECIMAL(argsList *list.List) (result string, err error) {
if argsList.Len() != 2 {
@@ -1522,7 +1524,7 @@ func (fn *formulaFuncs) DECIMAL(argsList *list.List) (result string, err error)
// DEGREES function converts radians into degrees. The syntax of the function
// is:
//
-// DEGREES(angle)
+// DEGREES(angle)
//
func (fn *formulaFuncs) DEGREES(argsList *list.List) (result string, err error) {
if argsList.Len() != 1 {
@@ -1546,7 +1548,7 @@ func (fn *formulaFuncs) DEGREES(argsList *list.List) (result string, err error)
// positive number up and a negative number down), to the next even number.
// The syntax of the function is:
//
-// EVEN(number)
+// EVEN(number)
//
func (fn *formulaFuncs) EVEN(argsList *list.List) (result string, err error) {
if argsList.Len() != 1 {
@@ -1575,7 +1577,7 @@ func (fn *formulaFuncs) EVEN(argsList *list.List) (result string, err error) {
// EXP function calculates the value of the mathematical constant e, raised to
// the power of a given number. The syntax of the function is:
//
-// EXP(number)
+// EXP(number)
//
func (fn *formulaFuncs) EXP(argsList *list.List) (result string, err error) {
if argsList.Len() != 1 {
@@ -1603,7 +1605,7 @@ func fact(number float64) float64 {
// FACT function returns the factorial of a supplied number. The syntax of the
// function is:
//
-// FACT(number)
+// FACT(number)
//
func (fn *formulaFuncs) FACT(argsList *list.List) (result string, err error) {
if argsList.Len() != 1 {
@@ -1625,7 +1627,7 @@ func (fn *formulaFuncs) FACT(argsList *list.List) (result string, err error) {
// FACTDOUBLE function returns the double factorial of a supplied number. The
// syntax of the function is:
//
-// FACTDOUBLE(number)
+// FACTDOUBLE(number)
//
func (fn *formulaFuncs) FACTDOUBLE(argsList *list.List) (result string, err error) {
if argsList.Len() != 1 {
@@ -1651,7 +1653,7 @@ func (fn *formulaFuncs) FACTDOUBLE(argsList *list.List) (result string, err erro
// FLOOR function rounds a supplied number towards zero to the nearest
// multiple of a specified significance. The syntax of the function is:
//
-// FLOOR(number,significance)
+// FLOOR(number,significance)
//
func (fn *formulaFuncs) FLOOR(argsList *list.List) (result string, err error) {
if argsList.Len() != 2 {
@@ -1685,7 +1687,7 @@ func (fn *formulaFuncs) FLOOR(argsList *list.List) (result string, err error) {
// FLOORMATH function rounds a supplied number down to a supplied multiple of
// significance. The syntax of the function is:
//
-// FLOOR.MATH(number,[significance],[mode])
+// FLOOR.MATH(number,[significance],[mode])
//
func (fn *formulaFuncs) FLOORMATH(argsList *list.List) (result string, err error) {
if argsList.Len() == 0 {
@@ -1731,7 +1733,7 @@ func (fn *formulaFuncs) FLOORMATH(argsList *list.List) (result string, err error
// FLOORPRECISE function rounds a supplied number down to a supplied multiple
// of significance. The syntax of the function is:
//
-// FLOOR.PRECISE(number,[significance])
+// FLOOR.PRECISE(number,[significance])
//
func (fn *formulaFuncs) FLOORPRECISE(argsList *list.List) (result string, err error) {
if argsList.Len() == 0 {
@@ -1797,7 +1799,7 @@ func gcd(x, y float64) float64 {
// GCD function returns the greatest common divisor of two or more supplied
// integers. The syntax of the function is:
//
-// GCD(number1,[number2],...)
+// GCD(number1,[number2],...)
//
func (fn *formulaFuncs) GCD(argsList *list.List) (result string, err error) {
if argsList.Len() == 0 {
@@ -1842,7 +1844,7 @@ func (fn *formulaFuncs) GCD(argsList *list.List) (result string, err error) {
// INT function truncates a supplied number down to the closest integer. The
// syntax of the function is:
//
-// INT(number)
+// INT(number)
//
func (fn *formulaFuncs) INT(argsList *list.List) (result string, err error) {
if argsList.Len() != 1 {
@@ -1866,7 +1868,7 @@ func (fn *formulaFuncs) INT(argsList *list.List) (result string, err error) {
// sign), to the nearest multiple of a supplied significance. The syntax of
// the function is:
//
-// ISO.CEILING(number,[significance])
+// ISO.CEILING(number,[significance])
//
func (fn *formulaFuncs) ISOCEILING(argsList *list.List) (result string, err error) {
if argsList.Len() == 0 {
@@ -1923,7 +1925,7 @@ func lcm(a, b float64) float64 {
// LCM function returns the least common multiple of two or more supplied
// integers. The syntax of the function is:
//
-// LCM(number1,[number2],...)
+// LCM(number1,[number2],...)
//
func (fn *formulaFuncs) LCM(argsList *list.List) (result string, err error) {
if argsList.Len() == 0 {
@@ -1968,7 +1970,7 @@ func (fn *formulaFuncs) LCM(argsList *list.List) (result string, err error) {
// LN function calculates the natural logarithm of a given number. The syntax
// of the function is:
//
-// LN(number)
+// LN(number)
//
func (fn *formulaFuncs) LN(argsList *list.List) (result string, err error) {
if argsList.Len() != 1 {
@@ -1987,7 +1989,7 @@ func (fn *formulaFuncs) LN(argsList *list.List) (result string, err error) {
// LOG function calculates the logarithm of a given number, to a supplied
// base. The syntax of the function is:
//
-// LOG(number,[base])
+// LOG(number,[base])
//
func (fn *formulaFuncs) LOG(argsList *list.List) (result string, err error) {
if argsList.Len() == 0 {
@@ -2028,7 +2030,7 @@ func (fn *formulaFuncs) LOG(argsList *list.List) (result string, err error) {
// LOG10 function calculates the base 10 logarithm of a given number. The
// syntax of the function is:
//
-// LOG10(number)
+// LOG10(number)
//
func (fn *formulaFuncs) LOG10(argsList *list.List) (result string, err error) {
if argsList.Len() != 1 {
@@ -2082,7 +2084,7 @@ func det(sqMtx [][]float64) float64 {
// MDETERM calculates the determinant of a square matrix. The
// syntax of the function is:
//
-// MDETERM(array)
+// MDETERM(array)
//
func (fn *formulaFuncs) MDETERM(argsList *list.List) (result string, err error) {
var num float64
@@ -2113,7 +2115,7 @@ func (fn *formulaFuncs) MDETERM(argsList *list.List) (result string, err error)
// MOD function returns the remainder of a division between two supplied
// numbers. The syntax of the function is:
//
-// MOD(number,divisor)
+// MOD(number,divisor)
//
func (fn *formulaFuncs) MOD(argsList *list.List) (result string, err error) {
if argsList.Len() != 2 {
@@ -2144,7 +2146,7 @@ func (fn *formulaFuncs) MOD(argsList *list.List) (result string, err error) {
// MROUND function rounds a supplied number up or down to the nearest multiple
// of a given number. The syntax of the function is:
//
-// MOD(number,multiple)
+// MROUND(number,multiple)
//
func (fn *formulaFuncs) MROUND(argsList *list.List) (result string, err error) {
if argsList.Len() != 2 {
@@ -2852,7 +2854,7 @@ func (fn *formulaFuncs) SUMIF(argsList *list.List) (result string, err error) {
// SUMSQ function returns the sum of squares of a supplied set of values. The
// syntax of the function is:
//
-// SUMSQ(number1,[number2],...)
+// SUMSQ(number1,[number2],...)
//
func (fn *formulaFuncs) SUMSQ(argsList *list.List) (result string, err error) {
var val, sq float64
@@ -2928,7 +2930,7 @@ func (fn *formulaFuncs) TANH(argsList *list.List) (result string, err error) {
// TRUNC function truncates a supplied number to a specified number of decimal
// places. The syntax of the function is:
//
-// TRUNC(number,[number_digits])
+// TRUNC(number,[number_digits])
//
func (fn *formulaFuncs) TRUNC(argsList *list.List) (result string, err error) {
if argsList.Len() == 0 {
@@ -2967,7 +2969,7 @@ func (fn *formulaFuncs) TRUNC(argsList *list.List) (result string, err error) {
// COUNTA function returns the number of non-blanks within a supplied set of
// cells or values. The syntax of the function is:
//
-// COUNTA(value1,[value2],...)
+// COUNTA(value1,[value2],...)
//
func (fn *formulaFuncs) COUNTA(argsList *list.List) (result string, err error) {
var count int
@@ -2995,7 +2997,7 @@ func (fn *formulaFuncs) COUNTA(argsList *list.List) (result string, err error) {
// MEDIAN function returns the statistical median (the middle value) of a list
// of supplied numbers. The syntax of the function is:
//
-// MEDIAN(number1,[number2],...)
+// MEDIAN(number1,[number2],...)
//
func (fn *formulaFuncs) MEDIAN(argsList *list.List) (result string, err error) {
if argsList.Len() == 0 {
@@ -3044,7 +3046,7 @@ func (fn *formulaFuncs) MEDIAN(argsList *list.List) (result string, err error) {
// returns TRUE; Otherwise the function returns FALSE. The syntax of the
// function is:
//
-// ISBLANK(value)
+// ISBLANK(value)
//
func (fn *formulaFuncs) ISBLANK(argsList *list.List) (result string, err error) {
if argsList.Len() != 1 {
@@ -3069,7 +3071,7 @@ func (fn *formulaFuncs) ISBLANK(argsList *list.List) (result string, err error)
// 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)
+// ISERR(value)
//
func (fn *formulaFuncs) ISERR(argsList *list.List) (result string, err error) {
if argsList.Len() != 1 {
@@ -3092,7 +3094,7 @@ func (fn *formulaFuncs) ISERR(argsList *list.List) (result string, err error) {
// an Excel Error, and if so, returns the logical value TRUE; Otherwise the
// function returns FALSE. The syntax of the function is:
//
-// ISERROR(value)
+// ISERROR(value)
//
func (fn *formulaFuncs) ISERROR(argsList *list.List) (result string, err error) {
if argsList.Len() != 1 {
@@ -3115,7 +3117,7 @@ func (fn *formulaFuncs) ISERROR(argsList *list.List) (result string, err error)
// evaluates to an even number, and if so, returns TRUE; Otherwise, the
// function returns FALSE. The syntax of the function is:
//
-// ISEVEN(value)
+// ISEVEN(value)
//
func (fn *formulaFuncs) ISEVEN(argsList *list.List) (result string, err error) {
if argsList.Len() != 1 {
@@ -3142,7 +3144,7 @@ func (fn *formulaFuncs) ISEVEN(argsList *list.List) (result string, err error) {
// the Excel #N/A Error, and if so, returns TRUE; Otherwise the function
// returns FALSE. The syntax of the function is:
//
-// ISNA(value)
+// ISNA(value)
//
func (fn *formulaFuncs) ISNA(argsList *list.List) (result string, err error) {
if argsList.Len() != 1 {
@@ -3161,7 +3163,7 @@ func (fn *formulaFuncs) ISNA(argsList *list.List) (result string, err error) {
// function returns TRUE; If the supplied value is text, the function returns
// FALSE. The syntax of the function is:
//
-// ISNONTEXT(value)
+// ISNONTEXT(value)
//
func (fn *formulaFuncs) ISNONTEXT(argsList *list.List) (result string, err error) {
if argsList.Len() != 1 {
@@ -3180,7 +3182,7 @@ func (fn *formulaFuncs) ISNONTEXT(argsList *list.List) (result string, err error
// the function returns TRUE; Otherwise it returns FALSE. The syntax of the
// function is:
//
-// ISNUMBER(value)
+// ISNUMBER(value)
//
func (fn *formulaFuncs) ISNUMBER(argsList *list.List) (result string, err error) {
if argsList.Len() != 1 {
@@ -3202,7 +3204,7 @@ func (fn *formulaFuncs) ISNUMBER(argsList *list.List) (result string, err error)
// to an odd number, and if so, returns TRUE; Otherwise, the function returns
// FALSE. The syntax of the function is:
//
-// ISODD(value)
+// ISODD(value)
//
func (fn *formulaFuncs) ISODD(argsList *list.List) (result string, err error) {
if argsList.Len() != 1 {
@@ -3229,7 +3231,7 @@ func (fn *formulaFuncs) ISODD(argsList *list.List) (result string, err error) {
// 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()
+// NA()
//
func (fn *formulaFuncs) NA(argsList *list.List) (result string, err error) {
if argsList.Len() != 0 {
@@ -3243,7 +3245,10 @@ func (fn *formulaFuncs) NA(argsList *list.List) (result string, err error) {
// Logical Functions
// AND function tests a number of supplied conditions and returns TRUE or
-// FALSE.
+// FALSE. The syntax of the function is:
+//
+// AND(logical_test1,[logical_test2],...)
+//
func (fn *formulaFuncs) AND(argsList *list.List) (result string, err error) {
if argsList.Len() == 0 {
err = errors.New("AND requires at least 1 argument")
@@ -3284,7 +3289,10 @@ func (fn *formulaFuncs) AND(argsList *list.List) (result string, err error) {
}
// OR function tests a number of supplied conditions and returns either TRUE
-// or FALSE.
+// or FALSE. The syntax of the function is:
+//
+// OR(logical_test1,[logical_test2],...)
+//
func (fn *formulaFuncs) OR(argsList *list.List) (result string, err error) {
if argsList.Len() == 0 {
err = errors.New("OR requires at least 1 argument")
@@ -3326,7 +3334,11 @@ func (fn *formulaFuncs) OR(argsList *list.List) (result string, err error) {
// Date and Time Functions
-// DATE returns a date, from a user-supplied year, month and day.
+// DATE returns a date, from a user-supplied year, month and day. The syntax
+// of the function is:
+//
+// DATE(year,month,day)
+//
func (fn *formulaFuncs) DATE(argsList *list.List) (result string, err error) {
if argsList.Len() != 3 {
err = errors.New("DATE requires 3 number arguments")
@@ -3368,7 +3380,11 @@ func daysBetween(startDate, endDate int64) float64 {
// Text Functions
-// CLEAN removes all non-printable characters from a supplied text string.
+// CLEAN removes all non-printable characters from a supplied text string. The
+// syntax of the function is:
+//
+// CLEAN(text)
+//
func (fn *formulaFuncs) CLEAN(argsList *list.List) (result string, err error) {
if argsList.Len() != 1 {
err = errors.New("CLEAN requires 1 argument")
@@ -3385,7 +3401,11 @@ func (fn *formulaFuncs) CLEAN(argsList *list.List) (result string, err error) {
}
// TRIM removes extra spaces (i.e. all spaces except for single spaces between
-// words or characters) from a supplied text string.
+// words or characters) from a supplied text string. The syntax of the
+// function is:
+//
+// TRIM(text)
+//
func (fn *formulaFuncs) TRIM(argsList *list.List) (result string, err error) {
if argsList.Len() != 1 {
err = errors.New("TRIM requires 1 argument")
@@ -3394,3 +3414,58 @@ func (fn *formulaFuncs) TRIM(argsList *list.List) (result string, err error) {
result = strings.TrimSpace(argsList.Front().Value.(formulaArg).String)
return
}
+
+// LOWER converts all characters in a supplied text string to lower case. The
+// syntax of the function is:
+//
+// LOWER(text)
+//
+func (fn *formulaFuncs) LOWER(argsList *list.List) (result string, err error) {
+ if argsList.Len() != 1 {
+ err = errors.New("LOWER requires 1 argument")
+ return
+ }
+ result = strings.ToLower(argsList.Front().Value.(formulaArg).String)
+ return
+}
+
+// PROPER converts all characters in a supplied text string to proper case
+// (i.e. all letters that do not immediately follow another letter are set to
+// upper case and all other characters are lower case). The syntax of the
+// function is:
+//
+// PROPER(text)
+//
+func (fn *formulaFuncs) PROPER(argsList *list.List) (result string, err error) {
+ if argsList.Len() != 1 {
+ err = errors.New("PROPER requires 1 argument")
+ return
+ }
+ buf := bytes.Buffer{}
+ isLetter := false
+ for _, char := range argsList.Front().Value.(formulaArg).String {
+ if !isLetter && unicode.IsLetter(char) {
+ buf.WriteRune(unicode.ToUpper(char))
+ } else {
+ buf.WriteRune(unicode.ToLower(char))
+ }
+ isLetter = unicode.IsLetter(char)
+ }
+
+ result = buf.String()
+ return
+}
+
+// UPPER converts all characters in a supplied text string to upper case. The
+// syntax of the function is:
+//
+// UPPER(text)
+//
+func (fn *formulaFuncs) UPPER(argsList *list.List) (result string, err error) {
+ if argsList.Len() != 1 {
+ err = errors.New("UPPER requires 1 argument")
+ return
+ }
+ result = strings.ToUpper(argsList.Front().Value.(formulaArg).String)
+ return
+}