[Libreoffice-commits] .: formula/inc oox/source sc/inc sc/source

Kohei Yoshida kohei at kemper.freedesktop.org
Tue Sep 20 14:12:43 PDT 2011


 formula/inc/formula/compiler.hrc |    1 +
 formula/inc/formula/opcode.hxx   |    1 +
 oox/source/xls/tablebuffer.cxx   |    8 ++++++--
 sc/inc/tokenarray.hxx            |    1 +
 sc/source/core/tool/compiler.cxx |   15 +++++++++++++++
 sc/source/core/tool/token.cxx    |    7 +++++++
 6 files changed, 31 insertions(+), 2 deletions(-)

New commits:
commit 665d1011950dc41d9a7f8e95596d5e1d5d99ff63
Author: Kohei Yoshida <kohei.yoshida at suse.com>
Date:   Tue Sep 20 17:08:08 2011 -0400

    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.

diff --git a/formula/inc/formula/compiler.hrc b/formula/inc/formula/compiler.hrc
index 49252ce..15d8aab 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 e562c27..b1e585c 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 d339020..cc6647a 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 740bbfa..b2f4565 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 876c992..c7d7d9b 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 f0dc5cf..5ed165a 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) );


More information about the Libreoffice-commits mailing list