@@ -844,7 +844,7 @@ func (f *File) calcCellValue(ctx *calcContext, sheet, cell string) (result formu
844
844
ps := efp.ExcelParser()
845
845
tokens := ps.Parse(formula)
846
846
if tokens == nil {
847
- return
847
+ return f.cellResolver(ctx, sheet, cell)
848
848
}
849
849
result, err = f.evalInfixExp(ctx, sheet, cell, tokens)
850
850
return
@@ -1225,6 +1225,12 @@ func calcAdd(rOpd, lOpd formulaArg, opdStack *Stack) error {
1225
1225
1226
1226
// calcSubtract evaluate subtraction arithmetic operations.
1227
1227
func calcSubtract(rOpd, lOpd formulaArg, opdStack *Stack) error {
1228
+ if rOpd.Value() == "" {
1229
+ rOpd = newNumberFormulaArg(0)
1230
+ }
1231
+ if lOpd.Value() == "" {
1232
+ lOpd = newNumberFormulaArg(0)
1233
+ }
1228
1234
lOpdVal := lOpd.ToNumber()
1229
1235
if lOpdVal.Type != ArgNumber {
1230
1236
return errors.New(lOpdVal.Value())
@@ -1300,22 +1306,27 @@ func calculate(opdStack *Stack, opt efp.Token) error {
1300
1306
">=": calcGe,
1301
1307
"&": calcSplice,
1302
1308
}
1303
- fn, ok := tokenCalcFunc[opt.TValue]
1304
- if ok {
1309
+ if fn, ok := tokenCalcFunc[opt.TValue]; ok {
1305
1310
if opdStack.Len() < 2 {
1306
1311
return ErrInvalidFormula
1307
1312
}
1308
1313
rOpd := opdStack.Pop().(formulaArg)
1309
1314
lOpd := opdStack.Pop().(formulaArg)
1315
+ if opt.TValue != "&" {
1316
+ if rOpd.Value() == "" {
1317
+ rOpd = newNumberFormulaArg(0)
1318
+ }
1319
+ if lOpd.Value() == "" {
1320
+ lOpd = newNumberFormulaArg(0)
1321
+ }
1322
+ }
1310
1323
if rOpd.Type == ArgError {
1311
1324
return errors.New(rOpd.Value())
1312
1325
}
1313
1326
if lOpd.Type == ArgError {
1314
1327
return errors.New(lOpd.Value())
1315
1328
}
1316
- if err := fn(rOpd, lOpd, opdStack); err != nil {
1317
- return err
1318
- }
1329
+ return fn(rOpd, lOpd, opdStack)
1319
1330
}
1320
1331
return nil
1321
1332
}
@@ -1329,6 +1340,10 @@ func (f *File) parseOperatorPrefixToken(optStack, opdStack *Stack, token efp.Tok
1329
1340
tokenPriority := getPriority(token)
1330
1341
topOpt := optStack.Peek().(efp.Token)
1331
1342
topOptPriority := getPriority(topOpt)
1343
+ if topOpt.TValue == "-" && topOpt.TType == efp.TokenTypeOperatorPrefix && token.TValue == "-" && token.TType == efp.TokenTypeOperatorPrefix {
1344
+ optStack.Pop()
1345
+ return
1346
+ }
1332
1347
if tokenPriority > topOptPriority {
1333
1348
optStack.Push(token)
1334
1349
return
@@ -13757,7 +13772,7 @@ func (fn *formulaFuncs) LEN(argsList *list.List) formulaArg {
13757
13772
if argsList.Len() != 1 {
13758
13773
return newErrorFormulaArg(formulaErrorVALUE, "LEN requires 1 string argument")
13759
13774
}
13760
- return newNumberFormulaArg(float64(utf8.RuneCountInString(argsList.Front().Value.(formulaArg).String )))
13775
+ return newNumberFormulaArg(float64(utf8.RuneCountInString(argsList.Front().Value.(formulaArg).Value() )))
13761
13776
}
13762
13777
13763
13778
// LENB returns the number of bytes used to represent the characters in a text
@@ -13790,7 +13805,7 @@ func (fn *formulaFuncs) LOWER(argsList *list.List) formulaArg {
13790
13805
if argsList.Len() != 1 {
13791
13806
return newErrorFormulaArg(formulaErrorVALUE, "LOWER requires 1 argument")
13792
13807
}
13793
- return newStringFormulaArg(strings.ToLower(argsList.Front().Value.(formulaArg).String ))
13808
+ return newStringFormulaArg(strings.ToLower(argsList.Front().Value.(formulaArg).Value() ))
13794
13809
}
13795
13810
13796
13811
// MID function returns a specified number of characters from the middle of a
@@ -13881,7 +13896,7 @@ func (fn *formulaFuncs) PROPER(argsList *list.List) formulaArg {
13881
13896
}
13882
13897
buf := bytes.Buffer{}
13883
13898
isLetter := false
13884
- for _, char := range argsList.Front().Value.(formulaArg).String {
13899
+ for _, char := range argsList.Front().Value.(formulaArg).Value() {
13885
13900
if !isLetter && unicode.IsLetter(char) {
13886
13901
buf.WriteRune(unicode.ToUpper(char))
13887
13902
} else {
@@ -13962,7 +13977,7 @@ func (fn *formulaFuncs) REPT(argsList *list.List) formulaArg {
13962
13977
}
13963
13978
buf := bytes.Buffer{}
13964
13979
for i := 0; i < int(times.Number); i++ {
13965
- buf.WriteString(text.String )
13980
+ buf.WriteString(text.Value() )
13966
13981
}
13967
13982
return newStringFormulaArg(buf.String())
13968
13983
}
@@ -14327,7 +14342,7 @@ func (fn *formulaFuncs) UPPER(argsList *list.List) formulaArg {
14327
14342
if argsList.Len() != 1 {
14328
14343
return newErrorFormulaArg(formulaErrorVALUE, "UPPER requires 1 argument")
14329
14344
}
14330
- return newStringFormulaArg(strings.ToUpper(argsList.Front().Value.(formulaArg).String ))
14345
+ return newStringFormulaArg(strings.ToUpper(argsList.Front().Value.(formulaArg).Value() ))
14331
14346
}
14332
14347
14333
14348
// VALUE function converts a text string into a numeric value. The syntax of
@@ -14405,7 +14420,7 @@ func (fn *formulaFuncs) IF(argsList *list.List) formulaArg {
14405
14420
)
14406
14421
switch token.Type {
14407
14422
case ArgString:
14408
- if cond, err = strconv.ParseBool(token.String ); err != nil {
14423
+ if cond, err = strconv.ParseBool(token.Value() ); err != nil {
14409
14424
return newErrorFormulaArg(formulaErrorVALUE, err.Error())
14410
14425
}
14411
14426
case ArgNumber:
@@ -14421,7 +14436,7 @@ func (fn *formulaFuncs) IF(argsList *list.List) formulaArg {
14421
14436
case ArgNumber:
14422
14437
result = value.ToNumber()
14423
14438
default:
14424
- result = newStringFormulaArg(value.String )
14439
+ result = newStringFormulaArg(value.Value() )
14425
14440
}
14426
14441
return result
14427
14442
}
@@ -14431,7 +14446,7 @@ func (fn *formulaFuncs) IF(argsList *list.List) formulaArg {
14431
14446
case ArgNumber:
14432
14447
result = value.ToNumber()
14433
14448
default:
14434
- result = newStringFormulaArg(value.String )
14449
+ result = newStringFormulaArg(value.Value() )
14435
14450
}
14436
14451
}
14437
14452
return result
@@ -14582,7 +14597,7 @@ func compareFormulaArg(lhs, rhs, matchMode formulaArg, caseSensitive bool) byte
14582
14597
}
14583
14598
return criteriaG
14584
14599
case ArgString:
14585
- ls, rs := lhs.String , rhs.String
14600
+ ls, rs := lhs.Value() , rhs.Value()
14586
14601
if !caseSensitive {
14587
14602
ls, rs = strings.ToLower(ls), strings.ToLower(rs)
14588
14603
}
0 commit comments