From 27d7dd7c20e57eb7149e2dfc59752493dd068b6a Mon Sep 17 00:00:00 2001 From: Eike Rathke Date: Mon, 7 Sep 2015 23:08:43 +0200 Subject: TableRef: finally support header-less table structured references Change-Id: Ifd6928bafc59abc252f29af81f26f6362e9fc933 --- sc/source/core/tool/compiler.cxx | 49 +++++++++++++++++++++------------------- 1 file changed, 26 insertions(+), 23 deletions(-) diff --git a/sc/source/core/tool/compiler.cxx b/sc/source/core/tool/compiler.cxx index b04e6517ca37..d954c2d73227 100644 --- a/sc/source/core/tool/compiler.cxx +++ b/sc/source/core/tool/compiler.cxx @@ -3524,26 +3524,17 @@ bool ScCompiler::IsTableRefColumn( const OUString& rName ) const sal_Int32 nOffset = pDBData->GetColumnNameOffset( aName); if (nOffset >= 0) { - if (pDBData->HasHeader()) - { - ScSingleRefData aRef; - ScAddress aAdr( aRange.aStart); - aAdr.IncCol( nOffset); - aRef.InitAddress( aAdr); - maRawToken.SetSingleReference( aRef ); - } - else - { - /* TODO: this probably needs a new token type to hold offset and - * name, to be handled in HandleTableRef(). We can't use a - * reference token here because any reference would be wrong as - * there are no header cells to be referenced. However, it would - * only work as long as the ScDBData column names are not - * invalidated during document structure changes, otherwise - * recompiling the same formula could not resolve the name again. - * As long as this doesn't work generate an error. */ - return false; - } + // This is sneaky.. we always use the top row of the database range, + // regardless of whether it is a header row or not. Code evaluating + // this reference must take that into account and may have to act + // differently if it is a header-less table. Which are two places, + // HandleTableRef() (no change necessary there) and + // CreateStringFromSingleRef() (must not fallback to cell lookup). + ScSingleRefData aRef; + ScAddress aAdr( aRange.aStart); + aAdr.IncCol( nOffset); + aRef.InitAddress( aAdr); + maRawToken.SetSingleReference( aRef ); return true; } @@ -4706,13 +4697,25 @@ void ScCompiler::CreateStringFromSingleRef( OUStringBuffer& rBuffer, const Formu { OUString aStr; ScAddress aAbs = rRef.toAbs(aPos); - const ScDBData* pData = pDoc->GetDBAtCursor( aAbs.Col(), aAbs.Row(), aAbs.Tab(), ScDBDataPortion::HEADER); + const ScDBData* pData = pDoc->GetDBAtCursor( aAbs.Col(), aAbs.Row(), aAbs.Tab(), ScDBDataPortion::AREA); + SAL_WARN_IF( !pData, "sc.core", "ScCompiler::CreateStringFromSingleRef - TableRef without ScDBData: " << + aAbs.Format( SCA_VALID | SCA_TAB_3D, pDoc)); if (pData) aStr = pData->GetTableColumnName( aAbs.Col()); if (aStr.isEmpty()) { - SAL_WARN("sc.core", "ScCompiler::CreateStringFromSingleRef - TableRef falling back to cell"); - aStr = pDoc->GetString(aAbs); + if (pData && pData->HasHeader()) + { + SAL_WARN("sc.core", "ScCompiler::CreateStringFromSingleRef - TableRef falling back to cell: " << + aAbs.Format( SCA_VALID | SCA_TAB_3D, pDoc)); + aStr = pDoc->GetString(aAbs); + } + else + { + SAL_WARN("sc.core", "ScCompiler::CreateStringFromSingleRef - TableRef of empty header-less: " << + aAbs.Format( SCA_VALID | SCA_TAB_3D, pDoc)); + aStr = aErrRef; + } } escapeTableRefColumnSpecifier( aStr); rBuffer.append(aStr); -- cgit