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
This commit is contained in:
Mark Baker 2022-01-29 14:32:40 +01:00 committed by GitHub
parent e7b0497237
commit 26079174a0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 166 additions and 2 deletions

View File

@ -9,6 +9,9 @@ and this project adheres to [Semantic Versioning](https://semver.org).
### Added ### 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) - 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: - Provide support for a wider range of Conditional Formatting Rules for Xlsx Reader/Writer:
- Cells Containing (cellIs) - Cells Containing (cellIs)

View File

@ -2220,8 +2220,8 @@ class Calculation
], ],
'SEQUENCE' => [ 'SEQUENCE' => [
'category' => Category::CATEGORY_MATH_AND_TRIG, 'category' => Category::CATEGORY_MATH_AND_TRIG,
'functionCall' => [Functions::class, 'DUMMY'], 'functionCall' => [MathTrig\MatrixFunctions::class, 'sequence'],
'argumentCount' => '2', 'argumentCount' => '1-4',
], ],
'SERIESSUM' => [ 'SERIESSUM' => [
'category' => Category::CATEGORY_MATH_AND_TRIG, 'category' => Category::CATEGORY_MATH_AND_TRIG,

View File

@ -42,6 +42,47 @@ class MatrixFunctions
return new Matrix($matrixData); 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. * MDETERM.
* *

View File

@ -0,0 +1,25 @@
<?php
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\MathTrig;
use PhpOffice\PhpSpreadsheet\Calculation\MathTrig;
class SequenceTest extends AllSetupTeardown
{
/**
* @dataProvider providerSEQUENCE
*
* @param mixed[] $arguments
* @param mixed[]|string $expectedResult
*/
public function testSEQUENCE(array $arguments, $expectedResult): void
{
$result = MathTrig\MatrixFunctions::sequence(...$arguments);
self::assertEquals($expectedResult, $result);
}
public function providerSEQUENCE(): array
{
return require 'tests/data/Calculation/MathTrig/SEQUENCE.php';
}
}

View File

@ -0,0 +1,95 @@
<?php
return [
[
[2, 2],
[
[1, 2],
[3, 4],
],
],
[
[2, 3],
[
[1, 2, 3],
[4, 5, 6],
],
],
[
[3, 2],
[
[1, 2],
[3, 4],
[5, 6],
],
],
[
[3],
[
[1],
[2],
[3],
],
],
[
[null, 3],
[
[1, 2, 3],
],
],
[
[3, 1, 10, 5],
[
[10],
[15],
[20],
],
],
[
[3, 2, 10, 5],
[
[10, 15],
[20, 25],
[30, 35],
],
],
[
[1, 3, 10, -5],
[
[10, 5, 0],
],
],
[
[1, 6, -10, 2],
[
[-10, -8, -6, -4, -2, 0],
],
],
[
[3, 3, -10, 2.5],
[
[-10, -7.5, -5],
[-2.5, 0, 2.5],
[5, 7.5, 10],
],
],
[
[3, 3, 10, -2.5],
[
[10, 7.5, 5],
[2.5, 0, -2.5],
[-5, -7.5, -10],
],
],
[
[2, 2, 1, 0],
[
[1, 1],
[1, 1],
],
],
[
[2, 2, 'A', 0],
'#VALUE!',
],
];