Skip to content

Commit df95a86

Browse files
authored
Merge pull request #4967 from DIReports/fix/vlookup-column-range-empty-end-column
Fix VLOOKUP #N/A with whole-column ranges when the end column contains no data
2 parents 11645d5 + 24fe547 commit df95a86

2 files changed

Lines changed: 53 additions & 1 deletion

File tree

src/PhpSpreadsheet/Calculation/Calculation.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1544,7 +1544,7 @@ private function internalParseFormula(string $formula, ?Cell $cell = null): bool
15441544
} elseif (ctype_alpha($val) && strlen($val) <= 3) {
15451545
// Column range
15461546
$stackItemType = 'Column Reference';
1547-
$endRowColRef = ($refSheet !== null) ? $refSheet->getHighestDataRow($val) : AddressRange::MAX_ROW; // Max 1,048,576 rows for Excel2007
1547+
$endRowColRef = ($refSheet !== null) ? $refSheet->getHighestDataRow() : AddressRange::MAX_ROW; // Max 1,048,576 rows for Excel2007
15481548
$val = "{$rangeWS2}{$val}{$endRowColRef}";
15491549
}
15501550
$stackItemReference = $val;

tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/VLookupTest.php

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
use PhpOffice\PhpSpreadsheet\Calculation\Calculation;
88
use PhpOffice\PhpSpreadsheet\Cell\DataType;
9+
use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
910
use PHPUnit\Framework\Attributes\DataProvider;
1011

1112
class VLookupTest extends AllSetupTeardown
@@ -91,4 +92,55 @@ public function testIssue1402(): void
9192
$worksheet->setCellValue('B5', '=VLOOKUP(A5,$A$1:$B$3,2,0)');
9293
self::assertSame('Numeric result', $worksheet->getCell('B5')->getCalculatedValue());
9394
}
95+
96+
/**
97+
* VLOOKUP with a whole-column range where the end column contains no data.
98+
* getHighestDataRow() on the empty end column returned 1, producing an
99+
* inverted range (e.g. A4:F1) that caused a #N/A result.
100+
*
101+
* @see https://github.com/PHPOffice/PhpSpreadsheet/pull/4967
102+
*/
103+
#[DataProvider('providerVlookupWholeColumnRange')]
104+
public function testVlookupWholeColumnRange(string $formula, string $expectedResult): void
105+
{
106+
$spreadsheet = $this->getSpreadsheet();
107+
108+
// Lookup sheet: col A = keys, col C = values; cols B, D, E, F are empty
109+
$lookupSheet = new Worksheet($spreadsheet, 'Sheet2');
110+
$spreadsheet->addSheet($lookupSheet, 0);
111+
$lookupSheet->fromArray([
112+
[1234, null, 'row1'],
113+
[2345, null, 'row2'],
114+
[3456, null, 'row3'],
115+
[4567, null, 'row4'],
116+
], null, 'A1');
117+
118+
// Formula sheet: C1 holds the lookup value
119+
$formulaSheet = new Worksheet($spreadsheet, 'Sheet1');
120+
$spreadsheet->addSheet($formulaSheet, 1);
121+
$formulaSheet->setCellValue('C1', 3456);
122+
$formulaSheet->setCellValue('A1', $formula);
123+
$spreadsheet->setActiveSheetIndexByName('Sheet1');
124+
125+
$result = $formulaSheet->getCell('A1')->getCalculatedValue();
126+
self::assertSame($expectedResult, $result);
127+
}
128+
129+
public static function providerVlookupWholeColumnRange(): array
130+
{
131+
return [
132+
'VLOOKUP with absolute whole-column range across sheets' => [
133+
'=VLOOKUP($C1,Sheet2!$A:$F,3,FALSE)',
134+
'row3',
135+
],
136+
'VLOOKUP with relative whole-column range across sheets' => [
137+
'=VLOOKUP($C1,Sheet2!A:F,3,FALSE)',
138+
'row3',
139+
],
140+
'VLOOKUP with mixed whole-column range across sheets' => [
141+
'=VLOOKUP($C1,Sheet2!A:$F,3,FALSE)',
142+
'row3',
143+
],
144+
];
145+
}
94146
}

0 commit comments

Comments
 (0)