From 26079174a05b8b61358698116ff1fca1f86a9950 Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Sat, 29 Jan 2022 14:32:40 +0100 Subject: [PATCH] Implementation of the SEQUENCE() Excel365 function (#2536) * Implementation of the SEQUENCE() Excel365 function Note that the Calculation Engine does not yet support the Spill operator, or spilling functions * Handle the use-case of step = 0; and tests for exception handling for invalid arguments * Update Change Log --- CHANGELOG.md | 3 + .../Calculation/Calculation.php | 4 +- .../Calculation/MathTrig/MatrixFunctions.php | 41 ++++++++ .../Functions/MathTrig/SequenceTest.php | 25 +++++ tests/data/Calculation/MathTrig/SEQUENCE.php | 95 +++++++++++++++++++ 5 files changed, 166 insertions(+), 2 deletions(-) create mode 100644 tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/SequenceTest.php create mode 100644 tests/data/Calculation/MathTrig/SEQUENCE.php diff --git a/CHANGELOG.md b/CHANGELOG.md index 58bb9a3a..433dfb6c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,9 @@ and this project adheres to [Semantic Versioning](https://semver.org). ### Added +- Support for the Excel365 Math/Trig SEQUENCE() function [PR #2536](https://github.com/PHPOffice/PhpSpreadsheet/pull/2536) + + Note that the Spill Operator is not yet supported in the Calculation Engine; but this can still be useful for defining array constants. - Improved support for Conditional Formatting Rules [PR #2491](https://github.com/PHPOffice/PhpSpreadsheet/pull/2491) - Provide support for a wider range of Conditional Formatting Rules for Xlsx Reader/Writer: - Cells Containing (cellIs) diff --git a/src/PhpSpreadsheet/Calculation/Calculation.php b/src/PhpSpreadsheet/Calculation/Calculation.php index 4f4b0607..41320a7c 100644 --- a/src/PhpSpreadsheet/Calculation/Calculation.php +++ b/src/PhpSpreadsheet/Calculation/Calculation.php @@ -2220,8 +2220,8 @@ class Calculation ], 'SEQUENCE' => [ 'category' => Category::CATEGORY_MATH_AND_TRIG, - 'functionCall' => [Functions::class, 'DUMMY'], - 'argumentCount' => '2', + 'functionCall' => [MathTrig\MatrixFunctions::class, 'sequence'], + 'argumentCount' => '1-4', ], 'SERIESSUM' => [ 'category' => Category::CATEGORY_MATH_AND_TRIG, diff --git a/src/PhpSpreadsheet/Calculation/MathTrig/MatrixFunctions.php b/src/PhpSpreadsheet/Calculation/MathTrig/MatrixFunctions.php index 92e1ff8e..4cef4625 100644 --- a/src/PhpSpreadsheet/Calculation/MathTrig/MatrixFunctions.php +++ b/src/PhpSpreadsheet/Calculation/MathTrig/MatrixFunctions.php @@ -42,6 +42,47 @@ class MatrixFunctions return new Matrix($matrixData); } + /** + * SEQUENCE. + * + * Generates a list of sequential numbers in an array. + * + * Excel Function: + * SEQUENCE(rows,[columns],[start],[step]) + * + * @param mixed $rows the number of rows to return, defaults to 1 + * @param mixed $columns the number of columns to return, defaults to 1 + * @param mixed $start the first number in the sequence, defaults to 1 + * @param mixed $step the amount to increment each subsequent value in the array, defaults to 1 + * + * @return array|string The resulting array, or a string containing an error + */ + public static function sequence($rows = 1, $columns = 1, $start = 1, $step = 1) + { + try { + $rows = (int) Helpers::validateNumericNullSubstitution($rows, 1); + Helpers::validatePositive($rows); + $columns = (int) Helpers::validateNumericNullSubstitution($columns, 1); + Helpers::validatePositive($columns); + $start = Helpers::validateNumericNullSubstitution($start, 1); + $step = Helpers::validateNumericNullSubstitution($step, 1); + } catch (Exception $e) { + return $e->getMessage(); + } + + if ($step === 0) { + return array_chunk( + array_fill(0, $rows * $columns, $start), + $columns + ); + } + + return array_chunk( + range($start, $start + (($rows * $columns - 1) * $step), $step), + $columns + ); + } + /** * MDETERM. * diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/SequenceTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/SequenceTest.php new file mode 100644 index 00000000..d2ba3345 --- /dev/null +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/SequenceTest.php @@ -0,0 +1,25 @@ +