Add support for IFS() logical function (#1442)

* Add support for IFS() logical function

* Use Exception as false value in IFS logical function, so it never collides with string in spreadsheet
This commit is contained in:
Dawid Warmuz 2020-06-20 18:21:19 +02:00 committed by GitHub
parent ca506ba87f
commit 859bef1901
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 121 additions and 3 deletions

View File

@ -213,7 +213,7 @@ FALSE | \PhpOffice\PhpSpreadsheet\Calculation\Logical::FALSE
IF | \PhpOffice\PhpSpreadsheet\Calculation\Logical::statementIf IF | \PhpOffice\PhpSpreadsheet\Calculation\Logical::statementIf
IFERROR | \PhpOffice\PhpSpreadsheet\Calculation\Logical::IFERROR IFERROR | \PhpOffice\PhpSpreadsheet\Calculation\Logical::IFERROR
IFNA | \PhpOffice\PhpSpreadsheet\Calculation\Logical::IFNA IFNA | \PhpOffice\PhpSpreadsheet\Calculation\Logical::IFNA
IFS | **Not yet Implemented** IFS | \PhpOffice\PhpSpreadsheet\Calculation\Logical::IFS
NOT | \PhpOffice\PhpSpreadsheet\Calculation\Logical::NOT NOT | \PhpOffice\PhpSpreadsheet\Calculation\Logical::NOT
OR | \PhpOffice\PhpSpreadsheet\Calculation\Logical::logicalOr OR | \PhpOffice\PhpSpreadsheet\Calculation\Logical::logicalOr
SWITCH | \PhpOffice\PhpSpreadsheet\Calculation\Logical::statementSwitch SWITCH | \PhpOffice\PhpSpreadsheet\Calculation\Logical::statementSwitch

View File

@ -212,7 +212,7 @@ Excel Function | Category | PhpSpreadsheet Function
IF | CATEGORY_LOGICAL | \PhpOffice\PhpSpreadsheet\Calculation\Logical::statementIf IF | CATEGORY_LOGICAL | \PhpOffice\PhpSpreadsheet\Calculation\Logical::statementIf
IFERROR | CATEGORY_LOGICAL | \PhpOffice\PhpSpreadsheet\Calculation\Logical::IFERROR IFERROR | CATEGORY_LOGICAL | \PhpOffice\PhpSpreadsheet\Calculation\Logical::IFERROR
IFNA | CATEGORY_LOGICAL | \PhpOffice\PhpSpreadsheet\Calculation\Logical::IFNA IFNA | CATEGORY_LOGICAL | \PhpOffice\PhpSpreadsheet\Calculation\Logical::IFNA
IFS | CATEGORY_LOGICAL | **Not yet Implemented** IFS | CATEGORY_LOGICAL | \PhpOffice\PhpSpreadsheet\Calculation\Logical::IFS
IMABS | CATEGORY_ENGINEERING | \PhpOffice\PhpSpreadsheet\Calculation\Engineering::IMABS IMABS | CATEGORY_ENGINEERING | \PhpOffice\PhpSpreadsheet\Calculation\Engineering::IMABS
IMAGINARY | CATEGORY_ENGINEERING | \PhpOffice\PhpSpreadsheet\Calculation\Engineering::IMAGINARY IMAGINARY | CATEGORY_ENGINEERING | \PhpOffice\PhpSpreadsheet\Calculation\Engineering::IMAGINARY
IMARGUMENT | CATEGORY_ENGINEERING | \PhpOffice\PhpSpreadsheet\Calculation\Engineering::IMARGUMENT IMARGUMENT | CATEGORY_ENGINEERING | \PhpOffice\PhpSpreadsheet\Calculation\Engineering::IMARGUMENT

View File

@ -1059,7 +1059,7 @@ class Calculation
], ],
'IFS' => [ 'IFS' => [
'category' => Category::CATEGORY_LOGICAL, 'category' => Category::CATEGORY_LOGICAL,
'functionCall' => [Functions::class, 'DUMMY'], 'functionCall' => [Logical::class, 'IFS'],
'argumentCount' => '2+', 'argumentCount' => '2+',
], ],
'IMABS' => [ 'IMABS' => [

View File

@ -352,4 +352,39 @@ class Logical
return self::statementIf(Functions::isNa($testValue), $napart, $testValue); return self::statementIf(Functions::isNa($testValue), $napart, $testValue);
} }
/**
* IFS.
*
* Excel Function:
* =IFS(testValue1;returnIfTrue1;testValue2;returnIfTrue2;...;testValue_n;returnIfTrue_n)
*
* testValue1 ... testValue_n
* Conditions to Evaluate
* returnIfTrue1 ... returnIfTrue_n
* Value returned if corresponding testValue (nth) was true
*
* @param mixed ...$arguments Statement arguments
*
* @return mixed|string The value of returnIfTrue_n, if testValue_n was true. #N/A if none of testValues was true
*/
public static function IFS(...$arguments)
{
if (count($arguments) % 2 != 0) {
return Functions::NA();
}
// We use instance of Exception as a falseValue in order to prevent string collision with value in cell
$falseValueException = new Exception();
for ($i = 0; $i < count($arguments); $i += 2) {
$testValue = ($arguments[$i] === null) ? '' : Functions::flattenSingleValue($arguments[$i]);
$returnIfTrue = ($arguments[$i + 1] === null) ? '' : Functions::flattenSingleValue($arguments[$i + 1]);
$result = self::statementIf($testValue, $returnIfTrue, $falseValueException);
if ($result !== $falseValueException) {
return $result;
}
}
return Functions::NA();
}
} }

View File

@ -163,6 +163,7 @@ HYPERLINK
HYPGEOMDIST HYPGEOMDIST
IF IF
IFERROR IFERROR
IFS
IMABS IMABS
IMAGINARY IMAGINARY
IMARGUMENT IMARGUMENT

View File

@ -0,0 +1,32 @@
<?php
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Logical;
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
use PhpOffice\PhpSpreadsheet\Calculation\Logical;
use PHPUnit\Framework\TestCase;
class IfsTest extends TestCase
{
protected function setUp(): void
{
Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL);
}
/**
* @dataProvider providerIFS
*
* @param mixed $expectedResult
* @param mixed $args
*/
public function testIFS($expectedResult, ...$args): void
{
$result = Logical::IFS(...$args);
self::assertEquals($expectedResult, $result);
}
public function providerIFS()
{
return require 'tests/data/Calculation/Logical/IFS.php';
}
}

View File

@ -0,0 +1,50 @@
<?php
return [
[
'#N/A',
],
[
1,
true,
1,
],
[
'#N/A',
false,
1,
true,
],
[
'ABC',
true,
'ABC',
],
[
'#N/A',
false,
false,
false,
1,
false,
'ABC',
],
[
'ABC',
false,
false,
false,
1,
true,
'ABC',
],
[
false,
true,
false,
false,
1,
true,
'ABC',
],
];