@@ -259,12 +259,18 @@ func (f *File) evalInfixExp(sheet string, tokens []efp.Token) (efp.Token, error)
259259 }
260260 optStack .Pop ()
261261 }
262+ if opdStack .Len () == 0 {
263+ return efp.Token {}, errors .New ("formula not valid" )
264+ }
262265 return opdStack .Peek ().(efp.Token ), err
263266}
264267
265268// calculate evaluate basic arithmetic operations.
266269func calculate (opdStack * Stack , opt efp.Token ) error {
267270 if opt .TValue == "-" && opt .TType == efp .TokenTypeOperatorPrefix {
271+ if opdStack .Len () < 1 {
272+ return errors .New ("formula not valid" )
273+ }
268274 opd := opdStack .Pop ().(efp.Token )
269275 opdVal , err := strconv .ParseFloat (opd .TValue , 64 )
270276 if err != nil {
@@ -274,6 +280,9 @@ func calculate(opdStack *Stack, opt efp.Token) error {
274280 opdStack .Push (efp.Token {TValue : fmt .Sprintf ("%g" , result ), TType : efp .TokenTypeOperand , TSubType : efp .TokenSubTypeNumber })
275281 }
276282 if opt .TValue == "+" {
283+ if opdStack .Len () < 2 {
284+ return errors .New ("formula not valid" )
285+ }
277286 rOpd := opdStack .Pop ().(efp.Token )
278287 lOpd := opdStack .Pop ().(efp.Token )
279288 lOpdVal , err := strconv .ParseFloat (lOpd .TValue , 64 )
@@ -288,6 +297,9 @@ func calculate(opdStack *Stack, opt efp.Token) error {
288297 opdStack .Push (efp.Token {TValue : fmt .Sprintf ("%g" , result ), TType : efp .TokenTypeOperand , TSubType : efp .TokenSubTypeNumber })
289298 }
290299 if opt .TValue == "-" && opt .TType == efp .TokenTypeOperatorInfix {
300+ if opdStack .Len () < 2 {
301+ return errors .New ("formula not valid" )
302+ }
291303 rOpd := opdStack .Pop ().(efp.Token )
292304 lOpd := opdStack .Pop ().(efp.Token )
293305 lOpdVal , err := strconv .ParseFloat (lOpd .TValue , 64 )
@@ -302,6 +314,9 @@ func calculate(opdStack *Stack, opt efp.Token) error {
302314 opdStack .Push (efp.Token {TValue : fmt .Sprintf ("%g" , result ), TType : efp .TokenTypeOperand , TSubType : efp .TokenSubTypeNumber })
303315 }
304316 if opt .TValue == "*" {
317+ if opdStack .Len () < 2 {
318+ return errors .New ("formula not valid" )
319+ }
305320 rOpd := opdStack .Pop ().(efp.Token )
306321 lOpd := opdStack .Pop ().(efp.Token )
307322 lOpdVal , err := strconv .ParseFloat (lOpd .TValue , 64 )
@@ -316,6 +331,9 @@ func calculate(opdStack *Stack, opt efp.Token) error {
316331 opdStack .Push (efp.Token {TValue : fmt .Sprintf ("%g" , result ), TType : efp .TokenTypeOperand , TSubType : efp .TokenSubTypeNumber })
317332 }
318333 if opt .TValue == "/" {
334+ if opdStack .Len () < 2 {
335+ return errors .New ("formula not valid" )
336+ }
319337 rOpd := opdStack .Pop ().(efp.Token )
320338 lOpd := opdStack .Pop ().(efp.Token )
321339 lOpdVal , err := strconv .ParseFloat (lOpd .TValue , 64 )
@@ -444,35 +462,73 @@ func (f *File) parseReference(sheet, reference string) (result []string, matrix
444462}
445463
446464// rangeResolver extract value as string from given reference and range list.
447- // This function will not ignore the empty cell. Note that the result of 3D
448- // range references may be different from Excel in some cases, for example,
449- // A1:A2:A2:B3 in Excel will include B1, but we wont.
465+ // This function will not ignore the empty cell. For example,
466+ // A1:A2:A2:B3 will be reference A1:B3.
450467func (f * File ) rangeResolver (cellRefs , cellRanges * list.List ) (result []string , matrix [][]string , err error ) {
468+ var fromRow , toRow , fromCol , toCol int = 1 , 1 , 1 , 1
469+ var sheet string
451470 filter := map [string ]string {}
452- // extract value from ranges
471+ // prepare value range
453472 for temp := cellRanges .Front (); temp != nil ; temp = temp .Next () {
454473 cr := temp .Value .(cellRange )
455474 if cr .From .Sheet != cr .To .Sheet {
456475 err = errors .New (formulaErrorVALUE )
457476 }
458477 rng := []int {cr .From .Col , cr .From .Row , cr .To .Col , cr .To .Row }
459478 sortCoordinates (rng )
460- matrix = [][]string {}
461- for row := rng [1 ]; row <= rng [3 ]; row ++ {
479+ if cr .From .Row < fromRow {
480+ fromRow = cr .From .Row
481+ }
482+ if cr .From .Col < fromCol {
483+ fromCol = cr .From .Col
484+ }
485+ if cr .To .Row > fromRow {
486+ toRow = cr .To .Row
487+ }
488+ if cr .To .Col > toCol {
489+ toCol = cr .To .Col
490+ }
491+ if cr .From .Sheet != "" {
492+ sheet = cr .From .Sheet
493+ }
494+ }
495+ for temp := cellRefs .Front (); temp != nil ; temp = temp .Next () {
496+ cr := temp .Value .(cellRef )
497+ if cr .Sheet != "" {
498+ sheet = cr .Sheet
499+ }
500+ if cr .Row < fromRow {
501+ fromRow = cr .Row
502+ }
503+ if cr .Col < fromCol {
504+ fromCol = cr .Col
505+ }
506+ if cr .Row > fromRow {
507+ toRow = cr .Row
508+ }
509+ if cr .Col > toCol {
510+ toCol = cr .Col
511+ }
512+ }
513+ // extract value from ranges
514+ if cellRanges .Len () > 0 {
515+ for row := fromRow ; row <= toRow ; row ++ {
462516 var matrixRow = []string {}
463- for col := rng [ 0 ] ; col <= rng [ 2 ] ; col ++ {
517+ for col := fromCol ; col <= toCol ; col ++ {
464518 var cell , value string
465519 if cell , err = CoordinatesToCellName (col , row ); err != nil {
466520 return
467521 }
468- if value , err = f .GetCellValue (cr . From . Sheet , cell ); err != nil {
522+ if value , err = f .GetCellValue (sheet , cell ); err != nil {
469523 return
470524 }
471525 filter [cell ] = value
472526 matrixRow = append (matrixRow , value )
527+ result = append (result , value )
473528 }
474529 matrix = append (matrix , matrixRow )
475530 }
531+ return
476532 }
477533 // extract value from references
478534 for temp := cellRefs .Front (); temp != nil ; temp = temp .Next () {
@@ -824,7 +880,7 @@ func (fn *formulaFuncs) CEILING(argsList *list.List) (result string, err error)
824880 err = errors .New ("CEILING allows at most 2 arguments" )
825881 return
826882 }
827- var number , significance float64 = 0 , 1
883+ number , significance , res : = 0.0 , 1.0 , 0.0
828884 if number , err = strconv .ParseFloat (argsList .Front ().Value .(formulaArg ).Value , 64 ); err != nil {
829885 return
830886 }
@@ -844,7 +900,7 @@ func (fn *formulaFuncs) CEILING(argsList *list.List) (result string, err error)
844900 result = fmt .Sprintf ("%g" , math .Ceil (number ))
845901 return
846902 }
847- number , res : = math .Modf (number / significance )
903+ number , res = math .Modf (number / significance )
848904 if res > 0 {
849905 number ++
850906 }
@@ -866,7 +922,7 @@ func (fn *formulaFuncs) CEILINGMATH(argsList *list.List) (result string, err err
866922 err = errors .New ("CEILING.MATH allows at most 3 arguments" )
867923 return
868924 }
869- var number , significance , mode float64 = 0 , 1 , 1
925+ number , significance , mode : = 0.0 , 1.0 , 1.0
870926 if number , err = strconv .ParseFloat (argsList .Front ().Value .(formulaArg ).Value , 64 ); err != nil {
871927 return
872928 }
@@ -914,7 +970,7 @@ func (fn *formulaFuncs) CEILINGPRECISE(argsList *list.List) (result string, err
914970 err = errors .New ("CEILING.PRECISE allows at most 2 arguments" )
915971 return
916972 }
917- var number , significance float64 = 0 , 1
973+ number , significance : = 0.0 , 1.0
918974 if number , err = strconv .ParseFloat (argsList .Front ().Value .(formulaArg ).Value , 64 ); err != nil {
919975 return
920976 }
@@ -955,7 +1011,7 @@ func (fn *formulaFuncs) COMBIN(argsList *list.List) (result string, err error) {
9551011 err = errors .New ("COMBIN requires 2 argument" )
9561012 return
9571013 }
958- var number , chosen , val float64 = 0 , 0 , 1
1014+ number , chosen , val : = 0.0 , 0.0 , 1.0
9591015 if number , err = strconv .ParseFloat (argsList .Front ().Value .(formulaArg ).Value , 64 ); err != nil {
9601016 return
9611017 }
@@ -1274,7 +1330,7 @@ func (fn *formulaFuncs) FACTDOUBLE(argsList *list.List) (result string, err erro
12741330 err = errors .New ("FACTDOUBLE requires 1 numeric argument" )
12751331 return
12761332 }
1277- var number , val float64 = 0 , 1
1333+ number , val : = 0.0 , 1.0
12781334 if number , err = strconv .ParseFloat (argsList .Front ().Value .(formulaArg ).Value , 64 ); err != nil {
12791335 return
12801336 }
@@ -1298,7 +1354,7 @@ func (fn *formulaFuncs) FLOOR(argsList *list.List) (result string, err error) {
12981354 err = errors .New ("FLOOR requires 2 numeric arguments" )
12991355 return
13001356 }
1301- var number , significance float64 = 0 , 1
1357+ var number , significance float64
13021358 if number , err = strconv .ParseFloat (argsList .Front ().Value .(formulaArg ).Value , 64 ); err != nil {
13031359 return
13041360 }
@@ -1333,7 +1389,7 @@ func (fn *formulaFuncs) FLOORMATH(argsList *list.List) (result string, err error
13331389 err = errors .New ("FLOOR.MATH allows at most 3 arguments" )
13341390 return
13351391 }
1336- var number , significance , mode float64 = 0 , 1 , 1
1392+ number , significance , mode : = 0.0 , 1.0 , 1.0
13371393 if number , err = strconv .ParseFloat (argsList .Front ().Value .(formulaArg ).Value , 64 ); err != nil {
13381394 return
13391395 }
@@ -1376,7 +1432,7 @@ func (fn *formulaFuncs) FLOORPRECISE(argsList *list.List) (result string, err er
13761432 err = errors .New ("FLOOR.PRECISE allows at most 2 arguments" )
13771433 return
13781434 }
1379- var number , significance float64 = 0 , 1
1435+ var number , significance float64
13801436 if number , err = strconv .ParseFloat (argsList .Front ().Value .(formulaArg ).Value , 64 ); err != nil {
13811437 return
13821438 }
@@ -1488,7 +1544,7 @@ func (fn *formulaFuncs) ISOCEILING(argsList *list.List) (result string, err erro
14881544 err = errors .New ("ISO.CEILING allows at most 2 arguments" )
14891545 return
14901546 }
1491- var number , significance float64 = 0 , 1
1547+ var number , significance float64
14921548 if number , err = strconv .ParseFloat (argsList .Front ().Value .(formulaArg ).Value , 64 ); err != nil {
14931549 return
14941550 }
@@ -1605,7 +1661,7 @@ func (fn *formulaFuncs) LOG(argsList *list.List) (result string, err error) {
16051661 err = errors .New ("LOG allows at most 2 arguments" )
16061662 return
16071663 }
1608- var number , base float64 = 0 , 10
1664+ number , base : = 0.0 , 10.0
16091665 if number , err = strconv .ParseFloat (argsList .Front ().Value .(formulaArg ).Value , 64 ); err != nil {
16101666 return
16111667 }
@@ -1757,7 +1813,7 @@ func (fn *formulaFuncs) MROUND(argsList *list.List) (result string, err error) {
17571813 err = errors .New ("MROUND requires 2 numeric arguments" )
17581814 return
17591815 }
1760- var number , multiple float64 = 0 , 1
1816+ var number , multiple float64
17611817 if number , err = strconv .ParseFloat (argsList .Front ().Value .(formulaArg ).Value , 64 ); err != nil {
17621818 return
17631819 }
@@ -1788,7 +1844,7 @@ func (fn *formulaFuncs) MROUND(argsList *list.List) (result string, err error) {
17881844// MULTINOMIAL(number1,[number2],...)
17891845//
17901846func (fn * formulaFuncs ) MULTINOMIAL (argsList * list.List ) (result string , err error ) {
1791- var val , num , denom float64 = 0 , 0 , 1
1847+ val , num , denom : = 0.0 , 0.0 , 1.0
17921848 for arg := argsList .Front (); arg != nil ; arg = arg .Next () {
17931849 token := arg .Value .(formulaArg )
17941850 if token .Value == "" {
@@ -1915,7 +1971,7 @@ func (fn *formulaFuncs) POWER(argsList *list.List) (result string, err error) {
19151971// PRODUCT(number1,[number2],...)
19161972//
19171973func (fn * formulaFuncs ) PRODUCT (argsList * list.List ) (result string , err error ) {
1918- var val , product float64 = 0 , 1
1974+ val , product : = 0.0 , 1.0
19191975 for arg := argsList .Front (); arg != nil ; arg = arg .Next () {
19201976 token := arg .Value .(formulaArg )
19211977 if token .Value == "" {
@@ -2088,7 +2144,7 @@ const (
20882144
20892145// round rounds a supplied number up or down.
20902146func (fn * formulaFuncs ) round (number , digits float64 , mode roundMode ) float64 {
2091- significance := 1.0
2147+ var significance float64
20922148 if digits > 0 {
20932149 significance = math .Pow (1 / 10.0 , digits )
20942150 } else {
@@ -2343,6 +2399,27 @@ func (fn *formulaFuncs) SUM(argsList *list.List) (result string, err error) {
23432399 return
23442400}
23452401
2402+ // SUMSQ function returns the sum of squares of a supplied set of values. The
2403+ // syntax of the function is:
2404+ //
2405+ // SUMSQ(number1,[number2],...)
2406+ //
2407+ func (fn * formulaFuncs ) SUMSQ (argsList * list.List ) (result string , err error ) {
2408+ var val , sq float64
2409+ for arg := argsList .Front (); arg != nil ; arg = arg .Next () {
2410+ token := arg .Value .(formulaArg )
2411+ if token .Value == "" {
2412+ continue
2413+ }
2414+ if val , err = strconv .ParseFloat (token .Value , 64 ); err != nil {
2415+ return
2416+ }
2417+ sq += val * val
2418+ }
2419+ result = fmt .Sprintf ("%g" , sq )
2420+ return
2421+ }
2422+
23462423// TAN function calculates the tangent of a given angle. The syntax of the
23472424// function is:
23482425//
0 commit comments