Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions docs/references/function-list-by-category.md
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,8 @@ RTD | **Not yet Implemented**
SORT | \PhpOffice\PhpSpreadsheet\Calculation\LookupRef\Sort::sort
SORTBY | \PhpOffice\PhpSpreadsheet\Calculation\LookupRef\Sort::sortBy
TAKE | \PhpOffice\PhpSpreadsheet\Calculation\LookupRef\ChooseRowsEtc::take
TOCOL | \PhpOffice\PhpSpreadsheet\Calculation\LookupRef\TorowTocol::tocol
TOROW | \PhpOffice\PhpSpreadsheet\Calculation\LookupRef\TorowTocol::torow
TRANSPOSE | \PhpOffice\PhpSpreadsheet\Calculation\LookupRef\Matrix::transpose
UNIQUE | \PhpOffice\PhpSpreadsheet\Calculation\LookupRef\Unique::unique
VLOOKUP | \PhpOffice\PhpSpreadsheet\Calculation\LookupRef\VLookup::lookup
Expand Down Expand Up @@ -357,8 +359,6 @@ SUMX2PY2 | \PhpOffice\PhpSpreadsheet\Calculation\MathTrig\SumSqu
SUMXMY2 | \PhpOffice\PhpSpreadsheet\Calculation\MathTrig\SumSquares::sumXMinusYSquared
TAN | \PhpOffice\PhpSpreadsheet\Calculation\MathTrig\Trig\Tangent::tan
TANH | \PhpOffice\PhpSpreadsheet\Calculation\MathTrig\Trig\Tangent::tanh
TOCOL | **Not yet Implemented**
TOROW | **Not yet Implemented**
TRUNC | \PhpOffice\PhpSpreadsheet\Calculation\MathTrig\Trunc::evaluate
VSTACK | **Not yet Implemented**
WRAPCOLS | **Not yet Implemented**
Expand Down
4 changes: 2 additions & 2 deletions docs/references/function-list-by-name-compact.md
Original file line number Diff line number Diff line change
Expand Up @@ -583,9 +583,9 @@ THAIYEAR | DATE_AND_TIME | **Not yet Implemented**
TIME | DATE_AND_TIME | DateTimeExcel\Time::fromHMS
TIMEVALUE | DATE_AND_TIME | DateTimeExcel\TimeValue::fromString
TINV | STATISTICAL | Statistical\Distributions\StudentT::inverse
TOCOL | MATH_AND_TRIG | **Not yet Implemented**
TOCOL | LOOKUP_AND_REFERENCE | LookupRef\TorowTocol::tocol
TODAY | DATE_AND_TIME | DateTimeExcel\Current::today
TOROW | MATH_AND_TRIG | **Not yet Implemented**
TOROW | LOOKUP_AND_REFERENCE | LookupRef\TorowTocol::torow
TRANSPOSE | LOOKUP_AND_REFERENCE | LookupRef\Matrix::transpose
TREND | STATISTICAL | Statistical\Trends::TREND
TRIM | TEXT_AND_DATA | TextData\Trim::spaces
Expand Down
4 changes: 2 additions & 2 deletions docs/references/function-list-by-name.md
Original file line number Diff line number Diff line change
Expand Up @@ -579,9 +579,9 @@ THAIYEAR | CATEGORY_DATE_AND_TIME | **Not yet Implemente
TIME | CATEGORY_DATE_AND_TIME | \PhpOffice\PhpSpreadsheet\Calculation\DateTimeExcel\Time::fromHMS
TIMEVALUE | CATEGORY_DATE_AND_TIME | \PhpOffice\PhpSpreadsheet\Calculation\DateTimeExcel\TimeValue::fromString
TINV | CATEGORY_STATISTICAL | \PhpOffice\PhpSpreadsheet\Calculation\Statistical\Distributions\StudentT::inverse
TOCOL | CATEGORY_MATH_AND_TRIG | **Not yet Implemented**
TOCOL | CATEGORY_LOOKUP_AND_REFERENCE | \PhpOffice\PhpSpreadsheet\Calculation\LookupRef\TorowTocol::tocol
TODAY | CATEGORY_DATE_AND_TIME | \PhpOffice\PhpSpreadsheet\Calculation\DateTimeExcel\Current::today
TOROW | CATEGORY_MATH_AND_TRIG | **Not yet Implemented**
TOROW | CATEGORY_LOOKUP_AND_REFERENCE | \PhpOffice\PhpSpreadsheet\Calculation\LookupRef\TorowTocol::torow
TRANSPOSE | CATEGORY_LOOKUP_AND_REFERENCE | \PhpOffice\PhpSpreadsheet\Calculation\LookupRef\Matrix::transpose
TREND | CATEGORY_STATISTICAL | \PhpOffice\PhpSpreadsheet\Calculation\Statistical\Trends::TREND
TRIM | CATEGORY_TEXT_AND_DATA | \PhpOffice\PhpSpreadsheet\Calculation\TextData\Trim::spaces
Expand Down
8 changes: 4 additions & 4 deletions src/PhpSpreadsheet/Calculation/FunctionArray.php
Original file line number Diff line number Diff line change
Expand Up @@ -2439,13 +2439,13 @@ class FunctionArray extends CalculationBase
'argumentCount' => '0',
],
'TOCOL' => [
'category' => Category::CATEGORY_MATH_AND_TRIG,
'functionCall' => [Functions::class, 'DUMMY'],
'category' => Category::CATEGORY_LOOKUP_AND_REFERENCE,
'functionCall' => [LookupRef\TorowTocol::class, 'tocol'],
'argumentCount' => '1-3',
],
'TOROW' => [
'category' => Category::CATEGORY_MATH_AND_TRIG,
'functionCall' => [Functions::class, 'DUMMY'],
'category' => Category::CATEGORY_LOOKUP_AND_REFERENCE,
'functionCall' => [LookupRef\TorowTocol::class, 'torow'],
'argumentCount' => '1-3',
],
'TRANSPOSE' => [
Expand Down
3 changes: 3 additions & 0 deletions src/PhpSpreadsheet/Calculation/LookupRef/Matrix.php
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@ public static function transpose($matrixData): array
if (!is_array($matrixData)) {
$matrixData = [[$matrixData]];
}
if (!is_array(end($matrixData))) {
$matrixData = [$matrixData];
}

$column = 0;
/** @var mixed[][] $matrixData */
Expand Down
94 changes: 94 additions & 0 deletions src/PhpSpreadsheet/Calculation/LookupRef/TorowTocol.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
<?php

namespace PhpOffice\PhpSpreadsheet\Calculation\LookupRef;

use PhpOffice\PhpSpreadsheet\Calculation\Functions;
use PhpOffice\PhpSpreadsheet\Calculation\Information\ErrorValue;
use PhpOffice\PhpSpreadsheet\Calculation\Information\ExcelError;

class TorowTocol
{
/**
* Excel function TOCOL.
*
* @return mixed[]|string
*/
public static function tocol(mixed $array, mixed $ignore = 0, mixed $byColumn = false): array|string
{
$result = self::torow($array, $ignore, $byColumn);
if (is_array($result)) {
return array_map((fn ($x) => [$x]), $result);
}

return $result;
}

/**
* Excel function TOROW.
*
* @return mixed[]|string
*/
public static function torow(mixed $array, mixed $ignore = 0, mixed $byColumn = false): array|string
{
if (!is_numeric($ignore)) {
return ExcelError::VALUE();
}
$ignore = (int) $ignore;
if ($ignore < 0 || $ignore > 3) {
return ExcelError::VALUE();
}
if (is_int($byColumn) || is_float($byColumn)) {
$byColumn = (bool) $byColumn;
}
if (!is_bool($byColumn)) {
return ExcelError::VALUE();
}
if (!is_array($array)) {
$array = [$array];
}
if ($byColumn) {
$temp = [];
foreach ($array as $row) {
if (!is_array($row)) {
$row = [$row];
}
$temp[] = Functions::flattenArray($row);
}
$array = ChooseRowsEtc::transpose($temp);
} else {
$array = Functions::flattenArray($array);
}

return self::byRow($array, $ignore);
}

/**
* @param mixed[] $array
*
* @return mixed[]
*/
private static function byRow(array $array, int $ignore): array
{
$returnMatrix = [];
foreach ($array as $row) {
if (!is_array($row)) {
$row = [$row];
}
foreach ($row as $cell) {
if ($cell === null) {
if ($ignore === 1 || $ignore === 3) {
continue;
}
$cell = 0;
} elseif (ErrorValue::isError($cell)) {
if ($ignore === 2 || $ignore === 3) {
continue;
}
}
$returnMatrix[] = $cell;
}
}

return $returnMatrix;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -95,4 +95,13 @@ protected function setArrayAsValue(): void
Calculation::RETURN_ARRAY_AS_VALUE
);
}

protected function setArrayAsArray(): void
{
$spreadsheet = $this->getSpreadsheet();
$calculation = Calculation::getInstance($spreadsheet);
$calculation->setInstanceArrayReturnType(
Calculation::RETURN_ARRAY_AS_ARRAY
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
<?php

declare(strict_types=1);

namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\LookupRef;

use PhpOffice\PhpSpreadsheet\Shared\StringHelper;
use PHPUnit\Framework\Attributes\DataProvider;

class TocolTest extends AllSetupTeardown
{
#[DataProvider('providerTocol')]
public function testTorow(mixed $expectedResult, mixed $ignore = 'omitted', mixed $byColumn = 'omitted'): void
{
$this->mightHaveException($expectedResult);
$sheet = $this->getSheet();
$this->setArrayAsArray();
if (is_string($ignore) && $ignore !== 'omitted') {
$ignore = '"' . $ignore . '"';
}
if (is_string($byColumn) && $byColumn !== 'omitted') {
$byColumn = '"' . $byColumn . '"';
}
$ignore = StringHelper::convertToString($ignore);
$byColumn = StringHelper::convertToString($byColumn, convertBool: true);
if ($ignore === 'omitted') {
$formula = '=TOCOL(A1:D3)';
} elseif ($byColumn === 'omitted') {
$formula = "=TOCOL(A1:D3,$ignore)";
} else {
$formula = "=TOCOL(A1:D3,$ignore,$byColumn)";
}

$data = [
['a-one', 'b-one', 'c-one', 'd-one'],
[null, 'b-two', 'c-two', '=2/0'],
[' ', 'b-three', 'c-three', 'd-three'],
];
$sheet->fromArray($data, null, 'A1', true);
$sheet->setCellValue('A5', $formula);
$result = $sheet->getCell('A5')->getCalculatedValue();
self::assertSame($expectedResult, $result);
}

public static function providerTocol(): array
{
return [
'defaults' => [[['a-one'], ['b-one'], ['c-one'], ['d-one'], [0], ['b-two'], ['c-two'], ['#DIV/0!'], [' '], ['b-three'], ['c-three'], ['d-three']]],
'ignore=0' => [[['a-one'], ['b-one'], ['c-one'], ['d-one'], [0], ['b-two'], ['c-two'], ['#DIV/0!'], [' '], ['b-three'], ['c-three'], ['d-three']], 0],
'ignore=1 supplied as 1.1' => [[['a-one'], ['b-one'], ['c-one'], ['d-one'], ['b-two'], ['c-two'], ['#DIV/0!'], [' '], ['b-three'], ['c-three'], ['d-three']], 1.1],
'ignore=2' => [[['a-one'], ['b-one'], ['c-one'], ['d-one'], [0], ['b-two'], ['c-two'], [' '], ['b-three'], ['c-three'], ['d-three']], 2],
'ignore=3' => [[['a-one'], ['b-one'], ['c-one'], ['d-one'], ['b-two'], ['c-two'], [' '], ['b-three'], ['c-three'], ['d-three']], 3],
'ignore=4 invalid' => ['#VALUE!', 4],
'ignore=string invalid' => ['#VALUE!', 'x'],
'by column' => [[['a-one'], [0], [' '], ['b-one'], ['b-two'], ['b-three'], ['c-one'], ['c-two'], ['c-three'], ['d-one'], ['#DIV/0!'], ['d-three']], 0, true],
'by column using float rather than bool, ignore=2' => [[['a-one'], [0], [' '], ['b-one'], ['b-two'], ['b-three'], ['c-one'], ['c-two'], ['c-three'], ['d-one'], ['d-three']], 2, 29.7],
];
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
<?php

declare(strict_types=1);

namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\LookupRef;

use PhpOffice\PhpSpreadsheet\Shared\StringHelper;
use PHPUnit\Framework\Attributes\DataProvider;

class TorowTest extends AllSetupTeardown
{
#[DataProvider('providerTorow')]
public function testTorow(mixed $expectedResult, mixed $ignore = 'omitted', mixed $byColumn = 'omitted'): void
{
$this->mightHaveException($expectedResult);
$sheet = $this->getSheet();
$this->setArrayAsArray();
if (is_string($ignore) && $ignore !== 'omitted') {
$ignore = '"' . $ignore . '"';
}
if (is_string($byColumn) && $byColumn !== 'omitted') {
$byColumn = '"' . $byColumn . '"';
}
$ignore = StringHelper::convertToString($ignore);
$byColumn = StringHelper::convertToString($byColumn, convertBool: true);
if ($ignore === 'omitted') {
$formula = '=TOROW(A1:D3)';
} elseif ($byColumn === 'omitted') {
$formula = "=TOROW(A1:D3,$ignore)";
} else {
$formula = "=TOROW(A1:D3,$ignore,$byColumn)";
}

$data = [
['a-one', 'b-one', 'c-one', 'd-one'],
[null, 'b-two', 'c-two', '=2/0'],
[' ', 'b-three', 'c-three', 'd-three'],
];
$sheet->fromArray($data, null, 'A1', true);
$sheet->setCellValue('A5', $formula);
$result = $sheet->getCell('A5')->getCalculatedValue();
self::assertSame($expectedResult, $result);
}

public static function providerTorow(): array
{
return [
'defaults' => [['a-one', 'b-one', 'c-one', 'd-one', 0, 'b-two', 'c-two', '#DIV/0!', ' ', 'b-three', 'c-three', 'd-three']],
'ignore=0' => [['a-one', 'b-one', 'c-one', 'd-one', 0, 'b-two', 'c-two', '#DIV/0!', ' ', 'b-three', 'c-three', 'd-three'], 0],
'ignore=1 supplied as 1.1' => [['a-one', 'b-one', 'c-one', 'd-one', 'b-two', 'c-two', '#DIV/0!', ' ', 'b-three', 'c-three', 'd-three'], 1.1],
'ignore=2' => [['a-one', 'b-one', 'c-one', 'd-one', 0, 'b-two', 'c-two', ' ', 'b-three', 'c-three', 'd-three'], 2],
'ignore=3' => [['a-one', 'b-one', 'c-one', 'd-one', 'b-two', 'c-two', ' ', 'b-three', 'c-three', 'd-three'], 3],
'ignore=-1 invalid' => ['#VALUE!', -1],
'ignore=string invalid' => ['#VALUE!', 'x'],
'by column' => [['a-one', 0, ' ', 'b-one', 'b-two', 'b-three', 'c-one', 'c-two', 'c-three', 'd-one', '#DIV/0!', 'd-three'], 0, true],
'by column using int rather than bool, ignore=1' => [['a-one', ' ', 'b-one', 'b-two', 'b-three', 'c-one', 'c-two', 'c-three', 'd-one', '#DIV/0!', 'd-three'], 1, -15],
];
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?php

declare(strict_types=1);

namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\LookupRef;

use PHPUnit\Framework\Attributes\DataProvider;

class TransposeOnSpreadsheetTest extends AllSetupTeardown
{
#[DataProvider('providerTRANSPOSE')]
public function testTRANSPOSE(mixed $expectedResult, mixed $matrix): void
{
$sheet = $this->getSheet();
$this->setArrayAsArray();
if (!is_array($matrix)) {
$matrix = [$matrix];
}
$sheet->fromArray($matrix, null, 'A1', true);
$highColumn = $sheet->getHighestDataColumn();
$highRow = $sheet->getHighestDataRow();
$newHighColumn = $highColumn;
++$newHighColumn;
$sheet->getCell("{$newHighColumn}1")
->setValue("=TRANSPOSE(A1:$highColumn$highRow)");
self::assertSame($expectedResult, $sheet->getCell("{$newHighColumn}1")->getCalculatedValue());
}

public static function providerTRANSPOSE(): array
{
return require 'tests/data/Calculation/LookupRef/TRANSPOSE.php';
}
}
16 changes: 16 additions & 0 deletions tests/data/Calculation/LookupRef/TRANSPOSE.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,20 @@
[[3.14]],
3.14,
],
'single row' => [
[[1], [2], [3], [4]],
[[1, 2, 3, 4]],
],
'single row 1-D' => [
[[1], [2], [3], [4]],
[1, 2, 3, 4],
],
'single column' => [
[[1, 2, 3, 4]],
[[1], [2], [3], [4]],
],
'single cell' => [
[[1]],
[[1]],
],
];