summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEike Rathke <erack@redhat.com>2022-09-19 12:29:34 +0200
committerXisco Fauli <xiscofauli@libreoffice.org>2022-09-19 17:22:31 +0200
commit4f66fada43cf50767066c756def7eb39654e376b (patch)
treed8bddfe59bedd8484632f374b414c359b9916f5e
parentd700377556ca6e1adf5972fcbc8eef658adc0b53 (diff)
Resolves: tdf#151046 INDIRECT() try named expressions and DB range names first
... as older 1K columns allowed names that would now match a 16k columns cell address, which ConvertSingleRef() would already resolve. Change-Id: I9322732e554da20c81856c0a30c41a246356f65b Reviewed-on: https://gerrit.libreoffice.org/c/core/+/140147 Reviewed-by: Eike Rathke <erack@redhat.com> Tested-by: Jenkins (cherry picked from commit cc28ea4c4483df1643154adc50bd537e35fabb05) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/140154 Reviewed-by: Xisco Fauli <xiscofauli@libreoffice.org>
-rw-r--r--sc/source/core/tool/interpr1.cxx130
1 files changed, 66 insertions, 64 deletions
diff --git a/sc/source/core/tool/interpr1.cxx b/sc/source/core/tool/interpr1.cxx
index 25f334d6835d..e09620605d35 100644
--- a/sc/source/core/tool/interpr1.cxx
+++ b/sc/source/core/tool/interpr1.cxx
@@ -8190,6 +8190,72 @@ void ScInterpreter::ScIndirect()
const ScAddress::Details aDetailsXlA1( FormulaGrammar::CONV_XL_A1, aPos );
SCTAB nTab = aPos.Tab();
+ // Named expressions and DB range names need to be tried first, as older 1K
+ // columns allowed names that would now match a 16k columns cell address.
+ do
+ {
+ ScRangeData* pData = ScRangeStringConverter::GetRangeDataFromString( sRefStr, nTab, mrDoc, eConv);
+ if (!pData)
+ break;
+
+ // We need this in order to obtain a good range.
+ pData->ValidateTabRefs();
+
+ ScRange aRange;
+
+ // This is the usual way to treat named ranges containing
+ // relative references.
+ if (!pData->IsReference( aRange, aPos))
+ break;
+
+ if (aRange.aStart == aRange.aEnd)
+ PushSingleRef( aRange.aStart.Col(), aRange.aStart.Row(),
+ aRange.aStart.Tab());
+ else
+ PushDoubleRef( aRange.aStart.Col(), aRange.aStart.Row(),
+ aRange.aStart.Tab(), aRange.aEnd.Col(),
+ aRange.aEnd.Row(), aRange.aEnd.Tab());
+
+ // success!
+ return;
+ }
+ while (false);
+
+ do
+ {
+ OUString aName( ScGlobal::getCharClass().uppercase( sRefStr));
+ ScDBCollection::NamedDBs& rDBs = mrDoc.GetDBCollection()->getNamedDBs();
+ const ScDBData* pData = rDBs.findByUpperName( aName);
+ if (!pData)
+ break;
+
+ ScRange aRange;
+ pData->GetArea( aRange);
+
+ // In Excel, specifying a table name without [] resolves to the
+ // same as with [], a range that excludes header and totals
+ // rows and contains only data rows. Do the same.
+ if (pData->HasHeader())
+ aRange.aStart.IncRow();
+ if (pData->HasTotals())
+ aRange.aEnd.IncRow(-1);
+
+ if (aRange.aStart.Row() > aRange.aEnd.Row())
+ break;
+
+ if (aRange.aStart == aRange.aEnd)
+ PushSingleRef( aRange.aStart.Col(), aRange.aStart.Row(),
+ aRange.aStart.Tab());
+ else
+ PushDoubleRef( aRange.aStart.Col(), aRange.aStart.Row(),
+ aRange.aStart.Tab(), aRange.aEnd.Col(),
+ aRange.aEnd.Row(), aRange.aEnd.Tab());
+
+ // success!
+ return;
+ }
+ while (false);
+
ScRefAddress aRefAd, aRefAd2;
ScAddress::ExternalInfo aExtInfo;
if ( ConvertDoubleRef(mrDoc, sRefStr, nTab, aRefAd, aRefAd2, aDetails, &aExtInfo) ||
@@ -8220,70 +8286,6 @@ void ScInterpreter::ScIndirect()
}
else
{
- do
- {
- ScRangeData* pData = ScRangeStringConverter::GetRangeDataFromString( sRefStr, nTab, mrDoc, eConv);
- if (!pData)
- break;
-
- // We need this in order to obtain a good range.
- pData->ValidateTabRefs();
-
- ScRange aRange;
-
- // This is the usual way to treat named ranges containing
- // relative references.
- if (!pData->IsReference( aRange, aPos))
- break;
-
- if (aRange.aStart == aRange.aEnd)
- PushSingleRef( aRange.aStart.Col(), aRange.aStart.Row(),
- aRange.aStart.Tab());
- else
- PushDoubleRef( aRange.aStart.Col(), aRange.aStart.Row(),
- aRange.aStart.Tab(), aRange.aEnd.Col(),
- aRange.aEnd.Row(), aRange.aEnd.Tab());
-
- // success!
- return;
- }
- while (false);
-
- do
- {
- OUString aName( ScGlobal::getCharClass().uppercase( sRefStr));
- ScDBCollection::NamedDBs& rDBs = mrDoc.GetDBCollection()->getNamedDBs();
- const ScDBData* pData = rDBs.findByUpperName( aName);
- if (!pData)
- break;
-
- ScRange aRange;
- pData->GetArea( aRange);
-
- // In Excel, specifying a table name without [] resolves to the
- // same as with [], a range that excludes header and totals
- // rows and contains only data rows. Do the same.
- if (pData->HasHeader())
- aRange.aStart.IncRow();
- if (pData->HasTotals())
- aRange.aEnd.IncRow(-1);
-
- if (aRange.aStart.Row() > aRange.aEnd.Row())
- break;
-
- if (aRange.aStart == aRange.aEnd)
- PushSingleRef( aRange.aStart.Col(), aRange.aStart.Row(),
- aRange.aStart.Tab());
- else
- PushDoubleRef( aRange.aStart.Col(), aRange.aStart.Row(),
- aRange.aStart.Tab(), aRange.aEnd.Col(),
- aRange.aEnd.Row(), aRange.aEnd.Tab());
-
- // success!
- return;
- }
- while (false);
-
// It may be even a TableRef or an external name.
// Anything else that resolves to one reference could be added
// here, but we don't want to compile every arbitrary string. This