|
|
@ -412,7 +412,7 @@ func (f *File) parseReference(sheet, reference string) (result []string, err err
|
|
|
|
// rangeResolver extract value as string from given reference and range list.
|
|
|
|
// rangeResolver extract value as string from given reference and range list.
|
|
|
|
// This function will not ignore the empty cell. Note that the result of 3D
|
|
|
|
// This function will not ignore the empty cell. Note that the result of 3D
|
|
|
|
// range references may be different from Excel in some cases, for example,
|
|
|
|
// range references may be different from Excel in some cases, for example,
|
|
|
|
// A1:A2:A2:B3 in Excel will include B2, but we wont.
|
|
|
|
// A1:A2:A2:B3 in Excel will include B1, but we wont.
|
|
|
|
func (f *File) rangeResolver(cellRefs, cellRanges *list.List) (result []string, err error) {
|
|
|
|
func (f *File) rangeResolver(cellRefs, cellRanges *list.List) (result []string, err error) {
|
|
|
|
filter := map[string]string{}
|
|
|
|
filter := map[string]string{}
|
|
|
|
// extract value from ranges
|
|
|
|
// extract value from ranges
|
|
|
@ -475,14 +475,58 @@ func callFuncByName(receiver interface{}, name string, params []reflect.Value) (
|
|
|
|
|
|
|
|
|
|
|
|
// Math and Trigonometric functions
|
|
|
|
// Math and Trigonometric functions
|
|
|
|
|
|
|
|
|
|
|
|
// SUM function adds together a supplied set of numbers and returns the sum of
|
|
|
|
// ABS function returns the absolute value of any supplied number. The syntax
|
|
|
|
// these values. The syntax of the function is:
|
|
|
|
// of the function is:
|
|
|
|
//
|
|
|
|
//
|
|
|
|
// SUM(number1,[number2],...)
|
|
|
|
// ABS(number)
|
|
|
|
//
|
|
|
|
//
|
|
|
|
func (fn *formulaFuncs) SUM(argsStack *Stack) (result string, err error) {
|
|
|
|
func (fn *formulaFuncs) ABS(argsStack *Stack) (result string, err error) {
|
|
|
|
|
|
|
|
if argsStack.Len() != 1 {
|
|
|
|
|
|
|
|
err = errors.New("ABS requires 1 numeric arguments")
|
|
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
}
|
|
|
|
var val float64
|
|
|
|
var val float64
|
|
|
|
var sum float64
|
|
|
|
val, err = strconv.ParseFloat(argsStack.Pop().(efp.Token).TValue, 64)
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
result = fmt.Sprintf("%g", math.Abs(val))
|
|
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// gcd returns the greatest common divisor of two supplied integers.
|
|
|
|
|
|
|
|
func gcd(x, y float64) float64 {
|
|
|
|
|
|
|
|
x, y = math.Trunc(x), math.Trunc(y)
|
|
|
|
|
|
|
|
if x == 0 {
|
|
|
|
|
|
|
|
return y
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if y == 0 {
|
|
|
|
|
|
|
|
return x
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
for x != y {
|
|
|
|
|
|
|
|
if x > y {
|
|
|
|
|
|
|
|
x = x - y
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
y = y - x
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return x
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// GCD function returns the greatest common divisor of two or more supplied
|
|
|
|
|
|
|
|
// integers.The syntax of the function is:
|
|
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
// GCD(number1,[number2],...)
|
|
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
func (fn *formulaFuncs) GCD(argsStack *Stack) (result string, err error) {
|
|
|
|
|
|
|
|
if argsStack.Len() == 0 {
|
|
|
|
|
|
|
|
err = errors.New("GCD requires at least 1 argument")
|
|
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
var (
|
|
|
|
|
|
|
|
val float64
|
|
|
|
|
|
|
|
nums = []float64{}
|
|
|
|
|
|
|
|
)
|
|
|
|
for !argsStack.Empty() {
|
|
|
|
for !argsStack.Empty() {
|
|
|
|
token := argsStack.Pop().(efp.Token)
|
|
|
|
token := argsStack.Pop().(efp.Token)
|
|
|
|
if token.TValue == "" {
|
|
|
|
if token.TValue == "" {
|
|
|
@ -492,21 +536,51 @@ func (fn *formulaFuncs) SUM(argsStack *Stack) (result string, err error) {
|
|
|
|
if err != nil {
|
|
|
|
if err != nil {
|
|
|
|
return
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
|
sum += val
|
|
|
|
nums = append(nums, val)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
result = fmt.Sprintf("%g", sum)
|
|
|
|
if nums[0] < 0 {
|
|
|
|
|
|
|
|
err = errors.New("GCD only accepts positive arguments")
|
|
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if len(nums) == 1 {
|
|
|
|
|
|
|
|
result = fmt.Sprintf("%g", nums[0])
|
|
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
cd := nums[0]
|
|
|
|
|
|
|
|
for i := 1; i < len(nums); i++ {
|
|
|
|
|
|
|
|
if nums[i] < 0 {
|
|
|
|
|
|
|
|
err = errors.New("GCD only accepts positive arguments")
|
|
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
cd = gcd(cd, nums[i])
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
result = fmt.Sprintf("%g", cd)
|
|
|
|
return
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// PRODUCT function returns the product (multiplication) of a supplied set of numerical values.
|
|
|
|
// lcm returns the least common multiple of two supplied integers.
|
|
|
|
// The syntax of the function is:
|
|
|
|
func lcm(a, b float64) float64 {
|
|
|
|
|
|
|
|
a = math.Trunc(a)
|
|
|
|
|
|
|
|
b = math.Trunc(b)
|
|
|
|
|
|
|
|
if a == 0 && b == 0 {
|
|
|
|
|
|
|
|
return 0
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return a * b / gcd(a, b)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// LCM function returns the least common multiple of two or more supplied
|
|
|
|
|
|
|
|
// integers. The syntax of the function is:
|
|
|
|
//
|
|
|
|
//
|
|
|
|
// PRODUCT(number1,[number2],...)
|
|
|
|
// LCM(number1,[number2],...)
|
|
|
|
//
|
|
|
|
//
|
|
|
|
func (fn *formulaFuncs) PRODUCT(argsStack *Stack) (result string, err error) {
|
|
|
|
func (fn *formulaFuncs) LCM(argsStack *Stack) (result string, err error) {
|
|
|
|
|
|
|
|
if argsStack.Len() == 0 {
|
|
|
|
|
|
|
|
err = errors.New("LCM requires at least 1 argument")
|
|
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
}
|
|
|
|
var (
|
|
|
|
var (
|
|
|
|
val float64
|
|
|
|
val float64
|
|
|
|
product float64 = 1
|
|
|
|
nums = []float64{}
|
|
|
|
)
|
|
|
|
)
|
|
|
|
for !argsStack.Empty() {
|
|
|
|
for !argsStack.Empty() {
|
|
|
|
token := argsStack.Pop().(efp.Token)
|
|
|
|
token := argsStack.Pop().(efp.Token)
|
|
|
@ -517,13 +591,29 @@ func (fn *formulaFuncs) PRODUCT(argsStack *Stack) (result string, err error) {
|
|
|
|
if err != nil {
|
|
|
|
if err != nil {
|
|
|
|
return
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
|
product = product * val
|
|
|
|
nums = append(nums, val)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
result = fmt.Sprintf("%g", product)
|
|
|
|
if nums[0] < 0 {
|
|
|
|
|
|
|
|
err = errors.New("LCM only accepts positive arguments")
|
|
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if len(nums) == 1 {
|
|
|
|
|
|
|
|
result = fmt.Sprintf("%g", nums[0])
|
|
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
cm := nums[0]
|
|
|
|
|
|
|
|
for i := 1; i < len(nums); i++ {
|
|
|
|
|
|
|
|
if nums[i] < 0 {
|
|
|
|
|
|
|
|
err = errors.New("LCM only accepts positive arguments")
|
|
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
cm = lcm(cm, nums[i])
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
result = fmt.Sprintf("%g", cm)
|
|
|
|
return
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// PRODUCT function calculates a given number, raised to a supplied power.
|
|
|
|
// POWER function calculates a given number, raised to a supplied power.
|
|
|
|
// The syntax of the function is:
|
|
|
|
// The syntax of the function is:
|
|
|
|
//
|
|
|
|
//
|
|
|
|
// POWER(number,power)
|
|
|
|
// POWER(number,power)
|
|
|
@ -554,8 +644,62 @@ func (fn *formulaFuncs) POWER(argsStack *Stack) (result string, err error) {
|
|
|
|
return
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// SQRT function calculates the positive square root of a supplied number.
|
|
|
|
// PRODUCT function returns the product (multiplication) of a supplied set of
|
|
|
|
// The syntax of the function is:
|
|
|
|
// numerical values. The syntax of the function is:
|
|
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
// PRODUCT(number1,[number2],...)
|
|
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
func (fn *formulaFuncs) PRODUCT(argsStack *Stack) (result string, err error) {
|
|
|
|
|
|
|
|
var (
|
|
|
|
|
|
|
|
val float64
|
|
|
|
|
|
|
|
product float64 = 1
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
for !argsStack.Empty() {
|
|
|
|
|
|
|
|
token := argsStack.Pop().(efp.Token)
|
|
|
|
|
|
|
|
if token.TValue == "" {
|
|
|
|
|
|
|
|
continue
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
val, err = strconv.ParseFloat(token.TValue, 64)
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
product = product * val
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
result = fmt.Sprintf("%g", product)
|
|
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// SIGN function returns the arithmetic sign (+1, -1 or 0) of a supplied
|
|
|
|
|
|
|
|
// number. I.e. if the number is positive, the Sign function returns +1, if
|
|
|
|
|
|
|
|
// the number is negative, the function returns -1 and if the number is 0
|
|
|
|
|
|
|
|
// (zero), the function returns 0. The syntax of the function is:
|
|
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
// SIGN(number)
|
|
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
func (fn *formulaFuncs) SIGN(argsStack *Stack) (result string, err error) {
|
|
|
|
|
|
|
|
if argsStack.Len() != 1 {
|
|
|
|
|
|
|
|
err = errors.New("SIGN requires 1 numeric arguments")
|
|
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
var val float64
|
|
|
|
|
|
|
|
val, err = strconv.ParseFloat(argsStack.Pop().(efp.Token).TValue, 64)
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if val < 0 {
|
|
|
|
|
|
|
|
result = "-1"
|
|
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if val > 0 {
|
|
|
|
|
|
|
|
result = "1"
|
|
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
result = "0"
|
|
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// SQRT function calculates the positive square root of a supplied number. The
|
|
|
|
|
|
|
|
// syntax of the function is:
|
|
|
|
//
|
|
|
|
//
|
|
|
|
// SQRT(number)
|
|
|
|
// SQRT(number)
|
|
|
|
//
|
|
|
|
//
|
|
|
@ -577,8 +721,31 @@ func (fn *formulaFuncs) SQRT(argsStack *Stack) (result string, err error) {
|
|
|
|
return
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// QUOTIENT function returns the integer portion of a division between two supplied numbers.
|
|
|
|
// SUM function adds together a supplied set of numbers and returns the sum of
|
|
|
|
// The syntax of the function is:
|
|
|
|
// these values. The syntax of the function is:
|
|
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
// SUM(number1,[number2],...)
|
|
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
func (fn *formulaFuncs) SUM(argsStack *Stack) (result string, err error) {
|
|
|
|
|
|
|
|
var val float64
|
|
|
|
|
|
|
|
var sum float64
|
|
|
|
|
|
|
|
for !argsStack.Empty() {
|
|
|
|
|
|
|
|
token := argsStack.Pop().(efp.Token)
|
|
|
|
|
|
|
|
if token.TValue == "" {
|
|
|
|
|
|
|
|
continue
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
val, err = strconv.ParseFloat(token.TValue, 64)
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
sum += val
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
result = fmt.Sprintf("%g", sum)
|
|
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// QUOTIENT function returns the integer portion of a division between two
|
|
|
|
|
|
|
|
// supplied numbers. The syntax of the function is:
|
|
|
|
//
|
|
|
|
//
|
|
|
|
// QUOTIENT(numerator,denominator)
|
|
|
|
// QUOTIENT(numerator,denominator)
|
|
|
|
//
|
|
|
|
//
|
|
|
|