Skip to content

Commit 64bdc64

Browse files
committed
Incorrect SUMPRODUCT Calculation
Fix PHPOffice#3909. SUMPRODUCT is mishandling multi-row ranges. In Calculation/Calculation, `checkMatrixOperands` will often resize its operands. When it does so, it needs to recalculate the dimensions of each. This fixes the reported problem. Likely cause was PR PHPOffice#3260. That ticket noted the poor coverage of the code being replaced. Tests of the problem in this ticket were absent and are now added. Despite this, I note that `resizeMatricesShrink` is virtually uncovered, and `resizeMatricesExpand` has substantial gaps in its coverage. I have covered some, but not all, of the Expand gaps. I am struggling to come up with examples to fill its remaining gaps and those for Shrink. However, I will merge this fix in about a week even if I don't succeed.
1 parent d620497 commit 64bdc64

File tree

3 files changed

+36
-0
lines changed

3 files changed

+36
-0
lines changed

src/PhpSpreadsheet/Calculation/Calculation.php

+2
Original file line numberDiff line numberDiff line change
@@ -3729,6 +3729,8 @@ private static function checkMatrixOperands(mixed &$operand1, mixed &$operand2,
37293729
// Given two matrices of (potentially) unequal size, convert the larger in each dimension to match the smaller
37303730
self::resizeMatricesShrink($operand1, $operand2, $matrix1Rows, $matrix1Columns, $matrix2Rows, $matrix2Columns);
37313731
}
3732+
[$matrix1Rows, $matrix1Columns] = self::getMatrixDimensions($operand1);
3733+
[$matrix2Rows, $matrix2Columns] = self::getMatrixDimensions($operand2);
37323734

37333735
return [$matrix1Rows, $matrix1Columns, $matrix2Rows, $matrix2Columns];
37343736
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\MathTrig;
6+
7+
use PhpOffice\PhpSpreadsheet\Reader\Xlsx as XlsxReader;
8+
9+
class SumProduct2Test extends AllSetupTeardown
10+
{
11+
public function testSUMPRODUCT(): void
12+
{
13+
$file = 'tests/data/Reader/XLSX/issue.3909b.xlsx';
14+
$reader = new XlsxReader();
15+
$spreadsheet = $reader->load($file);
16+
$sheet = $spreadsheet->getActiveSheet();
17+
self::assertSame('=SUMPRODUCT(((calNames=I3)*(calTiers=$K$2))*calHours)', $sheet->getCell('K3')->getValue());
18+
self::assertSame(40, $sheet->getCell('K3')->getCalculatedValue());
19+
self::assertSame(4, $sheet->getCell('L3')->getCalculatedValue());
20+
self::assertSame(40, $sheet->getCell('M3')->getCalculatedValue());
21+
self::assertSame(4, $sheet->getCell('N3')->getCalculatedValue());
22+
self::assertSame(40, $sheet->getCell('K4')->getCalculatedValue());
23+
self::assertSame(0, $sheet->getCell('L4')->getCalculatedValue());
24+
self::assertSame(40, $sheet->getCell('M4')->getCalculatedValue());
25+
self::assertSame(0, $sheet->getCell('N4')->getCalculatedValue());
26+
self::assertSame(24, $sheet->getCell('K5')->getCalculatedValue());
27+
self::assertSame(0, $sheet->getCell('L5')->getCalculatedValue());
28+
self::assertSame(24, $sheet->getCell('M5')->getCalculatedValue());
29+
self::assertSame(0, $sheet->getCell('N5')->getCalculatedValue());
30+
self::assertSame('=SUMPRODUCT(calHours*((calNames=I3)*(calTiers=$K$2)))', $sheet->getCell('I14')->getValue());
31+
self::assertSame(40, $sheet->getCell('I14')->getCalculatedValue());
32+
$spreadsheet->disconnectWorksheets();
33+
}
34+
}
10.3 KB
Binary file not shown.

0 commit comments

Comments
 (0)