summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xformula/inc/formula/compiler.hrc1
-rw-r--r--formula/inc/formula/opcode.hxx1
-rw-r--r--oox/source/xls/tablebuffer.cxx8
-rw-r--r--sc/inc/tokenarray.hxx1
-rw-r--r--sc/source/core/tool/compiler.cxx15
-rw-r--r--sc/source/core/tool/token.cxx7
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) );