@@ -14996,6 +14996,66 @@ func (fn *formulaFuncs) HYPERLINK(argsList *list.List) formulaArg {
14996
14996
return newStringFormulaArg(argsList.Back().Value.(formulaArg).Value())
14997
14997
}
14998
14998
14999
+ // calcMatch returns the position of the value by given match type, criteria
15000
+ // and lookup array for the formula function MATCH.
15001
+ func calcMatchMatrix(vertical bool, matchType int, criteria *formulaCriteria, lookupArray [][]formulaArg) formulaArg {
15002
+ idx := -1
15003
+ var result *formulaArg
15004
+
15005
+ var calc = func(i int, arg formulaArg) bool {
15006
+ switch matchType {
15007
+ case 0:
15008
+ if ok, _ := formulaCriteriaEval(arg, criteria); ok {
15009
+ out := newNumberFormulaArg(float64(i + 1))
15010
+ result = &out
15011
+ return true
15012
+ }
15013
+ case -1:
15014
+ if ok, _ := formulaCriteriaEval(arg, &formulaCriteria{
15015
+ Type: criteriaGe, Condition: criteria.Condition,
15016
+ }); ok {
15017
+ idx = i
15018
+ return false
15019
+ }
15020
+ if criteria.Condition.Type == ArgNumber {
15021
+ return true
15022
+ }
15023
+ case 1:
15024
+ if ok, _ := formulaCriteriaEval(arg, &formulaCriteria{
15025
+ Type: criteriaLe, Condition: criteria.Condition,
15026
+ }); ok {
15027
+ idx = i
15028
+ return false
15029
+ }
15030
+ if criteria.Condition.Type == ArgNumber {
15031
+ return true
15032
+ }
15033
+ }
15034
+ return false
15035
+ }
15036
+
15037
+ if vertical {
15038
+ for i, row := range lookupArray {
15039
+ if ok := calc(i, row[0]); ok {
15040
+ break
15041
+ }
15042
+ }
15043
+ } else {
15044
+ for i, cell := range lookupArray[0] {
15045
+ if ok := calc(i, cell); ok {
15046
+ break
15047
+ }
15048
+ }
15049
+ }
15050
+ if result != nil {
15051
+ return *result
15052
+ }
15053
+ if idx == -1 {
15054
+ return newErrorFormulaArg(formulaErrorNA, formulaErrorNA)
15055
+ }
15056
+ return newNumberFormulaArg(float64(idx + 1))
15057
+ }
15058
+
14999
15059
// calcMatch returns the position of the value by given match type, criteria
15000
15060
// and lookup array for the formula function MATCH.
15001
15061
func calcMatch(matchType int, criteria *formulaCriteria, lookupArray []formulaArg) formulaArg {
@@ -15110,18 +15170,8 @@ func (fn *formulaFuncs) TRANSPOSE(argsList *list.List) formulaArg {
15110
15170
// lookupLinearSearch sequentially checks each look value of the lookup array until
15111
15171
// a match is found or the whole list has been searched.
15112
15172
func lookupLinearSearch(vertical bool, lookupValue, lookupArray, matchMode, searchMode formulaArg) (int, bool) {
15113
- var tableArray []formulaArg
15114
- if vertical {
15115
- for _, row := range lookupArray.Matrix {
15116
- tableArray = append(tableArray, row[0])
15117
- }
15118
- } else {
15119
- tableArray = lookupArray.Matrix[0]
15120
- }
15121
15173
matchIdx, wasExact := -1, false
15122
- start:
15123
- for i, cell := range tableArray {
15124
- lhs := cell
15174
+ var linearSearch = func(i int, cell, lhs formulaArg) bool {
15125
15175
if lookupValue.Type == ArgNumber {
15126
15176
if lhs = cell.ToNumber(); lhs.Type == ArgError {
15127
15177
lhs = cell
@@ -15135,12 +15185,28 @@ start:
15135
15185
matchIdx = i
15136
15186
wasExact = true
15137
15187
if searchMode.Number == searchModeLinear {
15138
- break start
15188
+ return true
15139
15189
}
15140
15190
}
15141
15191
if matchMode.Number == matchModeMinGreater || matchMode.Number == matchModeMaxLess {
15142
- matchIdx = int(calcMatch(int(matchMode.Number), formulaCriteriaParser(lookupValue), tableArray).Number)
15143
- continue
15192
+ matchIdx = int(calcMatchMatrix(vertical, int(matchMode.Number), formulaCriteriaParser(lookupValue), lookupArray.Matrix).Number)
15193
+ return false
15194
+ }
15195
+ return false
15196
+ }
15197
+
15198
+ if vertical {
15199
+ for i, row := range lookupArray.Matrix {
15200
+ lhs := row[0]
15201
+ if linearSearch(i, lhs, lhs) {
15202
+ break
15203
+ }
15204
+ }
15205
+ } else {
15206
+ for i, lhs := range lookupArray.Matrix[0] {
15207
+ if linearSearch(i, lhs, lhs) {
15208
+ break
15209
+ }
15144
15210
}
15145
15211
}
15146
15212
return matchIdx, wasExact
0 commit comments