forked from p30928647/excelize
This fixed across worksheet reference issue for the formula calculation engine
This commit is contained in:
parent
1088302331
commit
ef3e81de8e
178
calc.go
178
calc.go
|
@ -951,9 +951,6 @@ func (f *File) evalInfixExp(ctx *calcContext, sheet, cell string, tokens []efp.T
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return result, err
|
return result, err
|
||||||
}
|
}
|
||||||
if result.Type == ArgError {
|
|
||||||
return result, errors.New(result.Error)
|
|
||||||
}
|
|
||||||
opfdStack.Push(result)
|
opfdStack.Push(result)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
@ -965,10 +962,7 @@ func (f *File) evalInfixExp(ctx *calcContext, sheet, cell string, tokens []efp.T
|
||||||
}
|
}
|
||||||
result, err := f.parseReference(ctx, sheet, token.TValue)
|
result, err := f.parseReference(ctx, sheet, token.TValue)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return newEmptyFormulaArg(), err
|
return result, err
|
||||||
}
|
|
||||||
if result.Type == ArgUnknown {
|
|
||||||
return newEmptyFormulaArg(), errors.New(formulaErrorVALUE)
|
|
||||||
}
|
}
|
||||||
// when current token is range, next token is argument and opfdStack not empty,
|
// when current token is range, next token is argument and opfdStack not empty,
|
||||||
// should push value to opfdStack and continue
|
// should push value to opfdStack and continue
|
||||||
|
@ -1442,74 +1436,99 @@ func (f *File) parseToken(ctx *calcContext, sheet string, token efp.Token, opdSt
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// parseRef parse reference for a cell, column name or row number.
|
||||||
|
func (f *File) parseRef(ref string) (cellRef, bool, bool, error) {
|
||||||
|
var (
|
||||||
|
err, colErr, rowErr error
|
||||||
|
cr cellRef
|
||||||
|
cell = ref
|
||||||
|
tokens = strings.Split(ref, "!")
|
||||||
|
)
|
||||||
|
if len(tokens) == 2 { // have a worksheet
|
||||||
|
cr.Sheet, cell = tokens[0], tokens[1]
|
||||||
|
}
|
||||||
|
if cr.Col, cr.Row, err = CellNameToCoordinates(cell); err != nil {
|
||||||
|
if cr.Col, colErr = ColumnNameToNumber(cell); colErr == nil { // cast to column
|
||||||
|
return cr, true, false, nil
|
||||||
|
}
|
||||||
|
if cr.Row, rowErr = strconv.Atoi(cell); rowErr == nil { // cast to row
|
||||||
|
return cr, false, true, nil
|
||||||
|
}
|
||||||
|
return cr, false, false, err
|
||||||
|
}
|
||||||
|
return cr, false, false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// prepareCellRange checking and convert cell reference to a cell range.
|
||||||
|
func (cr *cellRange) prepareCellRange(col, row bool, cellRef cellRef) error {
|
||||||
|
if col {
|
||||||
|
cellRef.Row = TotalRows
|
||||||
|
}
|
||||||
|
if row {
|
||||||
|
cellRef.Col = MaxColumns
|
||||||
|
}
|
||||||
|
if cellRef.Sheet == "" {
|
||||||
|
cellRef.Sheet = cr.From.Sheet
|
||||||
|
}
|
||||||
|
if cr.From.Sheet != cellRef.Sheet || cr.To.Sheet != cellRef.Sheet {
|
||||||
|
return errors.New("invalid reference")
|
||||||
|
}
|
||||||
|
if cr.From.Col > cellRef.Col {
|
||||||
|
cr.From.Col = cellRef.Col
|
||||||
|
}
|
||||||
|
if cr.From.Row > cellRef.Row {
|
||||||
|
cr.From.Row = cellRef.Row
|
||||||
|
}
|
||||||
|
if cr.To.Col < cellRef.Col {
|
||||||
|
cr.To.Col = cellRef.Col
|
||||||
|
}
|
||||||
|
if cr.To.Row < cellRef.Row {
|
||||||
|
cr.To.Row = cellRef.Row
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// parseReference parse reference and extract values by given reference
|
// parseReference parse reference and extract values by given reference
|
||||||
// characters and default sheet name.
|
// characters and default sheet name.
|
||||||
func (f *File) parseReference(ctx *calcContext, sheet, reference string) (arg formulaArg, err error) {
|
func (f *File) parseReference(ctx *calcContext, sheet, reference string) (formulaArg, error) {
|
||||||
reference = strings.ReplaceAll(reference, "$", "")
|
reference = strings.ReplaceAll(reference, "$", "")
|
||||||
refs, cellRanges, cellRefs := list.New(), list.New(), list.New()
|
ranges, cellRanges, cellRefs := strings.Split(reference, ":"), list.New(), list.New()
|
||||||
for _, ref := range strings.Split(reference, ":") {
|
if len(ranges) > 1 {
|
||||||
tokens := strings.Split(ref, "!")
|
var cr cellRange
|
||||||
cr := cellRef{}
|
for i, ref := range ranges {
|
||||||
if len(tokens) == 2 { // have a worksheet name
|
cellRef, col, row, err := f.parseRef(ref)
|
||||||
cr.Sheet = tokens[0]
|
if err != nil {
|
||||||
// cast to cell reference
|
return newErrorFormulaArg(formulaErrorNAME, "invalid reference"), errors.New("invalid reference")
|
||||||
if cr.Col, cr.Row, err = CellNameToCoordinates(tokens[1]); err != nil {
|
}
|
||||||
// cast to column
|
if i == 0 {
|
||||||
if cr.Col, err = ColumnNameToNumber(tokens[1]); err != nil {
|
if col {
|
||||||
// cast to row
|
cellRef.Row = 1
|
||||||
if cr.Row, err = strconv.Atoi(tokens[1]); err != nil {
|
|
||||||
err = newInvalidColumnNameError(tokens[1])
|
|
||||||
return
|
|
||||||
}
|
|
||||||
cr.Col = MaxColumns
|
|
||||||
}
|
}
|
||||||
}
|
if row {
|
||||||
if refs.Len() > 0 {
|
cellRef.Col = 1
|
||||||
e := refs.Back()
|
|
||||||
cellRefs.PushBack(e.Value.(cellRef))
|
|
||||||
refs.Remove(e)
|
|
||||||
}
|
|
||||||
refs.PushBack(cr)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
// cast to cell reference
|
|
||||||
if cr.Col, cr.Row, err = CellNameToCoordinates(tokens[0]); err != nil {
|
|
||||||
// cast to column
|
|
||||||
if cr.Col, err = ColumnNameToNumber(tokens[0]); err != nil {
|
|
||||||
// cast to row
|
|
||||||
if cr.Row, err = strconv.Atoi(tokens[0]); err != nil {
|
|
||||||
err = newInvalidColumnNameError(tokens[0])
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
cr.Col = MaxColumns
|
if cellRef.Sheet == "" {
|
||||||
|
cellRef.Sheet = sheet
|
||||||
|
}
|
||||||
|
cr.From, cr.To = cellRef, cellRef
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if err := cr.prepareCellRange(col, row, cellRef); err != nil {
|
||||||
|
return newErrorFormulaArg(formulaErrorNAME, err.Error()), err
|
||||||
}
|
}
|
||||||
cellRanges.PushBack(cellRange{
|
|
||||||
From: cellRef{Sheet: sheet, Col: cr.Col, Row: 1},
|
|
||||||
To: cellRef{Sheet: sheet, Col: cr.Col, Row: TotalRows},
|
|
||||||
})
|
|
||||||
cellRefs.Init()
|
|
||||||
arg, err = f.rangeResolver(ctx, cellRefs, cellRanges)
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
e := refs.Back()
|
cellRanges.PushBack(cr)
|
||||||
if e == nil {
|
return f.rangeResolver(ctx, cellRefs, cellRanges)
|
||||||
cr.Sheet = sheet
|
|
||||||
refs.PushBack(cr)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
cellRanges.PushBack(cellRange{
|
|
||||||
From: e.Value.(cellRef),
|
|
||||||
To: cr,
|
|
||||||
})
|
|
||||||
refs.Remove(e)
|
|
||||||
}
|
}
|
||||||
if refs.Len() > 0 {
|
cellRef, _, _, err := f.parseRef(reference)
|
||||||
e := refs.Back()
|
if err != nil {
|
||||||
cellRefs.PushBack(e.Value.(cellRef))
|
return newErrorFormulaArg(formulaErrorNAME, "invalid reference"), errors.New("invalid reference")
|
||||||
refs.Remove(e)
|
|
||||||
}
|
}
|
||||||
arg, err = f.rangeResolver(ctx, cellRefs, cellRanges)
|
if cellRef.Sheet == "" {
|
||||||
return
|
cellRef.Sheet = sheet
|
||||||
|
}
|
||||||
|
cellRefs.PushBack(cellRef)
|
||||||
|
return f.rangeResolver(ctx, cellRefs, cellRanges)
|
||||||
}
|
}
|
||||||
|
|
||||||
// prepareValueRange prepare value range.
|
// prepareValueRange prepare value range.
|
||||||
|
@ -1598,9 +1617,6 @@ func (f *File) rangeResolver(ctx *calcContext, cellRefs, cellRanges *list.List)
|
||||||
// prepare value range
|
// prepare value range
|
||||||
for temp := cellRanges.Front(); temp != nil; temp = temp.Next() {
|
for temp := cellRanges.Front(); temp != nil; temp = temp.Next() {
|
||||||
cr := temp.Value.(cellRange)
|
cr := temp.Value.(cellRange)
|
||||||
if cr.From.Sheet != cr.To.Sheet {
|
|
||||||
err = errors.New(formulaErrorVALUE)
|
|
||||||
}
|
|
||||||
rng := []int{cr.From.Col, cr.From.Row, cr.To.Col, cr.To.Row}
|
rng := []int{cr.From.Col, cr.From.Row, cr.To.Col, cr.To.Row}
|
||||||
_ = sortCoordinates(rng)
|
_ = sortCoordinates(rng)
|
||||||
cr.From.Col, cr.From.Row, cr.To.Col, cr.To.Row = rng[0], rng[1], rng[2], rng[3]
|
cr.From.Col, cr.From.Row, cr.To.Col, cr.To.Row = rng[0], rng[1], rng[2], rng[3]
|
||||||
|
@ -14155,18 +14171,9 @@ func calcColumnsMinMax(argsList *list.List) (min, max int) {
|
||||||
if min == 0 {
|
if min == 0 {
|
||||||
min = cr.Value.(cellRange).From.Col
|
min = cr.Value.(cellRange).From.Col
|
||||||
}
|
}
|
||||||
if min > cr.Value.(cellRange).From.Col {
|
|
||||||
min = cr.Value.(cellRange).From.Col
|
|
||||||
}
|
|
||||||
if min > cr.Value.(cellRange).To.Col {
|
|
||||||
min = cr.Value.(cellRange).To.Col
|
|
||||||
}
|
|
||||||
if max < cr.Value.(cellRange).To.Col {
|
if max < cr.Value.(cellRange).To.Col {
|
||||||
max = cr.Value.(cellRange).To.Col
|
max = cr.Value.(cellRange).To.Col
|
||||||
}
|
}
|
||||||
if max < cr.Value.(cellRange).From.Col {
|
|
||||||
max = cr.Value.(cellRange).From.Col
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if argsList.Front().Value.(formulaArg).cellRefs != nil && argsList.Front().Value.(formulaArg).cellRefs.Len() > 0 {
|
if argsList.Front().Value.(formulaArg).cellRefs != nil && argsList.Front().Value.(formulaArg).cellRefs.Len() > 0 {
|
||||||
|
@ -14175,9 +14182,6 @@ func calcColumnsMinMax(argsList *list.List) (min, max int) {
|
||||||
if min == 0 {
|
if min == 0 {
|
||||||
min = refs.Value.(cellRef).Col
|
min = refs.Value.(cellRef).Col
|
||||||
}
|
}
|
||||||
if min > refs.Value.(cellRef).Col {
|
|
||||||
min = refs.Value.(cellRef).Col
|
|
||||||
}
|
|
||||||
if max < refs.Value.(cellRef).Col {
|
if max < refs.Value.(cellRef).Col {
|
||||||
max = refs.Value.(cellRef).Col
|
max = refs.Value.(cellRef).Col
|
||||||
}
|
}
|
||||||
|
@ -14936,18 +14940,9 @@ func calcRowsMinMax(argsList *list.List) (min, max int) {
|
||||||
if min == 0 {
|
if min == 0 {
|
||||||
min = cr.Value.(cellRange).From.Row
|
min = cr.Value.(cellRange).From.Row
|
||||||
}
|
}
|
||||||
if min > cr.Value.(cellRange).From.Row {
|
|
||||||
min = cr.Value.(cellRange).From.Row
|
|
||||||
}
|
|
||||||
if min > cr.Value.(cellRange).To.Row {
|
|
||||||
min = cr.Value.(cellRange).To.Row
|
|
||||||
}
|
|
||||||
if max < cr.Value.(cellRange).To.Row {
|
if max < cr.Value.(cellRange).To.Row {
|
||||||
max = cr.Value.(cellRange).To.Row
|
max = cr.Value.(cellRange).To.Row
|
||||||
}
|
}
|
||||||
if max < cr.Value.(cellRange).From.Row {
|
|
||||||
max = cr.Value.(cellRange).From.Row
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if argsList.Front().Value.(formulaArg).cellRefs != nil && argsList.Front().Value.(formulaArg).cellRefs.Len() > 0 {
|
if argsList.Front().Value.(formulaArg).cellRefs != nil && argsList.Front().Value.(formulaArg).cellRefs.Len() > 0 {
|
||||||
|
@ -14956,9 +14951,6 @@ func calcRowsMinMax(argsList *list.List) (min, max int) {
|
||||||
if min == 0 {
|
if min == 0 {
|
||||||
min = refs.Value.(cellRef).Row
|
min = refs.Value.(cellRef).Row
|
||||||
}
|
}
|
||||||
if min > refs.Value.(cellRef).Row {
|
|
||||||
min = refs.Value.(cellRef).Row
|
|
||||||
}
|
|
||||||
if max < refs.Value.(cellRef).Row {
|
if max < refs.Value.(cellRef).Row {
|
||||||
max = refs.Value.(cellRef).Row
|
max = refs.Value.(cellRef).Row
|
||||||
}
|
}
|
||||||
|
|
48
calc_test.go
48
calc_test.go
|
@ -2409,7 +2409,7 @@ func TestCalcCellValue(t *testing.T) {
|
||||||
// ABS
|
// ABS
|
||||||
"=ABS()": {"#VALUE!", "ABS requires 1 numeric argument"},
|
"=ABS()": {"#VALUE!", "ABS requires 1 numeric argument"},
|
||||||
"=ABS(\"X\")": {"#VALUE!", "strconv.ParseFloat: parsing \"X\": invalid syntax"},
|
"=ABS(\"X\")": {"#VALUE!", "strconv.ParseFloat: parsing \"X\": invalid syntax"},
|
||||||
"=ABS(~)": {"", newInvalidColumnNameError("~").Error()},
|
"=ABS(~)": {"#NAME?", "invalid reference"},
|
||||||
// ACOS
|
// ACOS
|
||||||
"=ACOS()": {"#VALUE!", "ACOS requires 1 numeric argument"},
|
"=ACOS()": {"#VALUE!", "ACOS requires 1 numeric argument"},
|
||||||
"=ACOS(\"X\")": {"#VALUE!", "strconv.ParseFloat: parsing \"X\": invalid syntax"},
|
"=ACOS(\"X\")": {"#VALUE!", "strconv.ParseFloat: parsing \"X\": invalid syntax"},
|
||||||
|
@ -3794,17 +3794,19 @@ func TestCalcCellValue(t *testing.T) {
|
||||||
"=CHOOSE(2,0)": {"#VALUE!", "index_num should be <= to the number of values"},
|
"=CHOOSE(2,0)": {"#VALUE!", "index_num should be <= to the number of values"},
|
||||||
"=CHOOSE(1,NA())": {"#N/A", "#N/A"},
|
"=CHOOSE(1,NA())": {"#N/A", "#N/A"},
|
||||||
// COLUMN
|
// COLUMN
|
||||||
"=COLUMN(1,2)": {"#VALUE!", "COLUMN requires at most 1 argument"},
|
"=COLUMN(1,2)": {"#VALUE!", "COLUMN requires at most 1 argument"},
|
||||||
"=COLUMN(\"\")": {"#VALUE!", "invalid reference"},
|
"=COLUMN(\"\")": {"#VALUE!", "invalid reference"},
|
||||||
"=COLUMN(Sheet1)": {"", newInvalidColumnNameError("Sheet1").Error()},
|
"=COLUMN(Sheet1)": {"#NAME?", "invalid reference"},
|
||||||
"=COLUMN(Sheet1!A1!B1)": {"", newInvalidColumnNameError("Sheet1").Error()},
|
"=COLUMN(Sheet1!A1!B1)": {"#NAME?", "invalid reference"},
|
||||||
|
"=COLUMN(Sheet1!A1:Sheet2!A2)": {"#NAME?", "invalid reference"},
|
||||||
|
"=COLUMN(Sheet1!A1:1A)": {"#NAME?", "invalid reference"},
|
||||||
// COLUMNS
|
// COLUMNS
|
||||||
"=COLUMNS()": {"#VALUE!", "COLUMNS requires 1 argument"},
|
"=COLUMNS()": {"#VALUE!", "COLUMNS requires 1 argument"},
|
||||||
"=COLUMNS(1)": {"#VALUE!", "invalid reference"},
|
"=COLUMNS(1)": {"#VALUE!", "invalid reference"},
|
||||||
"=COLUMNS(\"\")": {"#VALUE!", "invalid reference"},
|
"=COLUMNS(\"\")": {"#VALUE!", "invalid reference"},
|
||||||
"=COLUMNS(Sheet1)": {"", newInvalidColumnNameError("Sheet1").Error()},
|
"=COLUMNS(Sheet1)": {"#NAME?", "invalid reference"},
|
||||||
"=COLUMNS(Sheet1!A1!B1)": {"", newInvalidColumnNameError("Sheet1").Error()},
|
"=COLUMNS(Sheet1!A1!B1)": {"#NAME?", "invalid reference"},
|
||||||
"=COLUMNS(Sheet1!Sheet1)": {"", newInvalidColumnNameError("Sheet1").Error()},
|
"=COLUMNS(Sheet1!Sheet1)": {"#NAME?", "invalid reference"},
|
||||||
// FORMULATEXT
|
// FORMULATEXT
|
||||||
"=FORMULATEXT()": {"#VALUE!", "FORMULATEXT requires 1 argument"},
|
"=FORMULATEXT()": {"#VALUE!", "FORMULATEXT requires 1 argument"},
|
||||||
"=FORMULATEXT(1)": {"#VALUE!", "#VALUE!"},
|
"=FORMULATEXT(1)": {"#VALUE!", "#VALUE!"},
|
||||||
|
@ -3874,15 +3876,15 @@ func TestCalcCellValue(t *testing.T) {
|
||||||
// ROW
|
// ROW
|
||||||
"=ROW(1,2)": {"#VALUE!", "ROW requires at most 1 argument"},
|
"=ROW(1,2)": {"#VALUE!", "ROW requires at most 1 argument"},
|
||||||
"=ROW(\"\")": {"#VALUE!", "invalid reference"},
|
"=ROW(\"\")": {"#VALUE!", "invalid reference"},
|
||||||
"=ROW(Sheet1)": {"", newInvalidColumnNameError("Sheet1").Error()},
|
"=ROW(Sheet1)": {"#NAME?", "invalid reference"},
|
||||||
"=ROW(Sheet1!A1!B1)": {"", newInvalidColumnNameError("Sheet1").Error()},
|
"=ROW(Sheet1!A1!B1)": {"#NAME?", "invalid reference"},
|
||||||
// ROWS
|
// ROWS
|
||||||
"=ROWS()": {"#VALUE!", "ROWS requires 1 argument"},
|
"=ROWS()": {"#VALUE!", "ROWS requires 1 argument"},
|
||||||
"=ROWS(1)": {"#VALUE!", "invalid reference"},
|
"=ROWS(1)": {"#VALUE!", "invalid reference"},
|
||||||
"=ROWS(\"\")": {"#VALUE!", "invalid reference"},
|
"=ROWS(\"\")": {"#VALUE!", "invalid reference"},
|
||||||
"=ROWS(Sheet1)": {"", newInvalidColumnNameError("Sheet1").Error()},
|
"=ROWS(Sheet1)": {"#NAME?", "invalid reference"},
|
||||||
"=ROWS(Sheet1!A1!B1)": {"", newInvalidColumnNameError("Sheet1").Error()},
|
"=ROWS(Sheet1!A1!B1)": {"#NAME?", "invalid reference"},
|
||||||
"=ROWS(Sheet1!Sheet1)": {"", newInvalidColumnNameError("Sheet1").Error()},
|
"=ROWS(Sheet1!Sheet1)": {"#NAME?", "invalid reference"},
|
||||||
// Web Functions
|
// Web Functions
|
||||||
// ENCODEURL
|
// ENCODEURL
|
||||||
"=ENCODEURL()": {"#VALUE!", "ENCODEURL requires 1 argument"},
|
"=ENCODEURL()": {"#VALUE!", "ENCODEURL requires 1 argument"},
|
||||||
|
@ -4376,6 +4378,7 @@ func TestCalcCellValue(t *testing.T) {
|
||||||
// SUM
|
// SUM
|
||||||
"=A1/A3": "0.333333333333333",
|
"=A1/A3": "0.333333333333333",
|
||||||
"=SUM(A1:A2)": "3",
|
"=SUM(A1:A2)": "3",
|
||||||
|
"=SUM(Sheet1!A1:Sheet1!A2)": "3",
|
||||||
"=SUM(Sheet1!A1,A2)": "3",
|
"=SUM(Sheet1!A1,A2)": "3",
|
||||||
"=(-2-SUM(-4+A2))*5": "0",
|
"=(-2-SUM(-4+A2))*5": "0",
|
||||||
"=SUM(Sheet1!A1:Sheet1!A1:A2,A2)": "5",
|
"=SUM(Sheet1!A1:Sheet1!A1:A2,A2)": "5",
|
||||||
|
@ -5549,8 +5552,7 @@ func TestCalcSHEETS(t *testing.T) {
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
formulaList := map[string]string{
|
formulaList := map[string]string{
|
||||||
"=SHEETS(Sheet1!A1:B1)": "1",
|
"=SHEETS(Sheet1!A1:B1)": "1",
|
||||||
"=SHEETS(Sheet1!A1:Sheet1!A1)": "1",
|
"=SHEETS(Sheet1!A1:Sheet1!B1)": "1",
|
||||||
"=SHEETS(Sheet1!A1:Sheet2!A1)": "2",
|
|
||||||
}
|
}
|
||||||
for formula, expected := range formulaList {
|
for formula, expected := range formulaList {
|
||||||
assert.NoError(t, f.SetCellFormula("Sheet1", "A1", formula))
|
assert.NoError(t, f.SetCellFormula("Sheet1", "A1", formula))
|
||||||
|
@ -5905,3 +5907,19 @@ func TestCalcCellResolver(t *testing.T) {
|
||||||
assert.Equal(t, expected, result, formula)
|
assert.Equal(t, expected, result, formula)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestEvalInfixExp(t *testing.T) {
|
||||||
|
f := NewFile()
|
||||||
|
arg, err := f.evalInfixExp(nil, "Sheet1", "A1", []efp.Token{
|
||||||
|
{TSubType: efp.TokenSubTypeRange, TValue: "1A"},
|
||||||
|
})
|
||||||
|
assert.Equal(t, arg, newEmptyFormulaArg())
|
||||||
|
assert.Equal(t, formulaErrorNAME, err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestParseToken(t *testing.T) {
|
||||||
|
f := NewFile()
|
||||||
|
assert.Equal(t, formulaErrorNAME, f.parseToken(nil, "Sheet1",
|
||||||
|
efp.Token{TSubType: efp.TokenSubTypeRange, TValue: "1A"}, nil, nil,
|
||||||
|
).Error())
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue