diff options
-rwxr-xr-x | formula/inc/formula/compiler.hrc | 1 | ||||
-rw-r--r-- | formula/inc/formula/opcode.hxx | 1 | ||||
-rw-r--r-- | oox/source/xls/tablebuffer.cxx | 8 | ||||
-rw-r--r-- | sc/inc/tokenarray.hxx | 1 | ||||
-rw-r--r-- | sc/source/core/tool/compiler.cxx | 15 | ||||
-rw-r--r-- | sc/source/core/tool/token.cxx | 7 |
6 files changed, 31 insertions, 2 deletions
diff --git a/formula/inc/formula/compiler.hrc b/formula/inc/formula/compiler.hrc index 49252ce85d2b..15d8aab91e3c 100755 --- a/formula/inc/formula/compiler.hrc +++ b/formula/inc/formula/compiler.hrc @@ -57,6 +57,7 @@ #define SC_OPCODE_ARRAY_ROW_SEP 23 #define SC_OPCODE_ARRAY_COL_SEP 24 /* some convs use sep != col_sep */ #define SC_OPCODE_STOP_DIV 25 +#define SC_OPCODE_SKIP 26 /* used to skip raw tokens during string compilation */ /*** error constants #... ***/ #define SC_OPCODE_START_ERRORS 30 diff --git a/formula/inc/formula/opcode.hxx b/formula/inc/formula/opcode.hxx index e562c27639c8..b1e585cd8548 100644 --- a/formula/inc/formula/opcode.hxx +++ b/formula/inc/formula/opcode.hxx @@ -58,6 +58,7 @@ enum OpCodeEnum ocStringXML = SC_OPCODE_STRINGXML, ocSpaces = SC_OPCODE_SPACES, ocMatRef = SC_OPCODE_MAT_REF, + ocSkip = SC_OPCODE_SKIP, // Access commands ocDBArea = SC_OPCODE_DB_AREA, ocMacro = SC_OPCODE_MACRO, diff --git a/oox/source/xls/tablebuffer.cxx b/oox/source/xls/tablebuffer.cxx index d3390204bce7..cc6647ab6e52 100644 --- a/oox/source/xls/tablebuffer.cxx +++ b/oox/source/xls/tablebuffer.cxx @@ -90,11 +90,15 @@ void Table::importTable( SequenceInputStream& rStrm, sal_Int16 nSheet ) void Table::finalizeImport() { - // create database range + // Create database range. Note that Excel 2007 and later names database + // ranges (or tables in their terminology) as Table1, Table2 etc. We need + // to import them as named db ranges because they may be referenced by + // name in formula expressions. if( (maModel.mnId > 0) && (maModel.maDisplayName.getLength() > 0) ) try { maDBRangeName = maModel.maDisplayName; - Reference< XDatabaseRange > xDatabaseRange( createUnnamedDatabaseRangeObject( maModel.maRange ), UNO_SET_THROW ); + Reference< XDatabaseRange > xDatabaseRange( + createDatabaseRangeObject( maDBRangeName, maModel.maRange ), UNO_SET_THROW); maDestRange = xDatabaseRange->getDataArea(); // get formula token index of the database range diff --git a/sc/inc/tokenarray.hxx b/sc/inc/tokenarray.hxx index 740bbfa54e3c..b2f4565d5a45 100644 --- a/sc/inc/tokenarray.hxx +++ b/sc/inc/tokenarray.hxx @@ -73,6 +73,7 @@ public: formula::FormulaToken* AddMatrixSingleReference( const ScSingleRefData& rRef ); formula::FormulaToken* AddDoubleReference( const ScComplexRefData& rRef ); formula::FormulaToken* AddRangeName( sal_uInt16 n, bool bGlobal ); + formula::FormulaToken* AddDBRange( sal_uInt16 n ); formula::FormulaToken* AddExternalName( sal_uInt16 nFileId, const String& rName ); formula::FormulaToken* AddExternalSingleReference( sal_uInt16 nFileId, const String& rTabName, const ScSingleRefData& rRef ); formula::FormulaToken* AddExternalDoubleReference( sal_uInt16 nFileId, const String& rTabName, const ScComplexRefData& rRef ); diff --git a/sc/source/core/tool/compiler.cxx b/sc/source/core/tool/compiler.cxx index 876c992b2a59..c7d7d9b1d92c 100644 --- a/sc/source/core/tool/compiler.cxx +++ b/sc/source/core/tool/compiler.cxx @@ -3013,6 +3013,18 @@ bool ScCompiler::IsExternalNamedRange( const String& rSymbol ) bool ScCompiler::IsDBRange( const String& rName ) { + if (rName.EqualsAscii("[]")) + { + if (pRawToken && pRawToken->GetOpCode() == ocDBArea) + { + // In OOXML, a database range is named Table1[], Table2[] etc. + // Skip the [] part if the previous token is a valid db range. + ScRawToken aToken; + aToken.eOp = ocSkip; + pRawToken = aToken.Clone(); + return true; + } + } ScDBCollection::NamedDBs& rDBs = pDoc->GetDBCollection()->getNamedDBs(); const ScDBData* p = rDBs.findByUpperName(rName); if (!p) @@ -3798,6 +3810,9 @@ ScTokenArray* ScCompiler::CompileString( const String& rFormula ) while( NextNewToken( bInArray ) ) { const OpCode eOp = pRawToken->GetOpCode(); + if (eOp == ocSkip) + continue; + switch (eOp) { case ocOpen: diff --git a/sc/source/core/tool/token.cxx b/sc/source/core/tool/token.cxx index f0dc5cf90418..5ed165a89f7f 100644 --- a/sc/source/core/tool/token.cxx +++ b/sc/source/core/tool/token.cxx @@ -1161,6 +1161,8 @@ bool ScTokenArray::AddFormulaToken(const com::sun::star::sheet::FormulaToken& _a _aToken.Data >>= aTokenData; if ( eOpCode == ocName ) AddRangeName(aTokenData.Index, aTokenData.Global); + else if (eOpCode == ocDBArea) + AddDBRange(aTokenData.Index); } else if ( aType.equals( cppu::UnoType<sheet::ExternalReference>::get() ) ) { @@ -1604,6 +1606,11 @@ FormulaToken* ScTokenArray::AddRangeName( sal_uInt16 n, bool bGlobal ) return Add( new FormulaIndexToken( ocName, n, bGlobal)); } +FormulaToken* ScTokenArray::AddDBRange( sal_uInt16 n ) +{ + return Add( new FormulaIndexToken( ocDBArea, n)); +} + FormulaToken* ScTokenArray::AddExternalName( sal_uInt16 nFileId, const String& rName ) { return Add( new ScExternalNameToken(nFileId, rName) ); |