sc/source/core/tool/interpr1.cxx | 52 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 48 insertions(+), 4 deletions(-)
New commits: commit 8100e82509b2f5f29dabf24e19461d649f166b4c Author: Eike Rathke <er...@redhat.com> AuthorDate: Sat Oct 31 01:36:18 2020 +0100 Commit: Eike Rathke <er...@redhat.com> CommitDate: Sat Oct 31 11:47:20 2020 +0100 Support external names in INDIRECT() Works with external global names, external sheet-local names are not supported by ScExternalRefManager / ScExternalRefCache. Change-Id: I59ecc9444268a14eee67439db5ed99181a716151 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/105092 Tested-by: Jenkins Reviewed-by: Eike Rathke <er...@redhat.com> diff --git a/sc/source/core/tool/interpr1.cxx b/sc/source/core/tool/interpr1.cxx index 8e50ae7303c5..1bcc37478eb5 100644 --- a/sc/source/core/tool/interpr1.cxx +++ b/sc/source/core/tool/interpr1.cxx @@ -8190,12 +8190,45 @@ void ScInterpreter::ScIndirect() } while (false); - // It may be even a TableRef. + // 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 // is already nasty enough... - sal_Int32 nIndex = sRefStr.indexOf('['); - if (nIndex >= 0 && sRefStr.indexOf(']',nIndex+1) > nIndex) + sal_Int32 nIndex = ScGlobal::FindUnquoted( sRefStr, '['); + const bool bTableRef = (nIndex > 0 && ScGlobal::FindUnquoted( sRefStr, ']', nIndex+1) > nIndex); + bool bExternalName = false; // External references would had been consumed above already. + if (!bTableRef) + { + // This is our own file name reference representation centric.. but + // would work also for XL '[doc]'!name and also for + // '[doc]Sheet1'!name ... sickos. + if (sRefStr[0] == '\'') + { + // Minimum 'a'#name or 'a'!name + // bTryXlA1 means try both, first our own. + if (bTryXlA1 || eConv == FormulaGrammar::CONV_OOO) + { + nIndex = ScGlobal::FindUnquoted( sRefStr, '#'); + if (nIndex >= 3 && sRefStr[nIndex-1] == '\'') + { + bExternalName = true; + eConv = FormulaGrammar::CONV_OOO; + } + } + if (!bExternalName && (bTryXlA1 || eConv != FormulaGrammar::CONV_OOO)) + { + nIndex = ScGlobal::FindUnquoted( sRefStr, '!'); + if (nIndex >= 3 && sRefStr[nIndex-1] == '\'') + { + bExternalName = true; + if (eConv == FormulaGrammar::CONV_OOO) + eConv = FormulaGrammar::CONV_XL_A1; + } + } + } + + } + if (bExternalName || bTableRef) { do { @@ -8203,8 +8236,17 @@ void ScInterpreter::ScIndirect() aComp.SetRefConvention( eConv); // must be after grammar std::unique_ptr<ScTokenArray> pTokArr( aComp.CompileString( sRefStr)); + if (pTokArr->GetCodeError() != FormulaError::NONE || !pTokArr->GetLen()) + break; + // Whatever... use only the specific case. - if (!pTokArr->HasOpCode( ocTableRef)) + if (bExternalName) + { + const formula::FormulaToken* pTok = pTokArr->FirstToken(); + if (!pTok || pTok->GetType() != svExternalName) + break; + } + else if (!pTokArr->HasOpCode( ocTableRef)) break; aComp.CompileTokenArray(); @@ -8223,6 +8265,8 @@ void ScInterpreter::ScIndirect() { case svSingleRef: case svDoubleRef: + case svExternalSingleRef: + case svExternalDoubleRef: case svError: PushTokenRef( xTok); // success! _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits