Skip to content

Commit a5e47f2

Browse files
authored
Merge pull request #3879 from oleibman/emptyarginif
IF Empty Arguments
2 parents 4a77798 + e1bcab6 commit a5e47f2

File tree

3 files changed

+51
-6
lines changed

3 files changed

+51
-6
lines changed

CHANGELOG.md

+22
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,28 @@ and this project adheres to [Semantic Versioning](https://semver.org).
77

88
## 2.0.0 - 2024-01-24
99

10+
### Added
11+
12+
- Nothing
13+
14+
### Changed
15+
16+
- Nothing
17+
18+
### Deprecated
19+
20+
- Nothing
21+
22+
### Removed
23+
24+
- Nothing
25+
26+
### Fixed
27+
28+
- IF Empty Arguments. [Issue #3875](https://github.com/PHPOffice/PhpSpreadsheet/issues/3875) [Issue #2146](https://github.com/PHPOffice/PhpSpreadsheet/issues/2146) [PR #3879](https://github.com/PHPOffice/PhpSpreadsheet/pull/3879)
29+
30+
## 2.0.0 - 2024-01-04
31+
1032
### BREAKING CHANGE
1133

1234
- Typing was strengthened by leveraging native typing. This should not change any behavior. However, if you implement

src/PhpSpreadsheet/Calculation/Calculation.php

+6-5
Original file line numberDiff line numberDiff line change
@@ -1307,7 +1307,7 @@ public static function getExcelConstants(string $key): bool|null
13071307
'IF' => [
13081308
'category' => Category::CATEGORY_LOGICAL,
13091309
'functionCall' => [Logical\Conditional::class, 'statementIf'],
1310-
'argumentCount' => '1-3',
1310+
'argumentCount' => '2-3',
13111311
],
13121312
'IFERROR' => [
13131313
'category' => Category::CATEGORY_LOGICAL,
@@ -4189,7 +4189,7 @@ private function internalParseFormula(string $formula, ?Cell $cell = null): bool
41894189
// If we've a comma when we're expecting an operand, then what we actually have is a null operand;
41904190
// so push a null onto the stack
41914191
if (($expectingOperand) || (!$expectingOperator)) {
4192-
$output[] = ['type' => 'Empty Argument', 'value' => self::$excelConstants['NULL'], 'reference' => 'NULL'];
4192+
$output[] = $stack->getStackItem('Empty Argument', null, 'NULL');
41934193
}
41944194
// make sure there was a function
41954195
$d = $stack->last(2);
@@ -4436,7 +4436,7 @@ private function internalParseFormula(string $formula, ?Cell $cell = null): bool
44364436
++$index;
44374437
} elseif ($opCharacter === ')') { // miscellaneous error checking
44384438
if ($expectingOperand) {
4439-
$output[] = ['type' => 'Empty Argument', 'value' => self::$excelConstants['NULL'], 'reference' => 'NULL'];
4439+
$output[] = $stack->getStackItem('Empty Argument', null, 'NULL');
44404440
$expectingOperand = false;
44414441
$expectingOperator = true;
44424442
} else {
@@ -4996,11 +4996,12 @@ private function processTokenStack(mixed $tokens, ?string $cellID = null, ?Cell
49964996
}
49974997
}
49984998
} else {
4999-
$emptyArguments[] = ($arg['type'] === 'Empty Argument');
5000-
if ($arg['type'] === 'Empty Argument' && in_array($functionName, ['MIN', 'MINA', 'MAX', 'MAXA'], true)) {
4999+
if ($arg['type'] === 'Empty Argument' && in_array($functionName, ['MIN', 'MINA', 'MAX', 'MAXA', 'IF'], true)) {
5000+
$emptyArguments[] = false;
50015001
$args[] = $arg['value'] = 0;
50025002
$this->debugLog->writeDebugLog('Empty Argument reevaluated as 0');
50035003
} else {
5004+
$emptyArguments[] = $arg['type'] === 'Empty Argument';
50045005
$args[] = self::unwrapResult($arg['value']);
50055006
}
50065007
if ($functionName !== 'MKMATRIX') {

tests/PhpSpreadsheetTests/Calculation/MissingArgumentsTest.php

+23-1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
namespace PhpOffice\PhpSpreadsheetTests\Calculation;
66

7+
use PhpOffice\PhpSpreadsheet\Calculation\Exception as CalcExp;
78
use PhpOffice\PhpSpreadsheet\Spreadsheet;
89
use PHPUnit\Framework\TestCase;
910

@@ -17,7 +18,14 @@ public function testMissingArguments(mixed $expected, string $formula): void
1718
$spreadsheet = new Spreadsheet();
1819
$sheet = $spreadsheet->getActiveSheet();
1920
$sheet->getCell('A1')->setValue($formula);
20-
self::assertSame($expected, $sheet->getCell('A1')->getCalculatedValue());
21+
$sheet->getCell('B1')->setValue(1);
22+
23+
try {
24+
self::assertSame($expected, $sheet->getCell('A1')->getCalculatedValue());
25+
} catch (CalcExp $e) {
26+
self::assertSame('exception', $expected);
27+
}
28+
2129
$spreadsheet->disconnectWorksheets();
2230
}
2331

@@ -35,6 +43,20 @@ public static function providerMissingArguments(): array
3543
'product ignores null argument' => [6.0, '=product(3,2,)'],
3644
'embedded function' => [5, '=sum(3,2,min(3,2,))'],
3745
'unaffected embedded function' => [8, '=sum(3,2,max(3,2,))'],
46+
'if true missing at end' => [0, '=if(b1=1,min(3,2,),product(3,2,))'],
47+
'if false missing at end' => [6.0, '=if(b1=2,min(3,2,),product(3,2,))'],
48+
'if true missing in middle' => [0, '=if(b1=1,min(3,,2),product(3,,2))'],
49+
'if false missing in middle' => [6.0, '=if(b1=2,min(3,,2),product(3,,2))'],
50+
'if true missing at beginning' => [0, '=if(b1=1,min(,3,2),product(,3,2))'],
51+
'if false missing at beginning' => [6.0, '=if(b1=2,min(,3,2),product(,3,2))'],
52+
'if true nothing missing' => [2, '=if(b1=1,min(3,2),product(3,2))'],
53+
'if false nothing missing' => [6.0, '=if(b1=2,min(3,2),product(3,2))'],
54+
'if true empty arg' => [0, '=if(b1=1,)'],
55+
'if true omitted args' => ['exception', '=if(b1=1)'],
56+
'if true missing arg' => [0, '=if(b1=1,,6)'],
57+
'if false missing arg' => [0, '=if(b1=2,6,)'],
58+
'if false omitted arg' => [false, '=if(b1=2,6)'],
59+
'multiple ifs and omissions' => [0, '=IF(0<9,,IF(0=0,,1))'],
3860
];
3961
}
4062
}

0 commit comments

Comments
 (0)