Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 7 additions & 3 deletions adjust.go
Original file line number Diff line number Diff line change
Expand Up @@ -320,7 +320,9 @@ func adjustFormulaColumnName(name, operand string, abs, keepRelative bool, dir a
return "", operand, false, err
}
if dir == columns && col >= num {
col += offset
if col += offset; col < 1 {
col = 1
}
colName, err := ColumnNumberToName(col)
return "", operand + colName, false, err
}
Expand All @@ -334,8 +336,10 @@ func adjustFormulaRowNumber(name, operand string, abs, keepRelative bool, dir ad
}
row, _ := strconv.Atoi(name)
if dir == rows && row >= num {
row += offset
if row <= 0 || row > TotalRows {
if row += offset; row < 1 {
row = 1
}
if row > TotalRows {
return "", operand + name, false, ErrMaxRows
}
return "", operand + strconv.Itoa(row), false, nil
Expand Down
82 changes: 57 additions & 25 deletions calc.go
Original file line number Diff line number Diff line change
Expand Up @@ -11602,7 +11602,22 @@ func (fn *formulaFuncs) ISNUMBER(argsList *list.List) formulaArg {
if argsList.Len() != 1 {
return newErrorFormulaArg(formulaErrorVALUE, "ISNUMBER requires 1 argument")
}
if argsList.Front().Value.(formulaArg).Type == ArgNumber {
arg := argsList.Front().Value.(formulaArg)
if arg.Type == ArgMatrix {
var mtx [][]formulaArg
for _, row := range arg.Matrix {
var array []formulaArg
for _, val := range row {
if val.Type == ArgNumber {
array = append(array, newBoolFormulaArg(true))
}
array = append(array, newBoolFormulaArg(false))
}
mtx = append(mtx, array)
}
return newMatrixFormulaArg(mtx)
}
if arg.Type == ArgNumber {
return newBoolFormulaArg(true)
}
return newBoolFormulaArg(false)
Expand Down Expand Up @@ -11951,11 +11966,14 @@ func (fn *formulaFuncs) OR(argsList *list.List) formulaArg {
return newStringFormulaArg(strings.ToUpper(strconv.FormatBool(or)))
}
case ArgMatrix:
// TODO
return newErrorFormulaArg(formulaErrorVALUE, formulaErrorVALUE)
args := list.New()
for _, arg := range token.ToList() {
args.PushBack(arg)
}
return fn.OR(args)
}
}
return newStringFormulaArg(strings.ToUpper(strconv.FormatBool(or)))
return newBoolFormulaArg(or)
}

// SWITCH function compares a number of supplied values to a supplied test
Expand Down Expand Up @@ -13741,34 +13759,48 @@ func (fn *formulaFuncs) find(name string, argsList *list.List) formulaArg {
if args.Type != ArgList {
return args
}
findText := argsList.Front().Value.(formulaArg).Value()
findTextArg := argsList.Front().Value.(formulaArg)
withinText := argsList.Front().Next().Value.(formulaArg).Value()
startNum := int(args.List[0].Number)
if findText == "" {
return newNumberFormulaArg(float64(startNum))
}
dbcs, search := name == "FINDB" || name == "SEARCHB", name == "SEARCH" || name == "SEARCHB"
if search {
findText, withinText = strings.ToUpper(findText), strings.ToUpper(withinText)
}
offset, ok := matchPattern(findText, withinText, dbcs, startNum)
if !ok {
return newErrorFormulaArg(formulaErrorVALUE, formulaErrorVALUE)
}
result := offset
if dbcs {
var pre int
for idx := range withinText {
if pre > offset {
break
find := func(findText string) formulaArg {
if findText == "" {
return newNumberFormulaArg(float64(startNum))
}
if search {
findText, withinText = strings.ToUpper(findText), strings.ToUpper(withinText)
}
offset, ok := matchPattern(findText, withinText, dbcs, startNum)
if !ok {
return newErrorFormulaArg(formulaErrorVALUE, formulaErrorVALUE)
}
result := offset
if dbcs {
var pre int
for idx := range withinText {
if pre > offset {
break
}
if idx-pre > 1 {
result++
}
pre = idx
}
if idx-pre > 1 {
result++
}
return newNumberFormulaArg(float64(result))
}
if findTextArg.Type == ArgMatrix {
var mtx [][]formulaArg
for _, row := range findTextArg.Matrix {
var array []formulaArg
for _, findText := range row {
array = append(array, find(findText.Value()))
}
pre = idx
mtx = append(mtx, array)
}
return newMatrixFormulaArg(mtx)
}
return newNumberFormulaArg(float64(result))
return find(findTextArg.Value())
}

// LEFT function returns a specified number of characters from the start of a
Expand Down
10 changes: 6 additions & 4 deletions calc_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1451,8 +1451,9 @@ func TestCalcCellValue(t *testing.T) {
"=ISNONTEXT(\"Excelize\")": "FALSE",
"=ISNONTEXT(NA())": "TRUE",
// ISNUMBER
"=ISNUMBER(A1)": "TRUE",
"=ISNUMBER(D1)": "FALSE",
"=ISNUMBER(A1)": "TRUE",
"=ISNUMBER(D1)": "FALSE",
"=ISNUMBER(A1:B1)": "TRUE",
// ISODD
"=ISODD(A1)": "TRUE",
"=ISODD(A2)": "FALSE",
Expand Down Expand Up @@ -1526,6 +1527,7 @@ func TestCalcCellValue(t *testing.T) {
"=OR(1=2,2=3)": "FALSE",
"=OR(1=1,2=3)": "TRUE",
"=OR(\"TRUE\",\"FALSE\")": "TRUE",
"=OR(A1:B1)": "TRUE",
// SWITCH
"=SWITCH(1,1,\"A\",2,\"B\",3,\"C\",\"N\")": "A",
"=SWITCH(3,1,\"A\",2,\"B\",3,\"C\",\"N\")": "C",
Expand Down Expand Up @@ -1748,6 +1750,7 @@ func TestCalcCellValue(t *testing.T) {
"=FIND(\"\",\"Original Text\")": "1",
"=FIND(\"\",\"Original Text\",2)": "2",
"=FIND(\"s\",\"Sales\",2)": "5",
"=FIND(D1:E2,\"Month\")": "1",
// FINDB
"=FINDB(\"T\",\"Original Text\")": "10",
"=FINDB(\"t\",\"Original Text\")": "13",
Expand Down Expand Up @@ -3663,7 +3666,6 @@ func TestCalcCellValue(t *testing.T) {
"=NOT(\"\")": {"#VALUE!", "NOT expects 1 boolean or numeric argument"},
// OR
"=OR(\"text\")": {"#VALUE!", "#VALUE!"},
"=OR(A1:B1)": {"#VALUE!", "#VALUE!"},
"=OR(\"1\",\"TRUE\",\"FALSE\")": {"#VALUE!", "#VALUE!"},
"=OR()": {"#VALUE!", "OR requires at least 1 argument"},
"=OR(1" + strings.Repeat(",1", 30) + ")": {"#VALUE!", "OR accepts at most 30 arguments"},
Expand Down Expand Up @@ -4773,7 +4775,7 @@ func TestCalcOR(t *testing.T) {
})
fn := formulaFuncs{}
result := fn.OR(argsList)
assert.Equal(t, result.String, "FALSE")
assert.Equal(t, result.Value(), "FALSE")
assert.Empty(t, result.Error)
}

Expand Down