From 1135bfd78802e5c40ca09bcbc75d0908a423872a Mon Sep 17 00:00:00 2001 From: Eike Rathke Date: Tue, 26 Jun 2012 02:05:09 +0200 Subject: fdo#46338 preserve sheet name input of invalid reference If sheet name doesn't exist the resulting reference had replaced the sheet name with #REF!, e.g. #REF!.A1, because the actual sheet name is not part of the reference. From a syntactically valid but otherwise invalid non-external reference create an ocBad token instead to preserve the sheet name. Currently a #NAME? error instead of #REF! is generated, further work would be needed to pass specific error values with ocBad. Change-Id: I5a608a74d3b3ff2baa4967f2b2e3078cfecfbabc --- sc/inc/compiler.hxx | 7 +++++++ sc/source/core/tool/compiler.cxx | 8 ++++++++ sc/source/core/tool/token.cxx | 19 +++++++++++++++++++ 3 files changed, 34 insertions(+) (limited to 'sc') diff --git a/sc/inc/compiler.hxx b/sc/inc/compiler.hxx index 58a3c6c6f918..470d8eb8afd1 100644 --- a/sc/inc/compiler.hxx +++ b/sc/inc/compiler.hxx @@ -196,6 +196,13 @@ public: void SetMatrix( ScMatrix* p ); void SetExternal(const sal_Unicode* pStr); + /** If the token is a non-external reference, determine if the reference is + valid. If the token is an external reference, return true. Else return + false. Used only in ScCompiler::NextNewToken() to preserve non-existing + sheet names in otherwise valid references. + */ + bool IsValidReference() const; + ScRawToken* Clone() const; // real copy! formula::FormulaToken* CreateToken() const; // create typified token void Load( SvStream&, sal_uInt16 nVer ); diff --git a/sc/source/core/tool/compiler.cxx b/sc/source/core/tool/compiler.cxx index 97ae77012619..dc30ff812805 100644 --- a/sc/source/core/tool/compiler.cxx +++ b/sc/source/core/tool/compiler.cxx @@ -3657,6 +3657,14 @@ bool ScCompiler::NextNewToken( bool bInArray ) { if (mbRewind) // Range operator, but no direct reference. continue; // do; up to range operator. + // If a syntactically correct reference was recognized but invalid + // e.g. because of non-existing sheet name => entire reference + // ocBad to preserve input instead of #REF!.A1 + if (!pRawToken->IsValidReference()) + { + aUpper = aOrg; // ensure for ocBad + break; // do; create ocBad token or set error. + } return true; } diff --git a/sc/source/core/tool/token.cxx b/sc/source/core/tool/token.cxx index 800d952de96d..99b0713a6661 100644 --- a/sc/source/core/tool/token.cxx +++ b/sc/source/core/tool/token.cxx @@ -292,6 +292,25 @@ void ScRawToken::SetExternal( const sal_Unicode* pStr ) nRefCnt = 0; } + +bool ScRawToken::IsValidReference() const +{ + switch (eType) + { + case svSingleRef: + return aRef.Ref1.Valid(); + case svDoubleRef: + return aRef.Valid(); + case svExternalSingleRef: + case svExternalDoubleRef: + return true; + default: + ; // nothing + } + return false; +} + + sal_uInt16 lcl_ScRawTokenOffset() { // offset of sbyte in ScRawToken -- cgit