Skip to content

Conversation

@jpoz
Copy link
Contributor

@jpoz jpoz commented Dec 12, 2025

PR Details

Introduces the SORTBY array function for dynamic in-cell sorting.

Description

The SORTBY function allows sorting a given array based on the values in one or more corresponding arrays (sort keys). Each sort key can specify an ascending or descending order.

It supports multi-key sorting and adheres to Excel's sorting rules for mixed data types: numbers precede strings, strings precede errors, and blanks come last. This provides powerful data manipulation capabilities directly within formulas.

The SORTBY function is in a new file calcrange.go, my thinking there was to move the range calculations into this file, which will reduce the overall size of calc.go making it easier to work with.

Related Issue

NA

Motivation and Context

The SORTBY function is a modern Excel dynamic array function (introduced in Excel 365) that was missing from excelize's formula calculation engine. This function is essential for users who need to sort data dynamically within formulas without manually rearranging cells.

Key benefits:

  • Enables dynamic, formula-based sorting of arrays
  • Supports multi-key sorting (up to 3 sort keys) with independent ascending/descending order control
  • Follows Excel's standard type ordering for consistent behavior
  • Complements existing array functions like UNIQUE, XLOOKUP, and TRANSPOSE

This implementation was organized into a new calcrange.go file to avoid further bloating the already large calc.go file (19k+ lines), making it easier to maintain and setting a pattern for future array functions like SORT, FILTER, and SEQUENCE.

How Has This Been Tested

Test Coverage

  • TestCalcSORTBY: Comprehensive integration tests covering:

    • Single key sorting (ascending/descending)
    • Multi-key sorting (2-3 keys with mixed orders)
    • Multi-column arrays and sort keys
    • Mixed data types (numbers, strings, blanks) following Excel ordering
    • 9 success cases and 7 error cases
  • TestCompareSortbyValues: Unit tests for comparison logic:

    • Type ordering verification (Numbers < Strings < Errors < Blanks)
    • Case-insensitive string comparison ("Apple" == "apple")
    • Numeric comparison edge cases
  • TestSORTBYEdgeCases: Edge case validation:

    • Single row arrays
    • Equal values (stable sort behavior)
    • Multi-key sorting where first key values are all equal

Test Environment

  • Go 1.18+
  • All existing tests pass (TestCalcCellValue and others)
  • No regressions introduced

Validation Method

Tests use TEXTJOIN to flatten array results into comma-separated strings for easy assertion, following the pattern used by other array function tests in the codebase.

Types of changes

  • Docs change / refactoring / dependency upgrade
  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)

Checklist

  • My code follows the code style of this project.
  • My change requires a change to the documentation.
  • I have updated the documentation accordingly.
  • I have read the CONTRIBUTING document.
  • I have added tests to cover my changes.
  • All new and existing tests passed.

Introduces the `SORTBY` array function for dynamic in-cell sorting. This
function allows sorting a given array based on the values in one or more
corresponding arrays (sort keys). Each sort key can specify an ascending
or descending order.

It supports multi-key sorting and adheres to Excel's sorting rules for
mixed data types: numbers precede strings, strings precede errors, and
blanks come last. This provides powerful data manipulation capabilities
directly within formulas.
Copy link
Member

@xuri xuri left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cool! Thanks for your PR. Implement in calc.go and calc_test.go instead of introduce separate source code files.

@xuri xuri added the size/XL Denotes a PR that changes 500-999 lines, ignoring generated files. label Dec 13, 2025
The SORTBY array function and its associated helper logic have been
moved from `calcrange.go` to `calc.go`. This consolidates formula
implementation into a single, primary file.

This change simplifies the project structure by reducing the number of
files. It also places the SORTBY logic alongside other core calculation
functions, improving code organization.
@jpoz
Copy link
Contributor Author

jpoz commented Dec 14, 2025

@xuri updated 👍

Copy link
Member

@xuri xuri left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for your update, I've left some comments.

- Using existing `compareFormulaArg` function instead of introducing new `compareSortbyValues` function
- Reduce `getSortbyArgs` function's cyclomatic complexity less than 16
- Add unit test cases to improve code coverage
@xuri xuri moved this to Features in Excelize v2.10.1 Dec 14, 2025
@xuri xuri added size/L Denotes a PR that changes 100-499 lines, ignoring generated files. and removed size/XL Denotes a PR that changes 500-999 lines, ignoring generated files. labels Dec 14, 2025
@codecov
Copy link

codecov bot commented Dec 14, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 99.55%. Comparing base (418be6d) to head (064631a).
⚠️ Report is 1 commits behind head on master.

Additional details and impacted files
@@           Coverage Diff            @@
##           master    #2245    +/-   ##
========================================
  Coverage   99.55%   99.55%            
========================================
  Files          32       32            
  Lines       25778    25884   +106     
========================================
+ Hits        25663    25769   +106     
  Misses         60       60            
  Partials       55       55            
Flag Coverage Δ
unittests 99.55% <100.00%> (+<0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copy link
Member

@xuri xuri left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for your contribution. I've made some changes based on your branch, resolved code review issues.

@xuri xuri merged commit 85ebb61 into qax-os:master Dec 15, 2025
17 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/L Denotes a PR that changes 100-499 lines, ignoring generated files.

Projects

Status: Features

Development

Successfully merging this pull request may close these issues.

2 participants