@@ -14540,9 +14540,9 @@ func (fn *formulaFuncs) UNICODE(argsList *list.List) formulaArg {
1454014540// For syntax refer to
1454114541// https://support.microsoft.com/en-us/office/unique-function-c5ab87fd-30a3-4ce9-9d1a-40204fb85e1e.
1454214542func (fn *formulaFuncs) UNIQUE(argsList *list.List) formulaArg {
14543- args := getFormulaUniqueArgs(argsList)
14544- if args. errArg != nil {
14545- return *args. errArg
14543+ args, errArg := getFormulaUniqueArgs(argsList)
14544+ if errArg != nil {
14545+ return *errArg
1454614546 }
1454714547
1454814548 if args.byColumn {
@@ -14561,18 +14561,14 @@ func (fn *formulaFuncs) UNIQUE(argsList *list.List) formulaArg {
1456114561 }
1456214562
1456314563 uniqueAxes := [][]formulaArg{}
14564- added := map[string]struct{}{}
1456514564
1456614565 for i := 0; i < len(args.cellRange); i += args.cols {
1456714566 key := concatValues(args.cellRange[i : i+args.cols])
14568- if _, ok := added[key]; ok {
14569- continue
14570- }
14571- added[key] = struct{}{}
1457214567
1457314568 if (args.exactlyOnce && counts[key] == 1) || (!args.exactlyOnce && counts[key] >= 1) {
1457414569 uniqueAxes = append(uniqueAxes, args.cellRange[i:i+args.cols])
1457514570 }
14571+ delete(counts, key)
1457614572 }
1457714573
1457814574 if args.byColumn {
@@ -14622,70 +14618,67 @@ func concatValues(args []formulaArg) string {
1462214618 return val
1462314619}
1462414620
14625- type formulaUniqueArgs struct {
14621+ type uniqueArgs struct {
1462614622 cellRange []formulaArg
1462714623 cols int
1462814624 rows int
1462914625 byColumn bool
1463014626 exactlyOnce bool
14631- errArg *formulaArg
1463214627}
1463314628
14634- func getFormulaUniqueArgs(argsList *list.List) formulaUniqueArgs {
14629+ func getFormulaUniqueArgs(argsList *list.List) (uniqueArgs, *formulaArg) {
14630+ res := uniqueArgs{}
14631+
1463514632 argsLen := argsList.Len()
1463614633 if argsLen == 0 {
1463714634 errArg := newErrorFormulaArg(formulaErrorVALUE, "UNIQUE requires at least 1 argument")
14638- return formulaUniqueArgs{errArg: &errArg}
14635+ return res, &errArg
1463914636 }
1464014637
14641- argRange := argsList.Front().Value.(formulaArg).ToList()
14642- if argRange == nil || argsLen > 3 {
14638+ if argsLen > 3 {
1464314639 msg := fmt.Sprintf("UNIQUE takes at most 3 arguments, received %d arguments", argsLen)
1464414640 errArg := newErrorFormulaArg(formulaErrorVALUE, msg)
1464514641
14646- return formulaUniqueArgs{errArg: &errArg}
14642+ return res, &errArg
14643+ }
14644+
14645+ firstArg := argsList.Front()
14646+ res.cellRange = firstArg.Value.(formulaArg).ToList()
14647+ if len(res.cellRange) == 0 {
14648+ errArg := newErrorFormulaArg(formulaErrorVALUE, "missing first argument to UNIQUE")
14649+ return res, &errArg
14650+ }
14651+ if res.cellRange[0].Type == ArgError {
14652+ return res, &res.cellRange[0]
1464714653 }
1464814654
1464914655 rmin, rmax := calcColsRowsMinMax(false, argsList)
1465014656 cmin, cmax := calcColsRowsMinMax(true, argsList)
14651- cols, rows : = cmax-cmin+1, rmax-rmin+1
14657+ res. cols, res. rows = cmax-cmin+1, rmax-rmin+1
1465214658
14653- sndArg := argsList.Front().Next()
14654- if sndArg == nil {
14655- return formulaUniqueArgs{
14656- cellRange: argRange,
14657- cols: cols,
14658- rows: rows,
14659- }
14659+ secondArg := firstArg.Next()
14660+ if secondArg == nil {
14661+ return res, nil
1466014662 }
1466114663
14662- argByColumn := sndArg .Value.(formulaArg).ToBool()
14664+ argByColumn := secondArg .Value.(formulaArg).ToBool()
1466314665 if argByColumn.Type == ArgError {
14664- return formulaUniqueArgs{errArg: &argByColumn}
14666+ return res, &argByColumn
1466514667 }
14668+ res.byColumn = (argByColumn.Value() == "TRUE")
1466614669
14667- trdArg := argsList.Front().Next().Next()
14668- if trdArg == nil {
14669- return formulaUniqueArgs{
14670- cellRange: argRange,
14671- cols: cols,
14672- rows: rows,
14673- byColumn: argByColumn.Value() == "TRUE",
14674- }
14670+ thirdArg := secondArg.Next()
14671+ if thirdArg == nil {
14672+ return res, nil
1467514673 }
1467614674
14677- argExactlyOnce := trdArg .Value.(formulaArg).ToBool()
14675+ argExactlyOnce := thirdArg .Value.(formulaArg).ToBool()
1467814676 if argExactlyOnce.Type == ArgError {
14679- return formulaUniqueArgs{errArg: &argExactlyOnce}
14677+ return res, &argExactlyOnce
1468014678 }
14679+ res.exactlyOnce = (argExactlyOnce.Value() == "TRUE")
1468114680
14682- return formulaUniqueArgs{
14683- cellRange: argRange,
14684- cols: cols,
14685- rows: rows,
14686- byColumn: argByColumn.Value() == "TRUE",
14687- exactlyOnce: argExactlyOnce.Value() == "TRUE",
14688- }
14681+ return res, nil
1468914682}
1469014683
1469114684// UPPER converts all characters in a supplied text string to upper case. The
0 commit comments