@@ -15285,6 +15285,56 @@ func (fn *formulaFuncs) HYPERLINK(argsList *list.List) formulaArg {
1528515285 return newStringFormulaArg(argsList.Back().Value.(formulaArg).Value())
1528615286}
1528715287
15288+ // calcMatch returns the position of the value by given match type, criteria
15289+ // and lookup array for the formula function MATCH.
15290+ // matchType only contains -1, and 1.
15291+ func calcMatchMatrix(vertical bool, matchType int, criteria *formulaCriteria, lookupArray [][]formulaArg) formulaArg {
15292+ idx := -1
15293+ var calc = func(i int, arg formulaArg) bool {
15294+ switch matchType {
15295+ case -1:
15296+ if ok, _ := formulaCriteriaEval(arg, &formulaCriteria{
15297+ Type: criteriaGe, Condition: criteria.Condition,
15298+ }); ok {
15299+ idx = i
15300+ return false
15301+ }
15302+ if criteria.Condition.Type == ArgNumber {
15303+ return true
15304+ }
15305+ case 1:
15306+ if ok, _ := formulaCriteriaEval(arg, &formulaCriteria{
15307+ Type: criteriaLe, Condition: criteria.Condition,
15308+ }); ok {
15309+ idx = i
15310+ return false
15311+ }
15312+ if criteria.Condition.Type == ArgNumber {
15313+ return true
15314+ }
15315+ }
15316+ return false
15317+ }
15318+
15319+ if vertical {
15320+ for i, row := range lookupArray {
15321+ if ok := calc(i, row[0]); ok {
15322+ break
15323+ }
15324+ }
15325+ } else {
15326+ for i, cell := range lookupArray[0] {
15327+ if ok := calc(i, cell); ok {
15328+ break
15329+ }
15330+ }
15331+ }
15332+ if idx == -1 {
15333+ return newErrorFormulaArg(formulaErrorNA, formulaErrorNA)
15334+ }
15335+ return newNumberFormulaArg(float64(idx + 1))
15336+ }
15337+
1528815338// calcMatch returns the position of the value by given match type, criteria
1528915339// and lookup array for the formula function MATCH.
1529015340func calcMatch(matchType int, criteria *formulaCriteria, lookupArray []formulaArg) formulaArg {
@@ -15399,18 +15449,8 @@ func (fn *formulaFuncs) TRANSPOSE(argsList *list.List) formulaArg {
1539915449// lookupLinearSearch sequentially checks each look value of the lookup array until
1540015450// a match is found or the whole list has been searched.
1540115451func lookupLinearSearch(vertical bool, lookupValue, lookupArray, matchMode, searchMode formulaArg) (int, bool) {
15402- var tableArray []formulaArg
15403- if vertical {
15404- for _, row := range lookupArray.Matrix {
15405- tableArray = append(tableArray, row[0])
15406- }
15407- } else {
15408- tableArray = lookupArray.Matrix[0]
15409- }
1541015452 matchIdx, wasExact := -1, false
15411- start:
15412- for i, cell := range tableArray {
15413- lhs := cell
15453+ var linearSearch = func(i int, cell, lhs formulaArg) bool {
1541415454 if lookupValue.Type == ArgNumber {
1541515455 if lhs = cell.ToNumber(); lhs.Type == ArgError {
1541615456 lhs = cell
@@ -15424,12 +15464,28 @@ start:
1542415464 matchIdx = i
1542515465 wasExact = true
1542615466 if searchMode.Number == searchModeLinear {
15427- break start
15467+ return true
1542815468 }
1542915469 }
1543015470 if matchMode.Number == matchModeMinGreater || matchMode.Number == matchModeMaxLess {
15431- matchIdx = int(calcMatch(int(matchMode.Number), formulaCriteriaParser(lookupValue), tableArray).Number)
15432- continue
15471+ matchIdx = int(calcMatchMatrix(vertical, int(matchMode.Number), formulaCriteriaParser(lookupValue), lookupArray.Matrix).Number)
15472+ return false
15473+ }
15474+ return false
15475+ }
15476+
15477+ if vertical {
15478+ for i, row := range lookupArray.Matrix {
15479+ lhs := row[0]
15480+ if linearSearch(i, lhs, lhs) {
15481+ break
15482+ }
15483+ }
15484+ } else {
15485+ for i, lhs := range lookupArray.Matrix[0] {
15486+ if linearSearch(i, lhs, lhs) {
15487+ break
15488+ }
1543315489 }
1543415490 }
1543515491 return matchIdx, wasExact
0 commit comments