mirror of
https://github.com/PHPOffice/PhpSpreadsheet.git
synced 2026-08-31 12:40:00 +00:00
Merge pull request #3311 from PHPOffice/StructuredReference_Invalid-Column-return-#REF!
For Structured References, an Invalid column reference should return an Excel #REF! error
This commit is contained in:
@@ -179,19 +179,28 @@ final class StructuredReference implements Operand
|
||||
|
||||
foreach ($this->columns as $columnId => $columnName) {
|
||||
$columnName = str_replace("\u{a0}", ' ', $columnName);
|
||||
$reference = $this->adjustRowReference($columnName, $reference, $cell, $columnId);
|
||||
}
|
||||
|
||||
/** @var string $reference */
|
||||
return $this->validateParsedReference(trim($reference, '[]@, '));
|
||||
}
|
||||
|
||||
private function adjustRowReference(string $columnName, string $reference, Cell $cell, string $columnId): string
|
||||
{
|
||||
if ($columnName !== '') {
|
||||
$cellReference = $columnId . $cell->getRow();
|
||||
$pattern1 = '/\[' . preg_quote($columnName) . '\]/miu';
|
||||
$pattern2 = '/@' . preg_quote($columnName) . '/miu';
|
||||
/** @var string $reference */
|
||||
if (preg_match($pattern1, $reference) === 1) {
|
||||
$reference = preg_replace($pattern1, $cellReference, $reference);
|
||||
} elseif (preg_match($pattern2, $reference) === 1) {
|
||||
$reference = preg_replace($pattern2, $cellReference, $reference);
|
||||
}
|
||||
/** @var string $reference */
|
||||
}
|
||||
|
||||
/** @var string $reference */
|
||||
return $this->validateParsedReference(trim($reference, '[]@, '));
|
||||
return $reference;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -226,7 +235,10 @@ final class StructuredReference implements Operand
|
||||
{
|
||||
if (preg_match('/^' . Calculation::CALCULATION_REGEXP_CELLREF . ':' . Calculation::CALCULATION_REGEXP_CELLREF . '$/miu', $reference) !== 1) {
|
||||
if (preg_match('/^' . Calculation::CALCULATION_REGEXP_CELLREF . '$/miu', $reference) !== 1) {
|
||||
throw new Exception("Invalid Structured Reference {$this->reference} {$reference}");
|
||||
throw new Exception(
|
||||
"Invalid Structured Reference {$this->reference} {$reference}",
|
||||
Exception::CALCULATION_ENGINE_PUSH_TO_STACK
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -198,6 +198,7 @@ class Cell
|
||||
*/
|
||||
protected static function updateIfCellIsTableHeader(Worksheet $workSheet, self $cell, $oldValue, $newValue): void
|
||||
{
|
||||
// var_dump('=>', $oldValue, $newValue);
|
||||
if (StringHelper::strToLower($oldValue ?? '') === StringHelper::strToLower($newValue ?? '')) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -205,9 +205,9 @@ class Column
|
||||
return $this;
|
||||
}
|
||||
|
||||
public static function updateStructuredReferences(?Worksheet $workSheet, ?string $oldTitle, string $newTitle): void
|
||||
public static function updateStructuredReferences(?Worksheet $workSheet, ?string $oldTitle, ?string $newTitle): void
|
||||
{
|
||||
if ($workSheet === null || $oldTitle === null || $oldTitle === '') {
|
||||
if ($workSheet === null || $oldTitle === null || $oldTitle === '' || $newTitle === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -92,6 +92,18 @@ class StructuredReferenceTest extends TestCase
|
||||
self::assertSame($expectedCellRange, $cellRange);
|
||||
}
|
||||
|
||||
public function testInvalidStructuredReferenceRow(): void
|
||||
{
|
||||
$cell = $this->spreadSheet->getActiveSheet()->getCell('E5');
|
||||
|
||||
$this->expectException(Exception::class);
|
||||
$this->expectExceptionCode(1);
|
||||
$this->expectExceptionMessage('Invalid Structured Reference');
|
||||
$this->expectExceptionCode(Exception::CALCULATION_ENGINE_PUSH_TO_STACK);
|
||||
$structuredReferenceObject = new StructuredReference('DeptSales[@[Sales]:[%age Commission]]');
|
||||
$structuredReferenceObject->parse($cell);
|
||||
}
|
||||
|
||||
public function testStructuredReferenceHeadersHidden(): void
|
||||
{
|
||||
$cell = $this->spreadSheet->getActiveSheet()->getCell('K1');
|
||||
@@ -103,11 +115,12 @@ class StructuredReferenceTest extends TestCase
|
||||
|
||||
$table->setShowHeaderRow(false);
|
||||
|
||||
self::expectException(Exception::class);
|
||||
self::expectExceptionCode(1);
|
||||
self::expectExceptionMessage('Table Headers are Hidden, and should not be Referenced');
|
||||
$this->expectException(Exception::class);
|
||||
$this->expectExceptionCode(1);
|
||||
$this->expectExceptionMessage('Table Headers are Hidden, and should not be Referenced');
|
||||
$this->expectExceptionCode(Exception::CALCULATION_ENGINE_PUSH_TO_STACK);
|
||||
$structuredReferenceObject = new StructuredReference('DeptSales[[#Headers],[% Commission]]');
|
||||
$cellRange = $structuredReferenceObject->parse($cell);
|
||||
$structuredReferenceObject->parse($cell);
|
||||
}
|
||||
|
||||
public function structuredReferenceProviderColumnData(): array
|
||||
|
||||
@@ -46,6 +46,21 @@ class StructuredReferenceFormulaTest extends TestCase
|
||||
self::assertSame(ExcelError::REF(), $result);
|
||||
}
|
||||
|
||||
public function testStructuredReferenceInvalidColumn(): void
|
||||
{
|
||||
$inputFileType = 'Xlsx';
|
||||
$inputFileName = __DIR__ . '/../../data/Calculation/TableFormulae.xlsx';
|
||||
|
||||
$reader = IOFactory::createReader($inputFileType);
|
||||
$spreadsheet = $reader->load($inputFileName);
|
||||
|
||||
$cellAddress = 'E2';
|
||||
$spreadsheet->getActiveSheet()->getCell($cellAddress)->setValue('=[@Sales Amount]*[@[%age Commission]]');
|
||||
|
||||
$result = $spreadsheet->getActiveSheet()->getCell($cellAddress)->getCalculatedValue();
|
||||
self::assertSame(ExcelError::REF(), $result);
|
||||
}
|
||||
|
||||
public function structuredReferenceProvider(): array
|
||||
{
|
||||
return [
|
||||
|
||||
Reference in New Issue
Block a user