summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKohei Yoshida <kohei.yoshida@suse.com>2011-09-20 17:08:08 -0400
committerKohei Yoshida <kohei.yoshida@suse.com>2011-09-20 17:12:46 -0400
commit665d1011950dc41d9a7f8e95596d5e1d5d99ff63 (patch)
treebf96341b70d2e928d6a8062a52eac03945c9479f
parent7dff26aa099aa97c7bfc03806ba8160a9d7e945c (diff)
Get DB range import from xlsx to work once again.
We need to map Excel's database ranges (or in Excel's terminology "tables") to named db ranges because they may be referenced in formula expressions. Also, Excel tables are always of the form Table*[] when used in formulas. Skip the "[]" part then the preceding token is a valid database range.
-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) );