Description
The bug
Calling Callculation::resizeMatricesExtend()
with matrices of different sizes overwrites all rows in the smaller matrix with the value found in the last row. I haven't found the expected behaviour of the method (comments of the method don't specify it), but I think the idea was to extend the smaller matrix with values found in the last row, not to overwrite all of it with the value found in the last row.
Example:
<?php
declare(strict_types=1);
require __DIR__ . '/vendor/autoload.php';
use PhpOffice\PhpSpreadsheet\Calculation\Calculation;
// Sample matrices to test with
$matrix1 = [[1], [3]];
$matrix2 = [[5], [8], [11]];
// Use reflection to make the protected method accessible
$calculation = new Calculation();
$reflectionMethod = new ReflectionMethod(Calculation::class, 'resizeMatricesExtend');
$reflectionMethod->setAccessible(true);
// Call the method using reflection
$reflectionMethod->invokeArgs($calculation, [&$matrix1, &$matrix2, count($matrix1), 1, count($matrix2), 1]);
echo "Matrix 1 after:\n";
print_r($matrix1);
(Presumably) Expected output:
$matrix1 = [ [1], [3], [3] ];
Actual output
$matrix1 = [ [3], [3], [3] ];
Relevant code:
PhpSpreadsheet/src/PhpSpreadsheet/Calculation/Calculation.php
Lines 871 to 876 in fb2cfed
Note that the analogous code for columns does not overwrite the previous columns, it extends them with the last value:
PhpSpreadsheet/src/PhpSpreadsheet/Calculation/Calculation.php
Lines 863 to 870 in fb2cfed
Proposed change
if ($matrix1Rows < $matrix2Rows) {
$x = $matrix1[$matrix1Rows - 1];
for ($i = matrix1Rows ; $i < $matrix2Rows; ++$i) {
$matrix1[$i] = $x;
}
}
Please note that analogous change should be done for case where $matrix2Rows < $matrix1Rows
.
I can create a PR if the change is accepted.
Why it matters
We found that some formulas that work for us in Excel result in #CALC!
in PhpSpreadsheet. As an example, the following type of formulas result in #CALC!
: =FILTER(Products!M:M;(Products!K:K=D5)*(Products!L:L=E5))
. Products!K:K=D5
and Products!L:L=E5
generate matrices of different sizes (for whatever reason). PhpSpreadsheet extends the smaller matrix and overwrites all of its values. In effect, FILTER()
fails to match any rows and results in #CALC!
Expected result
I don't know if the above behaviour is expected, but I suspect it's a bug. I haven't found any description of this behaviour. If it's not a bug, documenting it might be a good idea.