Skip to content

Commit 859bef1

Browse files
authored
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
1 parent ca506ba commit 859bef1

File tree

7 files changed

+121
-3
lines changed

7 files changed

+121
-3
lines changed

docs/references/function-list-by-category.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,7 @@ FALSE | \PhpOffice\PhpSpreadsheet\Calculation\Logical::FALSE
213213
IF | \PhpOffice\PhpSpreadsheet\Calculation\Logical::statementIf
214214
IFERROR | \PhpOffice\PhpSpreadsheet\Calculation\Logical::IFERROR
215215
IFNA | \PhpOffice\PhpSpreadsheet\Calculation\Logical::IFNA
216-
IFS | **Not yet Implemented**
216+
IFS | \PhpOffice\PhpSpreadsheet\Calculation\Logical::IFS
217217
NOT | \PhpOffice\PhpSpreadsheet\Calculation\Logical::NOT
218218
OR | \PhpOffice\PhpSpreadsheet\Calculation\Logical::logicalOr
219219
SWITCH | \PhpOffice\PhpSpreadsheet\Calculation\Logical::statementSwitch

docs/references/function-list-by-name.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,7 @@ Excel Function | Category | PhpSpreadsheet Function
212212
IF | CATEGORY_LOGICAL | \PhpOffice\PhpSpreadsheet\Calculation\Logical::statementIf
213213
IFERROR | CATEGORY_LOGICAL | \PhpOffice\PhpSpreadsheet\Calculation\Logical::IFERROR
214214
IFNA | CATEGORY_LOGICAL | \PhpOffice\PhpSpreadsheet\Calculation\Logical::IFNA
215-
IFS | CATEGORY_LOGICAL | **Not yet Implemented**
215+
IFS | CATEGORY_LOGICAL | \PhpOffice\PhpSpreadsheet\Calculation\Logical::IFS
216216
IMABS | CATEGORY_ENGINEERING | \PhpOffice\PhpSpreadsheet\Calculation\Engineering::IMABS
217217
IMAGINARY | CATEGORY_ENGINEERING | \PhpOffice\PhpSpreadsheet\Calculation\Engineering::IMAGINARY
218218
IMARGUMENT | CATEGORY_ENGINEERING | \PhpOffice\PhpSpreadsheet\Calculation\Engineering::IMARGUMENT

src/PhpSpreadsheet/Calculation/Calculation.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1059,7 +1059,7 @@ class Calculation
10591059
],
10601060
'IFS' => [
10611061
'category' => Category::CATEGORY_LOGICAL,
1062-
'functionCall' => [Functions::class, 'DUMMY'],
1062+
'functionCall' => [Logical::class, 'IFS'],
10631063
'argumentCount' => '2+',
10641064
],
10651065
'IMABS' => [

src/PhpSpreadsheet/Calculation/Logical.php

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -352,4 +352,39 @@ public static function IFNA($testValue = '', $napart = '')
352352

353353
return self::statementIf(Functions::isNa($testValue), $napart, $testValue);
354354
}
355+
356+
/**
357+
* IFS.
358+
*
359+
* Excel Function:
360+
* =IFS(testValue1;returnIfTrue1;testValue2;returnIfTrue2;...;testValue_n;returnIfTrue_n)
361+
*
362+
* testValue1 ... testValue_n
363+
* Conditions to Evaluate
364+
* returnIfTrue1 ... returnIfTrue_n
365+
* Value returned if corresponding testValue (nth) was true
366+
*
367+
* @param mixed ...$arguments Statement arguments
368+
*
369+
* @return mixed|string The value of returnIfTrue_n, if testValue_n was true. #N/A if none of testValues was true
370+
*/
371+
public static function IFS(...$arguments)
372+
{
373+
if (count($arguments) % 2 != 0) {
374+
return Functions::NA();
375+
}
376+
// We use instance of Exception as a falseValue in order to prevent string collision with value in cell
377+
$falseValueException = new Exception();
378+
for ($i = 0; $i < count($arguments); $i += 2) {
379+
$testValue = ($arguments[$i] === null) ? '' : Functions::flattenSingleValue($arguments[$i]);
380+
$returnIfTrue = ($arguments[$i + 1] === null) ? '' : Functions::flattenSingleValue($arguments[$i + 1]);
381+
$result = self::statementIf($testValue, $returnIfTrue, $falseValueException);
382+
383+
if ($result !== $falseValueException) {
384+
return $result;
385+
}
386+
}
387+
388+
return Functions::NA();
389+
}
355390
}

src/PhpSpreadsheet/Calculation/functionlist.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,7 @@ HYPERLINK
163163
HYPGEOMDIST
164164
IF
165165
IFERROR
166+
IFS
166167
IMABS
167168
IMAGINARY
168169
IMARGUMENT
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<?php
2+
3+
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Logical;
4+
5+
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
6+
use PhpOffice\PhpSpreadsheet\Calculation\Logical;
7+
use PHPUnit\Framework\TestCase;
8+
9+
class IfsTest extends TestCase
10+
{
11+
protected function setUp(): void
12+
{
13+
Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL);
14+
}
15+
16+
/**
17+
* @dataProvider providerIFS
18+
*
19+
* @param mixed $expectedResult
20+
* @param mixed $args
21+
*/
22+
public function testIFS($expectedResult, ...$args): void
23+
{
24+
$result = Logical::IFS(...$args);
25+
self::assertEquals($expectedResult, $result);
26+
}
27+
28+
public function providerIFS()
29+
{
30+
return require 'tests/data/Calculation/Logical/IFS.php';
31+
}
32+
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
<?php
2+
3+
return [
4+
[
5+
'#N/A',
6+
],
7+
[
8+
1,
9+
true,
10+
1,
11+
],
12+
[
13+
'#N/A',
14+
false,
15+
1,
16+
true,
17+
],
18+
[
19+
'ABC',
20+
true,
21+
'ABC',
22+
],
23+
[
24+
'#N/A',
25+
false,
26+
false,
27+
false,
28+
1,
29+
false,
30+
'ABC',
31+
],
32+
[
33+
'ABC',
34+
false,
35+
false,
36+
false,
37+
1,
38+
true,
39+
'ABC',
40+
],
41+
[
42+
false,
43+
true,
44+
false,
45+
false,
46+
1,
47+
true,
48+
'ABC',
49+
],
50+
];

0 commit comments

Comments
 (0)