[Libreoffice-commits] .: 5 commits - sc/inc sc/qa sc/source

Kohei Yoshida kohei at kemper.freedesktop.org
Mon Nov 7 18:34:27 PST 2011


 sc/inc/queryentry.hxx                            |   31 ++-
 sc/qa/unit/ucalc.cxx                             |   97 ++++++++----
 sc/source/core/data/dociter.cxx                  |   63 ++++----
 sc/source/core/data/dpshttab.cxx                 |   17 +-
 sc/source/core/data/dptablecache.cxx             |   26 +--
 sc/source/core/data/table3.cxx                   |  116 ++++++++------
 sc/source/core/tool/doubleref.cxx                |    4 
 sc/source/core/tool/interpr1.cxx                 |  179 ++++++++++++-----------
 sc/source/core/tool/lookupcache.cxx              |    8 -
 sc/source/core/tool/queryentry.cxx               |   87 +++--------
 sc/source/core/tool/queryparam.cxx               |   22 +-
 sc/source/filter/excel/excimp8.cxx               |   44 ++---
 sc/source/filter/excel/excrecds.cxx              |   11 -
 sc/source/filter/xml/XMLExportDataPilot.cxx      |   11 -
 sc/source/filter/xml/XMLExportDatabaseRanges.cxx |   16 +-
 sc/source/filter/xml/xmlfilti.cxx                |   17 +-
 sc/source/ui/dbgui/filtdlg.cxx                   |   41 ++---
 sc/source/ui/dbgui/pfiltdlg.cxx                  |   29 +--
 sc/source/ui/unoobj/cellsuno.cxx                 |    7 
 sc/source/ui/unoobj/datauno.cxx                  |   97 +++++-------
 sc/source/ui/view/gridwin.cxx                    |   47 ++----
 21 files changed, 518 insertions(+), 452 deletions(-)

New commits:
commit a3ddd330bd7f60402e17fe74324c64a394516a01
Author: Kohei Yoshida <kohei.yoshida at suse.com>
Date:   Mon Nov 7 21:32:00 2011 -0500

    Test for filtering empty and non-empty cells.

diff --git a/sc/qa/unit/ucalc.cxx b/sc/qa/unit/ucalc.cxx
index 1b64ade..b40b788 100644
--- a/sc/qa/unit/ucalc.cxx
+++ b/sc/qa/unit/ucalc.cxx
@@ -2247,12 +2247,43 @@ void Test::testAutofilter()
     CPPUNIT_ASSERT_MESSAGE("rows 2 & 3 should be hidden", bHidden && nRow1 == 2 && nRow2 == 3);
 
     // Remove filtering.
-    aParam.GetEntry(0).Clear();
-    pDBData->SetQueryParam(aParam);
+    rEntry.Clear();
     m_pDoc->Query(0, aParam, true);
     bHidden = m_pDoc->RowHidden(0, 0, &nRow1, &nRow2);
     CPPUNIT_ASSERT_MESSAGE("All rows should be shown.", !bHidden && nRow1 == 0 && nRow2 == MAXROW);
 
+    // Filter for non-empty cells by column C.
+    rEntry.bDoQuery = true;
+    rEntry.nField = 2;
+    rEntry.GetQueryItem().meType = ScQueryEntry::ByValue;
+    rEntry.GetQueryItem().maString = rtl::OUString();
+    rEntry.GetQueryItem().mfVal = SC_NONEMPTYFIELDS;
+    m_pDoc->Query(0, aParam, true);
+
+    // only row 3 should be hidden.  The rest should be visible.
+    bHidden = m_pDoc->RowHidden(0, 0, &nRow1, &nRow2);
+    CPPUNIT_ASSERT_MESSAGE("rows 1 & 2 should be visible.", !bHidden && nRow1 == 0 && nRow2 == 1);
+    bHidden = m_pDoc->RowHidden(2, 0, &nRow1, &nRow2);
+    CPPUNIT_ASSERT_MESSAGE("row 3 should be hidden.", bHidden && nRow1 == 2 && nRow2 == 2);
+    bHidden = m_pDoc->RowHidden(3, 0, &nRow1, &nRow2);
+    CPPUNIT_ASSERT_MESSAGE("row 4 and down should be visible.", !bHidden && nRow1 == 3 && nRow2 == MAXROW);
+
+    // Now, filter for empty cells by column C.
+    rEntry.GetQueryItem().mfVal = SC_EMPTYFIELDS;
+    m_pDoc->Query(0, aParam, true);
+
+    // Now, only row 1 and 3, and 6 and down should be visible.
+    bHidden = m_pDoc->RowHidden(0, 0, &nRow1, &nRow2);
+    CPPUNIT_ASSERT_MESSAGE("row 1 should be visible.", !bHidden && nRow1 == 0 && nRow2 == 0);
+    bHidden = m_pDoc->RowHidden(1, 0, &nRow1, &nRow2);
+    CPPUNIT_ASSERT_MESSAGE("row 2 should be hidden.", bHidden && nRow1 == 1 && nRow2 == 1);
+    bHidden = m_pDoc->RowHidden(2, 0, &nRow1, &nRow2);
+    CPPUNIT_ASSERT_MESSAGE("row 3 should be visible.", !bHidden && nRow1 == 2 && nRow2 == 2);
+    bHidden = m_pDoc->RowHidden(3, 0, &nRow1, &nRow2);
+    CPPUNIT_ASSERT_MESSAGE("rows 4 & 5 should be hidden.", bHidden && nRow1 == 3 && nRow2 == 4);
+    bHidden = m_pDoc->RowHidden(5, 0, &nRow1, &nRow2);
+    CPPUNIT_ASSERT_MESSAGE("rows 6 and down should be all visible.", !bHidden && nRow1 == 5 && nRow2 == MAXROW);
+
     m_pDoc->DeleteTab(0);
 }
 
commit cbe46bbe3e7211b937171136405aabd4b8ceaa39
Author: Kohei Yoshida <kohei.yoshida at suse.com>
Date:   Mon Nov 7 19:04:15 2011 -0500

    Simplified the filter test a bit, and clear the filter afterward.

diff --git a/sc/qa/unit/ucalc.cxx b/sc/qa/unit/ucalc.cxx
index 0f1fed5..1b64ade 100644
--- a/sc/qa/unit/ucalc.cxx
+++ b/sc/qa/unit/ucalc.cxx
@@ -45,6 +45,7 @@
 #include "undoblk.hxx"
 #include "queryentry.hxx"
 #include "postit.hxx"
+#include "attrib.hxx"
 
 #include "docsh.hxx"
 #include "docfunc.hxx"
@@ -2194,53 +2195,64 @@ void Test::testToggleRefFlag()
 void Test::testAutofilter()
 {
     OUString aTabName(RTL_CONSTASCII_USTRINGPARAM("Test"));
+    OUString aDBName(RTL_CONSTASCII_USTRINGPARAM("NONAME"));
+
     m_pDoc->InsertTab( 0, aTabName );
 
-    OUString aCol1(RTL_CONSTASCII_USTRINGPARAM("COL1"));
-    OUString aCol2(RTL_CONSTASCII_USTRINGPARAM("COL2"));
-    OUString aDBName(RTL_CONSTASCII_USTRINGPARAM("NONAME"));
+    // cell contents (0 = empty cell)
+    const char* aData[][3] = {
+        { "C1", "C2", "C3" },
+        {  "0",  "1",  "A" },
+        {  "1",  "2",    0 },
+        {  "1",  "2",  "B" },
+        {  "0",  "2",  "B" }
+    };
 
-    //set column headers
-    m_pDoc->SetString(0,0,0,aCol1);
-    m_pDoc->SetString(1,0,0,aCol2);
+    SCCOL nCols = SAL_N_ELEMENTS(aData[0]);
+    SCROW nRows = SAL_N_ELEMENTS(aData);
 
-    //set values
-    m_pDoc->SetValue(0,1,0,0);
-    m_pDoc->SetValue(1,1,0,1);
-    m_pDoc->SetValue(0,2,0,1);
-    m_pDoc->SetValue(1,2,0,3);
-    m_pDoc->SetValue(0,3,0,1);
-    m_pDoc->SetValue(1,3,0,2);
+    // Populate cells.
+    for (SCROW i = 0; i < nRows; ++i)
+        for (SCCOL j = 0; j < nCols; ++j)
+            if (aData[i][j])
+                m_pDoc->SetString(j, i, 0, rtl::OUString::createFromAscii(aData[i][j]));
 
-    //create db data and set it to autofilter
-    ScDBData* pDBData = new ScDBData(aDBName,0,0,0,1,3);
+    ScDBData* pDBData = new ScDBData(aDBName, 0, 0, 0, nCols-1, nRows-1);
     m_pDoc->SetAnonymousDBData(0,pDBData);
 
     pDBData->SetAutoFilter(true);
     ScRange aRange;
     pDBData->GetArea(aRange);
     m_pDoc->ApplyFlagsTab( aRange.aStart.Col(), aRange.aStart.Row(),
-                                aRange.aEnd.Col(), aRange.aStart.Row(),
-                                aRange.aStart.Tab(), 4 );
+                           aRange.aEnd.Col(), aRange.aStart.Row(),
+                           aRange.aStart.Tab(), SC_MF_AUTO);
 
     //create the query param
     ScQueryParam aParam;
-    aParam.Resize(1);
-    ScQueryEntry& aEntry = aParam.GetEntry(0);
-    aEntry.bDoQuery = true;
-    aEntry.eOp = SC_EQUAL;
-    aEntry.GetQueryItem().mfVal = 0;
-    //add queryParam to autofilter
+    pDBData->GetQueryParam(aParam);
+    ScQueryEntry& rEntry = aParam.GetEntry(0);
+    rEntry.bDoQuery = true;
+    rEntry.nField = 0;
+    rEntry.eOp = SC_EQUAL;
+    rEntry.GetQueryItem().mfVal = 0;
+    // add queryParam to database range.
     pDBData->SetQueryParam(aParam);
-    //perform the query
-    ScDBDocFunc aDBFunc(*m_xDocShRef);
-    aDBFunc.RepeatDB(aCol1,true,true,true,0);
+
+    // perform the query.
+    m_pDoc->Query(0, aParam, true);
 
     //control output
     SCROW nRow1, nRow2;
     bool bHidden = m_pDoc->RowHidden(2, 0, &nRow1, &nRow2);
     CPPUNIT_ASSERT_MESSAGE("rows 2 & 3 should be hidden", bHidden && nRow1 == 2 && nRow2 == 3);
 
+    // Remove filtering.
+    aParam.GetEntry(0).Clear();
+    pDBData->SetQueryParam(aParam);
+    m_pDoc->Query(0, aParam, true);
+    bHidden = m_pDoc->RowHidden(0, 0, &nRow1, &nRow2);
+    CPPUNIT_ASSERT_MESSAGE("All rows should be shown.", !bHidden && nRow1 == 0 && nRow2 == MAXROW);
+
     m_pDoc->DeleteTab(0);
 }
 
diff --git a/sc/source/core/tool/queryparam.cxx b/sc/source/core/tool/queryparam.cxx
index 2f10046..4012f13 100644
--- a/sc/source/core/tool/queryparam.cxx
+++ b/sc/source/core/tool/queryparam.cxx
@@ -229,10 +229,9 @@ void ScQueryParam::Clear()
     bHasHeader = bCaseSens = bRegExp = bMixedComparison = false;
     bInplace = bByRow = bDuplicate = sal_True;
 
-    boost::ptr_vector<ScQueryEntry> aNewEntries;
-    for (size_t i = 0; i < MAXQUERY; ++i)
-        aNewEntries.push_back(new ScQueryEntry);
-    maEntries.swap(aNewEntries);
+    boost::ptr_vector<ScQueryEntry>::iterator itr = maEntries.begin(), itrEnd = maEntries.end();
+    for (; itr != itrEnd; ++itr)
+        itr->Clear();
 
     ClearDestParams();
 }
commit 97453f1eabb473d0691e41153eff2ac92e88a302
Author: Kohei Yoshida <kohei.yoshida at suse.com>
Date:   Mon Nov 7 18:24:43 2011 -0500

    Another bug.

diff --git a/sc/source/core/data/table3.cxx b/sc/source/core/data/table3.cxx
index 418e4c7..59738e4 100644
--- a/sc/source/core/data/table3.cxx
+++ b/sc/source/core/data/table3.cxx
@@ -1629,7 +1629,7 @@ static void lcl_PrepareQuery( ScDocument* pDoc, ScTable* pTab, ScQueryParam& rPa
         {
             // TODO: adapt this for multi-query items.
             ScQueryEntry::Item& rItem = rEntry.GetQueryItem();
-            if (rItem.meType != ScQueryEntry::ByString)
+            if (rItem.meType == ScQueryEntry::ByString)
             {
                 sal_uInt32 nIndex = 0;
                 bool bNumber = pDoc->GetFormatTable()->
commit 5f31abed9d68b4ee533c739b3cc9ef5dfe85ea04
Author: Kohei Yoshida <kohei.yoshida at suse.com>
Date:   Mon Nov 7 18:06:37 2011 -0500

    Fixed a silly bug.

diff --git a/sc/source/core/data/table3.cxx b/sc/source/core/data/table3.cxx
index 0ad9736..418e4c7 100644
--- a/sc/source/core/data/table3.cxx
+++ b/sc/source/core/data/table3.cxx
@@ -1071,7 +1071,7 @@ bool isQueryByValue(
     const ScTable& rTable, const ScQueryEntry::Item& rItem,
     SCCOL nCol, SCROW nRow, const ScBaseCell* pCell)
 {
-    if (rItem.meType != ScQueryEntry::ByString)
+    if (rItem.meType == ScQueryEntry::ByString)
         return false;
 
     if (pCell)
commit 8808d77f199720be596a09084fbc36569ed2f1f1
Author: Kohei Yoshida <kohei.yoshida at suse.com>
Date:   Mon Nov 7 17:40:38 2011 -0500

    Changed data storage structure in ScQueryEntry.
    
    This required a whole bunch of chnages all over the place.

diff --git a/sc/inc/queryentry.hxx b/sc/inc/queryentry.hxx
index 48f7637..c0ce6e4 100644
--- a/sc/inc/queryentry.hxx
+++ b/sc/inc/queryentry.hxx
@@ -44,15 +44,23 @@ namespace utl {
  */
 struct ScQueryEntry
 {
-    typedef std::vector<rtl::OUString> QueryStringsType;
+    enum QueryType { ByValue, ByString, ByDate };
+
+    struct Item
+    {
+        QueryType     meType;
+        double        mfVal;
+        rtl::OUString maString;
+
+        bool operator== (const Item& r) const;
+        Item();
+    };
+    typedef std::vector<Item> QueryItemsType;
 
     bool            bDoQuery;
-    bool            bQueryByString;
-    bool            bQueryByDate;
     SCCOLROW        nField;
     ScQueryOp       eOp;
     ScQueryConnect  eConnect;
-    double          nVal;
     mutable utl::SearchParam* pSearchParam;       // if RegExp, not saved
     mutable utl::TextSearch*  pSearchText;        // if RegExp, not saved
 
@@ -63,16 +71,19 @@ struct ScQueryEntry
     // creates pSearchParam and pSearchText if necessary, always RegExp!
     utl::TextSearch* GetSearchTextPtr( bool bCaseSens ) const;
 
-    bool            IsQueryStringEmpty() const;
-    bool            MatchByString(const rtl::OUString& rStr, bool bCaseSens) const;
-    void            SortQueryStrings(bool bCaseSens);
-    SC_DLLPUBLIC void SetQueryString(const rtl::OUString& rStr);
-    SC_DLLPUBLIC rtl::OUString GetQueryString() const;
+    SC_DLLPUBLIC const Item& GetQueryItem() const;
+    SC_DLLPUBLIC Item& GetQueryItem();
     void            Clear();
     ScQueryEntry&   operator=( const ScQueryEntry& r );
     bool            operator==( const ScQueryEntry& r ) const;
+
 private:
-    QueryStringsType maQueryStrings;
+    /**
+     * Stores all query items.  It must contain at least one item at all times
+     * (for single equality match queries or comparative queries).  It may
+     * contain multiple items for multi-equality match queries.
+     */
+    mutable QueryItemsType maQueryItems;
 };
 
 #endif
diff --git a/sc/qa/unit/ucalc.cxx b/sc/qa/unit/ucalc.cxx
index a7770b5..0f1fed5 100644
--- a/sc/qa/unit/ucalc.cxx
+++ b/sc/qa/unit/ucalc.cxx
@@ -1178,7 +1178,7 @@ void Test::testDataPilotFilters()
     ScQueryEntry& rEntry = aQueryParam.GetEntry(0);
     rEntry.bDoQuery = true;
     rEntry.nField = 1;  // Group1
-    rEntry.nVal = 1;
+    rEntry.GetQueryItem().mfVal = 1;
     aDesc.SetQueryParam(aQueryParam);
     pDPObj->SetSheetDesc(aDesc);
     pDPObj->Output(aOutRange.aStart);
@@ -2229,7 +2229,7 @@ void Test::testAutofilter()
     ScQueryEntry& aEntry = aParam.GetEntry(0);
     aEntry.bDoQuery = true;
     aEntry.eOp = SC_EQUAL;
-    aEntry.nVal = 0;
+    aEntry.GetQueryItem().mfVal = 0;
     //add queryParam to autofilter
     pDBData->SetQueryParam(aParam);
     //perform the query
diff --git a/sc/source/core/data/dociter.cxx b/sc/source/core/data/dociter.cxx
index 91df276..5efe016 100644
--- a/sc/source/core/data/dociter.cxx
+++ b/sc/source/core/data/dociter.cxx
@@ -531,9 +531,11 @@ ScDBQueryDataIterator::DataAccessInternal::DataAccessInternal(const ScDBQueryDat
     for (i=0; (i<nCount) && (mpParam->GetEntry(i).bDoQuery); i++)
     {
         ScQueryEntry& rEntry = mpParam->GetEntry(i);
+        ScQueryEntry::Item& rItem = rEntry.GetQueryItem();
         sal_uInt32 nIndex = 0;
-        rEntry.bQueryByString =
-            !(mpDoc->GetFormatTable()->IsNumberFormat(rEntry.GetQueryString(), nIndex, rEntry.nVal));
+        bool bNumber = mpDoc->GetFormatTable()->IsNumberFormat(
+            rItem.maString, nIndex, rItem.mfVal);
+        rItem.meType = bNumber ? ScQueryEntry::ByValue : ScQueryEntry::ByString;
     }
     nNumFormat = 0;                 // werden bei GetNumberFormat initialisiert
     pAttrArray = 0;
@@ -713,9 +715,9 @@ bool ScDBQueryDataIterator::DataAccessMatrix::getNext(Value& rValue)
 
 namespace {
 
-bool lcl_isQueryByValue(const ScQueryEntry& rEntry, const ScMatrix& rMat, SCSIZE nCol, SCSIZE nRow)
+bool isQueryByValue(const ScQueryEntry::Item& rItem, const ScMatrix& rMat, SCSIZE nCol, SCSIZE nRow)
 {
-    if (rEntry.bQueryByString)
+    if (rItem.meType == ScQueryEntry::ByString)
         return false;
 
     if (!rMat.IsValueOrEmpty(nCol, nRow))
@@ -724,7 +726,7 @@ bool lcl_isQueryByValue(const ScQueryEntry& rEntry, const ScMatrix& rMat, SCSIZE
     return true;
 }
 
-bool lcl_isQueryByString(const ScQueryEntry& rEntry, const ScMatrix& rMat, SCSIZE nCol, SCSIZE nRow)
+bool isQueryByString(const ScQueryEntry& rEntry, const ScQueryEntry::Item& rItem, const ScMatrix& rMat, SCSIZE nCol, SCSIZE nRow)
 {
     switch (rEntry.eOp)
     {
@@ -741,7 +743,7 @@ bool lcl_isQueryByString(const ScQueryEntry& rEntry, const ScMatrix& rMat, SCSIZ
             ;
     }
 
-    if (rEntry.bQueryByString && rMat.IsString(nCol, nRow))
+    if (rItem.meType == ScQueryEntry::ByString && rMat.IsString(nCol, nRow))
         return true;
 
     return false;
@@ -761,6 +763,7 @@ bool ScDBQueryDataIterator::DataAccessMatrix::isValidQuery(SCROW nRow, const ScM
     for (SCSIZE i = 0; i < nEntryCount; ++i)
     {
         const ScQueryEntry& rEntry = mpParam->GetEntry(i);
+        const ScQueryEntry::Item& rItem = rEntry.GetQueryItem();
         if (!rEntry.bDoQuery)
             continue;
 
@@ -781,27 +784,27 @@ bool ScDBQueryDataIterator::DataAccessMatrix::isValidQuery(SCROW nRow, const ScM
         bool bValid = false;
 
         SCSIZE nField = static_cast<SCSIZE>(rEntry.nField);
-        if (lcl_isQueryByValue(rEntry, rMat, nField, nRow))
+        if (isQueryByValue(rItem, rMat, nField, nRow))
         {
             // By value
             double fMatVal = rMat.GetDouble(nField, nRow);
-            bool bEqual = approxEqual(fMatVal, rEntry.nVal);
+            bool bEqual = approxEqual(fMatVal, rItem.mfVal);
             switch (rEntry.eOp)
             {
                 case SC_EQUAL:
                     bValid = bEqual;
                 break;
                 case SC_LESS:
-                    bValid = (fMatVal < rEntry.nVal) && !bEqual;
+                    bValid = (fMatVal < rItem.mfVal) && !bEqual;
                 break;
                 case SC_GREATER:
-                    bValid = (fMatVal > rEntry.nVal) && !bEqual;
+                    bValid = (fMatVal > rItem.mfVal) && !bEqual;
                 break;
                 case SC_LESS_EQUAL:
-                    bValid = (fMatVal < rEntry.nVal) || bEqual;
+                    bValid = (fMatVal < rItem.mfVal) || bEqual;
                 break;
                 case SC_GREATER_EQUAL:
-                    bValid = (fMatVal > rEntry.nVal) || bEqual;
+                    bValid = (fMatVal > rItem.mfVal) || bEqual;
                 break;
                 case SC_NOT_EQUAL:
                     bValid = !bEqual;
@@ -810,7 +813,7 @@ bool ScDBQueryDataIterator::DataAccessMatrix::isValidQuery(SCROW nRow, const ScM
                     ;
             }
         }
-        else if (lcl_isQueryByString(rEntry, rMat, nField, nRow))
+        else if (isQueryByString(rEntry, rItem, rMat, nField, nRow))
         {
             // By string
             do
@@ -819,7 +822,7 @@ bool ScDBQueryDataIterator::DataAccessMatrix::isValidQuery(SCROW nRow, const ScM
 
                 OUString aMatStr = rMat.GetString(nField, nRow);
                 lcl_toUpper(aMatStr);
-                OUString aQueryStr = rEntry.GetQueryString();
+                OUString aQueryStr = rEntry.GetQueryItem().maString;
                 lcl_toUpper(aQueryStr);
                 bool bDone = false;
                 switch (rEntry.eOp)
@@ -1104,10 +1107,11 @@ ScQueryCellIterator::ScQueryCellIterator(ScDocument* pDocument, SCTAB nTable,
         for (i = 0; (i < nCount) && (aParam.GetEntry(i).bDoQuery); ++i)
         {
             ScQueryEntry& rEntry = aParam.GetEntry(i);
+            ScQueryEntry::Item& rItem = rEntry.GetQueryItem();
             sal_uInt32 nIndex = 0;
-            rEntry.bQueryByString =
-                !(pDoc->GetFormatTable()->IsNumberFormat(
-                    rEntry.GetQueryString(), nIndex, rEntry.nVal));
+            bool bNumber = pDoc->GetFormatTable()->IsNumberFormat(
+                rItem.maString, nIndex, rItem.mfVal);
+            rItem.meType = bNumber ? ScQueryEntry::ByValue : ScQueryEntry::ByString;
         }
     }
     nNumFormat = 0;                 // werden bei GetNumberFormat initialisiert
@@ -1121,11 +1125,13 @@ ScBaseCell* ScQueryCellIterator::GetThis()
         OSL_FAIL("try to access index out of bounds, FIX IT");
     ScColumn* pCol = &(pDoc->maTabs[nTab])->aCol[nCol];
     const ScQueryEntry& rEntry = aParam.GetEntry(0);
+    const ScQueryEntry::Item& rItem = rEntry.GetQueryItem();
+
     SCCOLROW nFirstQueryField = rEntry.nField;
     bool bAllStringIgnore = bIgnoreMismatchOnLeadingStrings &&
-        !rEntry.bQueryByString;
+        rItem.meType != ScQueryEntry::ByString;
     bool bFirstStringIgnore = bIgnoreMismatchOnLeadingStrings &&
-        !aParam.bHasHeader && rEntry.bQueryByString &&
+        !aParam.bHasHeader && rItem.meType == ScQueryEntry::ByString &&
         ((aParam.bByRow && nRow == aParam.nRow1) ||
          (!aParam.bByRow && nCol == aParam.nCol1));
     for ( ;; )
@@ -1148,7 +1154,7 @@ ScBaseCell* ScQueryCellIterator::GetThis()
             } while ( pCol->nCount == 0 );
             pCol->Search( nRow, nColRow );
             bFirstStringIgnore = bIgnoreMismatchOnLeadingStrings &&
-                !aParam.bHasHeader && rEntry.bQueryByString &&
+                !aParam.bHasHeader && rItem.meType == ScQueryEntry::ByString &&
                 aParam.bByRow;
         }
 
@@ -1267,7 +1273,7 @@ sal_Bool ScQueryCellIterator::FindEqualOrSortedLastInRange( SCCOL& nFoundCol,
     SetStopOnMismatch( sal_True );      // assume sorted keys
     SetTestEqualCondition( sal_True );
     bIgnoreMismatchOnLeadingStrings = bIgnoreMismatchOnLeadingStringsP;
-    bool bRegExp = aParam.bRegExp && aParam.GetEntry(0).bQueryByString;
+    bool bRegExp = aParam.bRegExp && aParam.GetEntry(0).GetQueryItem().meType == ScQueryEntry::ByString;
     bool bBinary = !bRegExp && aParam.bByRow && (aParam.GetEntry(0).eOp ==
             SC_LESS_EQUAL || aParam.GetEntry(0).eOp == SC_GREATER_EQUAL);
     if (bBinary ? (BinarySearch() ? GetThis() : 0) : GetFirst())
@@ -1396,8 +1402,9 @@ ScBaseCell* ScQueryCellIterator::BinarySearch()
         ScGlobal::GetCollator());
     SvNumberFormatter& rFormatter = *(pDoc->GetFormatTable());
     const ScQueryEntry& rEntry = aParam.GetEntry(0);
+    const ScQueryEntry::Item& rItem = rEntry.GetQueryItem();
     bool bLessEqual = rEntry.eOp == SC_LESS_EQUAL;
-    bool bByString = rEntry.bQueryByString;
+    bool bByString = rItem.meType == ScQueryEntry::ByString;
     bool bAllStringIgnore = bIgnoreMismatchOnLeadingStrings && !bByString;
     bool bFirstStringIgnore = bIgnoreMismatchOnLeadingStrings &&
         !aParam.bHasHeader && bByString;
@@ -1413,7 +1420,7 @@ ScBaseCell* ScQueryCellIterator::BinarySearch()
         sal_uLong nFormat = pCol->GetNumberFormat( pItems[nLo].nRow);
         ScCellFormat::GetInputString( pItems[nLo].pCell, nFormat, aCellStr,
                 rFormatter);
-        sal_Int32 nTmp = pCollator->compareString(aCellStr, rEntry.GetQueryString());
+        sal_Int32 nTmp = pCollator->compareString(aCellStr, rEntry.GetQueryItem().maString);
         if ((rEntry.eOp == SC_LESS_EQUAL && nTmp > 0) ||
                 (rEntry.eOp == SC_GREATER_EQUAL && nTmp < 0) ||
                 (rEntry.eOp == SC_EQUAL && nTmp != 0))
@@ -1502,8 +1509,8 @@ ScBaseCell* ScQueryCellIterator::BinarySearch()
                 default:
                     nCellVal = 0.0;
             }
-            if ((nCellVal < rEntry.nVal) && !::rtl::math::approxEqual(
-                        nCellVal, rEntry.nVal))
+            if ((nCellVal < rItem.mfVal) && !::rtl::math::approxEqual(
+                        nCellVal, rItem.mfVal))
             {
                 nRes = -1;
                 if (bLessEqual)
@@ -1521,8 +1528,8 @@ ScBaseCell* ScQueryCellIterator::BinarySearch()
                     }
                 }
             }
-            else if ((nCellVal > rEntry.nVal) && !::rtl::math::approxEqual(
-                        nCellVal, rEntry.nVal))
+            else if ((nCellVal > rItem.mfVal) && !::rtl::math::approxEqual(
+                        nCellVal, rItem.mfVal))
             {
                 nRes = 1;
                 if (!bLessEqual)
@@ -1547,7 +1554,7 @@ ScBaseCell* ScQueryCellIterator::BinarySearch()
             sal_uLong nFormat = pCol->GetNumberFormat( pItems[i].nRow);
             ScCellFormat::GetInputString( pItems[i].pCell, nFormat, aCellStr,
                     rFormatter);
-            nRes = pCollator->compareString( aCellStr, rEntry.GetQueryString());
+            nRes = pCollator->compareString(aCellStr, rEntry.GetQueryItem().maString);
             if (nRes < 0 && bLessEqual)
             {
                 sal_Int32 nTmp = pCollator->compareString( aLastInRangeString,
diff --git a/sc/source/core/data/dpshttab.cxx b/sc/source/core/data/dpshttab.cxx
index 5f97b2b..fc4072d 100644
--- a/sc/source/core/data/dpshttab.cxx
+++ b/sc/source/core/data/dpshttab.cxx
@@ -71,24 +71,25 @@ ScSheetDPData::ScSheetDPData(ScDocument* pD, const ScSheetSourceDesc& rDesc, con
 {
     SCSIZE nEntryCount( aQuery.GetEntryCount());
     pSpecial = new bool[nEntryCount];
-    for (SCSIZE j = 0; j < nEntryCount; ++j )
+    for (SCSIZE j = 0; j < nEntryCount; ++j)
     {
         ScQueryEntry& rEntry = aQuery.GetEntry(j);
         if (rEntry.bDoQuery)
         {
-           pSpecial[j] = false;
-            if (!rEntry.bQueryByString)
+            ScQueryEntry::Item& rItem = rEntry.GetQueryItem();
+            pSpecial[j] = false;
+            if (rItem.meType != ScQueryEntry::ByString)
             {
-                if (rEntry.GetQueryString().isEmpty() &&
-                   ((rEntry.nVal == SC_EMPTYFIELDS) || (rEntry.nVal == SC_NONEMPTYFIELDS)))
+                if (rItem.maString.isEmpty() &&
+                   ((rItem.mfVal == SC_EMPTYFIELDS) || (rItem.mfVal == SC_NONEMPTYFIELDS)))
                     pSpecial[j] = true;
             }
             else
             {
                 sal_uInt32 nIndex = 0;
-                rEntry.bQueryByString =
-                    !(pD->GetFormatTable()->IsNumberFormat(
-                        rEntry.GetQueryString(), nIndex, rEntry.nVal));
+                bool bNumber = pD->GetFormatTable()->IsNumberFormat(
+                    rItem.maString, nIndex, rItem.mfVal);
+                rItem.meType = bNumber ? ScQueryEntry::ByValue : ScQueryEntry::ByString;
             }
         }
     }
diff --git a/sc/source/core/data/dptablecache.cxx b/sc/source/core/data/dptablecache.cxx
index 133d231..4c894d7 100644
--- a/sc/source/core/data/dptablecache.cxx
+++ b/sc/source/core/data/dptablecache.cxx
@@ -601,6 +601,7 @@ bool ScDPCache::ValidQuery( SCROW nRow, const ScQueryParam &rParam, bool *pSpeci
     while ((i < nEntryCount) && rParam.GetEntry(i).bDoQuery)
     {
         const ScQueryEntry& rEntry = rParam.GetEntry(i);
+        const ScQueryEntry::Item& rItem = rEntry.GetQueryItem();
         // we can only handle one single direct query
         // #i115431# nField in QueryParam is the sheet column, not the field within the source range
         SCCOL nQueryCol = (SCCOL)rEntry.nField;
@@ -617,34 +618,34 @@ bool ScDPCache::ValidQuery( SCROW nRow, const ScQueryParam &rParam, bool *pSpeci
 
         if (pSpecial && pSpecial[i])
         {
-            if (rEntry.nVal == SC_EMPTYFIELDS)
+            if (rItem.mfVal == SC_EMPTYFIELDS)
                 bOk = ! pCellData->IsHasData();
             else // if (rEntry.nVal == SC_NONEMPTYFIELDS)
                 bOk =  pCellData->IsHasData();
         }
-        else if (!rEntry.bQueryByString && pCellData->IsValue())
+        else if (rEntry.GetQueryItem().meType != ScQueryEntry::ByString && pCellData->IsValue())
         {   // by Value
             double nCellVal = pCellData->GetValue();
 
             switch (rEntry.eOp)
             {
                 case SC_EQUAL :
-                    bOk = ::rtl::math::approxEqual( nCellVal, rEntry.nVal );
+                    bOk = ::rtl::math::approxEqual(nCellVal, rItem.mfVal);
                     break;
                 case SC_LESS :
-                    bOk = (nCellVal < rEntry.nVal) && !::rtl::math::approxEqual( nCellVal, rEntry.nVal );
+                    bOk = (nCellVal < rItem.mfVal) && !::rtl::math::approxEqual(nCellVal, rItem.mfVal);
                     break;
                 case SC_GREATER :
-                    bOk = (nCellVal > rEntry.nVal) && !::rtl::math::approxEqual( nCellVal, rEntry.nVal );
+                    bOk = (nCellVal > rItem.mfVal) && !::rtl::math::approxEqual(nCellVal, rItem.mfVal);
                     break;
                 case SC_LESS_EQUAL :
-                    bOk = (nCellVal < rEntry.nVal) || ::rtl::math::approxEqual( nCellVal, rEntry.nVal );
+                    bOk = (nCellVal < rItem.mfVal) || ::rtl::math::approxEqual(nCellVal, rItem.mfVal);
                     break;
                 case SC_GREATER_EQUAL :
-                    bOk = (nCellVal > rEntry.nVal) || ::rtl::math::approxEqual( nCellVal, rEntry.nVal );
+                    bOk = (nCellVal > rItem.mfVal) || ::rtl::math::approxEqual(nCellVal, rItem.mfVal);
                     break;
                 case SC_NOT_EQUAL :
-                    bOk = !::rtl::math::approxEqual( nCellVal, rEntry.nVal );
+                    bOk = !::rtl::math::approxEqual(nCellVal, rItem.mfVal);
                     break;
                 default:
                     bOk= false;
@@ -652,7 +653,7 @@ bool ScDPCache::ValidQuery( SCROW nRow, const ScQueryParam &rParam, bool *pSpeci
             }
         }
         else if ((rEntry.eOp == SC_EQUAL || rEntry.eOp == SC_NOT_EQUAL)
-                 || (rEntry.bQueryByString
+                 || (rEntry.GetQueryItem().meType == ScQueryEntry::ByString
                      && pCellData->HasStringData() )
                 )
         {   // by String
@@ -682,7 +683,7 @@ bool ScDPCache::ValidQuery( SCROW nRow, const ScQueryParam &rParam, bool *pSpeci
                 {
                     if (bMatchWholeCell)
                     {
-                        String aStr = rEntry.GetQueryString();
+                        String aStr = rEntry.GetQueryItem().maString;
                         bOk = pTransliteration->isEqual(aCellStr, aStr);
                         bool bHasStar = false;
                         xub_StrLen nIndex;
@@ -706,11 +707,12 @@ bool ScDPCache::ValidQuery( SCROW nRow, const ScQueryParam &rParam, bool *pSpeci
                     }
                     else
                     {
+                        const rtl::OUString& rQueryStr = rEntry.GetQueryItem().maString;
                         ::com::sun::star::uno::Sequence< sal_Int32 > xOff;
                         String aCell = pTransliteration->transliterate(
                             aCellStr, ScGlobal::eLnge, 0, aCellStr.Len(), &xOff);
                         String aQuer = pTransliteration->transliterate(
-                            rEntry.GetQueryString(), ScGlobal::eLnge, 0, rEntry.GetQueryString().getLength(), &xOff);
+                            rQueryStr, ScGlobal::eLnge, 0, rQueryStr.getLength(), &xOff);
                         bOk = (aCell.Search( aQuer ) != STRING_NOTFOUND);
                     }
                     if (rEntry.eOp == SC_NOT_EQUAL)
@@ -719,7 +721,7 @@ bool ScDPCache::ValidQuery( SCROW nRow, const ScQueryParam &rParam, bool *pSpeci
                 else
                 {   // use collator here because data was probably sorted
                     sal_Int32 nCompare = pCollator->compareString(
-                        aCellStr, rEntry.GetQueryString());
+                        aCellStr, rEntry.GetQueryItem().maString);
                     switch (rEntry.eOp)
                     {
                         case SC_LESS :
diff --git a/sc/source/core/data/table3.cxx b/sc/source/core/data/table3.cxx
index b4a8ff5..0ad9736 100644
--- a/sc/source/core/data/table3.cxx
+++ b/sc/source/core/data/table3.cxx
@@ -1067,15 +1067,17 @@ bool ScTable::DoSubTotals( ScSubTotalParam& rParam )
 
 namespace {
 
-bool isQueryByValue(const ScTable& rTable, const ScQueryEntry& rEntry, SCROW nRow, const ScBaseCell* pCell)
+bool isQueryByValue(
+    const ScTable& rTable, const ScQueryEntry::Item& rItem,
+    SCCOL nCol, SCROW nRow, const ScBaseCell* pCell)
 {
-    if (rEntry.bQueryByString)
+    if (rItem.meType != ScQueryEntry::ByString)
         return false;
 
     if (pCell)
         return pCell->HasValueData();
 
-    return rTable.HasValueData(static_cast<SCCOL>(rEntry.nField), nRow);
+    return rTable.HasValueData(nCol, nRow);
 }
 
 bool isPartialTextMatchOp(const ScQueryEntry& rEntry)
@@ -1113,18 +1115,20 @@ bool isTextMatchOp(const ScQueryEntry& rEntry)
     return false;
 }
 
-bool isQueryByString(const ScTable& rTable, const ScQueryEntry& rEntry, SCROW nRow, const ScBaseCell* pCell)
+bool isQueryByString(
+    const ScTable& rTable, const ScQueryEntry& rEntry, const ScQueryEntry::Item& rItem,
+    SCCOL nCol, SCROW nRow, const ScBaseCell* pCell)
 {
     if (isTextMatchOp(rEntry))
         return true;
 
-    if (!rEntry.bQueryByString)
+    if (rItem.meType != ScQueryEntry::ByString)
         return false;
 
     if (pCell)
         return pCell->HasStringData();
 
-    return rTable.HasStringData(static_cast<SCCOL>(rEntry.nField), nRow);
+    return rTable.HasStringData(nCol, nRow);
 }
 
 bool isRealRegExp(const ScQueryParam& rParam, const ScQueryEntry& rEntry)
@@ -1171,21 +1175,27 @@ bool ScTable::ValidQuery(SCROW nRow, const ScQueryParam& rParam,
     for (size_t i = 0; i < nEntryCount && rParam.GetEntry(i).bDoQuery; ++i)
     {
         const ScQueryEntry& rEntry = rParam.GetEntry(i);
+        SCCOL nCol = static_cast<SCCOL>(rEntry.nField);
+
         // we can only handle one single direct query
         if ( !pCell || i > 0 )
-            pCell = GetCell( static_cast<SCCOL>(rEntry.nField), nRow );
+            pCell = GetCell(nCol, nRow);
 
         bool bOk = false;
         bool bTestEqual = false;
 
+        // For now, we only handle single item queries.  We need to adopt this
+        // to multi-item queries later.
+        const ScQueryEntry::Item& rItem = rEntry.GetQueryItem();
+
         if ( pSpecial && pSpecial[i] )
         {
-            if (rEntry.nVal == SC_EMPTYFIELDS)
+            if (rItem.mfVal == SC_EMPTYFIELDS)
                 bOk = !( aCol[rEntry.nField].HasDataAt( nRow ) );
             else // if (rEntry.nVal == SC_NONEMPTYFIELDS)
                 bOk = aCol[rEntry.nField].HasDataAt( nRow );
         }
-        else if (isQueryByValue(*this, rEntry, nRow, pCell))
+        else if (isQueryByValue(*this, rItem, nCol, nRow, pCell))
         {
             double nCellVal;
             if ( pCell )
@@ -1204,7 +1214,7 @@ bool ScTable::ValidQuery(SCROW nRow, const ScQueryParam& rParam,
 
             }
             else
-                nCellVal = GetValue( static_cast<SCCOL>(rEntry.nField), nRow );
+                nCellVal = GetValue(nCol, nRow);
 
             /* NOTE: lcl_PrepareQuery() prepares a filter query such that if a
              * date+time format was queried rEntry.bQueryByDate is not set. In
@@ -1212,9 +1222,9 @@ bool ScTable::ValidQuery(SCROW nRow, const ScQueryParam& rParam,
              * the same, in other words only if rEntry.nVal is an integer value
              * rEntry.bQueryByDate should be true and the time fraction be
              * stripped here. */
-            if (rEntry.bQueryByDate)
+            if (rItem.meType == ScQueryEntry::ByDate)
             {
-                sal_uInt32 nNumFmt = GetNumberFormat(static_cast<SCCOL>(rEntry.nField), nRow);
+                sal_uInt32 nNumFmt = GetNumberFormat(nCol, nRow);
                 const SvNumberformat* pEntry = pDocument->GetFormatTable()->GetEntry(nNumFmt);
                 if (pEntry)
                 {
@@ -1237,26 +1247,26 @@ bool ScTable::ValidQuery(SCROW nRow, const ScQueryParam& rParam,
             switch (rEntry.eOp)
             {
                 case SC_EQUAL :
-                    bOk = ::rtl::math::approxEqual( nCellVal, rEntry.nVal );
+                    bOk = ::rtl::math::approxEqual(nCellVal, rItem.mfVal);
                     break;
                 case SC_LESS :
-                    bOk = (nCellVal < rEntry.nVal) && !::rtl::math::approxEqual( nCellVal, rEntry.nVal );
+                    bOk = (nCellVal < rItem.mfVal) && !::rtl::math::approxEqual(nCellVal, rItem.mfVal);
                     break;
                 case SC_GREATER :
-                    bOk = (nCellVal > rEntry.nVal) && !::rtl::math::approxEqual( nCellVal, rEntry.nVal );
+                    bOk = (nCellVal > rItem.mfVal) && !::rtl::math::approxEqual(nCellVal, rItem.mfVal);
                     break;
                 case SC_LESS_EQUAL :
-                    bOk = (nCellVal < rEntry.nVal) || ::rtl::math::approxEqual( nCellVal, rEntry.nVal );
+                    bOk = (nCellVal < rItem.mfVal) || ::rtl::math::approxEqual(nCellVal, rItem.mfVal);
                     if ( bOk && pbTestEqualCondition )
-                        bTestEqual = ::rtl::math::approxEqual( nCellVal, rEntry.nVal );
+                        bTestEqual = ::rtl::math::approxEqual(nCellVal, rItem.mfVal);
                     break;
                 case SC_GREATER_EQUAL :
-                    bOk = (nCellVal > rEntry.nVal) || ::rtl::math::approxEqual( nCellVal, rEntry.nVal );
+                    bOk = (nCellVal > rItem.mfVal) || ::rtl::math::approxEqual( nCellVal, rItem.mfVal);
                     if ( bOk && pbTestEqualCondition )
-                        bTestEqual = ::rtl::math::approxEqual( nCellVal, rEntry.nVal );
+                        bTestEqual = ::rtl::math::approxEqual(nCellVal, rItem.mfVal);
                     break;
                 case SC_NOT_EQUAL :
-                    bOk = !::rtl::math::approxEqual( nCellVal, rEntry.nVal );
+                    bOk = !::rtl::math::approxEqual(nCellVal, rItem.mfVal);
                     break;
                 default:
                 {
@@ -1264,7 +1274,7 @@ bool ScTable::ValidQuery(SCROW nRow, const ScQueryParam& rParam,
                 }
             }
         }
-        else if (isQueryByString(*this, rEntry, nRow, pCell))
+        else if (isQueryByString(*this, rEntry, rItem, nCol, nRow, pCell))
         {
             rtl::OUString  aCellStr;
             if (isPartialTextMatchOp(rEntry))
@@ -1343,7 +1353,7 @@ bool ScTable::ValidQuery(SCROW nRow, const ScQueryParam& rParam,
                 // Simple string matching i.e. no regexp match.
                 if (isTextMatchOp(rEntry))
                 {
-                    if (!rEntry.bQueryByString && rEntry.IsQueryStringEmpty())
+                    if (!rItem.meType != ScQueryEntry::ByString && rItem.maString.isEmpty())
                     {
                         // #i18374# When used from functions (match, countif, sumif, vlookup, hlookup, lookup),
                         // the query value is assigned directly, and the string is empty. In that case,
@@ -1354,18 +1364,18 @@ bool ScTable::ValidQuery(SCROW nRow, const ScQueryParam& rParam,
                     }
                     else if ( bMatchWholeCell )
                     {
-                        bOk = rEntry.MatchByString(aCellStr, rParam.bCaseSens);
+                        bOk = pTransliteration->isEqual(aCellStr, rEntry.GetQueryItem().maString);
                         if ( rEntry.eOp == SC_NOT_EQUAL )
                             bOk = !bOk;
                     }
                     else
                     {
-                        rtl::OUString aQueryStr = rEntry.GetQueryString();
+                        const rtl::OUString& rQueryStr = rItem.maString;
                         String aCell( pTransliteration->transliterate(
                             aCellStr, ScGlobal::eLnge, 0, aCellStr.getLength(),
                             NULL ) );
                         String aQuer( pTransliteration->transliterate(
-                            aQueryStr, ScGlobal::eLnge, 0, aQueryStr.getLength(),
+                            rQueryStr, ScGlobal::eLnge, 0, rQueryStr.getLength(),
                             NULL ) );
                         xub_StrLen nIndex = (rEntry.eOp == SC_ENDS_WITH
                             || rEntry.eOp == SC_DOES_NOT_END_WITH)? (aCell.Len()-aQuer.Len()):0;
@@ -1402,7 +1412,7 @@ bool ScTable::ValidQuery(SCROW nRow, const ScQueryParam& rParam,
                 else
                 {   // use collator here because data was probably sorted
                     sal_Int32 nCompare = pCollator->compareString(
-                        aCellStr, rEntry.GetQueryString());
+                        aCellStr, rEntry.GetQueryItem().maString);
                     switch (rEntry.eOp)
                     {
                         case SC_LESS :
@@ -1431,14 +1441,14 @@ bool ScTable::ValidQuery(SCROW nRow, const ScQueryParam& rParam,
         }
         else if (rParam.bMixedComparison)
         {
-            if (rEntry.bQueryByString &&
+            if (rItem.meType == ScQueryEntry::ByString &&
                     (rEntry.eOp == SC_LESS || rEntry.eOp == SC_LESS_EQUAL) &&
                     (pCell ? pCell->HasValueData() :
                      HasValueData( static_cast<SCCOL>(rEntry.nField), nRow)))
             {
                 bOk = true;
             }
-            else if (!rEntry.bQueryByString &&
+            else if (rItem.meType != ScQueryEntry::ByString &&
                     (rEntry.eOp == SC_GREATER || rEntry.eOp == SC_GREATER_EQUAL) &&
                     (pCell ? pCell->HasStringData() :
                      HasStringData( static_cast<SCCOL>(rEntry.nField), nRow)))
@@ -1491,6 +1501,8 @@ void ScTable::TopTenQuery( ScQueryParam& rParam )
     for ( SCSIZE i=0; (i<nEntryCount) && (rParam.GetEntry(i).bDoQuery); i++ )
     {
         ScQueryEntry& rEntry = rParam.GetEntry(i);
+        ScQueryEntry::Item& rItem = rEntry.GetQueryItem();
+
         switch ( rEntry.eOp )
         {
             case SC_TOPVAL:
@@ -1520,12 +1532,12 @@ void ScTable::TopTenQuery( ScQueryParam& rParam )
                     nValidCount--;
                 if ( nValidCount > 0 )
                 {
-                    if ( rEntry.bQueryByString )
+                    if ( rItem.meType == ScQueryEntry::ByString )
                     {   // dat wird nix
-                        rEntry.bQueryByString = false;
-                        rEntry.nVal = 10;   // 10 bzw. 10%
+                        rItem.meType = ScQueryEntry::ByValue;
+                        rItem.mfVal = 10;   // 10 bzw. 10%
                     }
-                    SCSIZE nVal = (rEntry.nVal >= 1 ? static_cast<SCSIZE>(rEntry.nVal) : 1);
+                    SCSIZE nVal = (rItem.mfVal >= 1 ? static_cast<SCSIZE>(rItem.mfVal) : 1);
                     SCSIZE nOffset = 0;
                     switch ( rEntry.eOp )
                     {
@@ -1574,22 +1586,22 @@ void ScTable::TopTenQuery( ScQueryParam& rParam )
                     if ( pCell->HasValueData() )
                     {
                         if ( pCell->GetCellType() == CELLTYPE_VALUE )
-                            rEntry.nVal = ((ScValueCell*)pCell)->GetValue();
+                            rItem.mfVal = ((ScValueCell*)pCell)->GetValue();
                         else
-                            rEntry.nVal = ((ScFormulaCell*)pCell)->GetValue();
+                            rItem.mfVal = ((ScFormulaCell*)pCell)->GetValue();
                     }
                     else
                     {
                         OSL_FAIL( "TopTenQuery: pCell kein ValueData" );
                         rEntry.eOp = SC_GREATER_EQUAL;
-                        rEntry.nVal = 0;
+                        rItem.mfVal = 0;
                     }
                 }
                 else
                 {
                     rEntry.eOp = SC_GREATER_EQUAL;
-                    rEntry.bQueryByString = false;
-                    rEntry.nVal = 0;
+                    rItem.meType = ScQueryEntry::ByValue;
+                    rItem.mfVal = 0;
                 }
                 delete pArray;
             }
@@ -1615,35 +1627,35 @@ static void lcl_PrepareQuery( ScDocument* pDoc, ScTable* pTab, ScQueryParam& rPa
         ScQueryEntry& rEntry = rParam.GetEntry(i);
         if ( rEntry.bDoQuery )
         {
-            rEntry.SortQueryStrings(rParam.bCaseSens);
-
-            if ( rEntry.bQueryByString )
+            // TODO: adapt this for multi-query items.
+            ScQueryEntry::Item& rItem = rEntry.GetQueryItem();
+            if (rItem.meType != ScQueryEntry::ByString)
             {
                 sal_uInt32 nIndex = 0;
-                rEntry.bQueryByString = !( pDoc->GetFormatTable()->
-                    IsNumberFormat(rEntry.GetQueryString(), nIndex, rEntry.nVal));
-                if (rEntry.bQueryByDate)
+                bool bNumber = pDoc->GetFormatTable()->
+                    IsNumberFormat(rItem.maString, nIndex, rItem.mfVal);
+                if (rItem.meType == ScQueryEntry::ByDate)
                 {
-                    if (!rEntry.bQueryByString && ((nIndex % SV_COUNTRY_LANGUAGE_OFFSET) != 0))
+                    if (bNumber && ((nIndex % SV_COUNTRY_LANGUAGE_OFFSET) != 0))
                     {
                         const SvNumberformat* pEntry = pDoc->GetFormatTable()->GetEntry(nIndex);
                         if (pEntry)
                         {
                             short nNumFmtType = pEntry->GetType();
                             if (!((nNumFmtType & NUMBERFORMAT_DATE) && !(nNumFmtType & NUMBERFORMAT_TIME)))
-                                rEntry.bQueryByDate = false;    // not a date only
+                                rItem.meType = ScQueryEntry::ByValue;    // not a date only
                         }
                         else
-                            rEntry.bQueryByDate = false;    // what the ... not a date
+                            rItem.meType = ScQueryEntry::ByValue;    // what the ... not a date
                     }
                     else
-                        rEntry.bQueryByDate = false;    // not a date
+                        rItem.meType = ScQueryEntry::ByValue;    // not a date
                 }
             }
             else
             {
                 // call from UNO or second call from autofilter
-                if ( rEntry.nVal == SC_EMPTYFIELDS || rEntry.nVal == SC_NONEMPTYFIELDS )
+                if ( rItem.mfVal == SC_EMPTYFIELDS || rItem.mfVal == SC_NONEMPTYFIELDS )
                 {
                     pSpecial[i] = true;
                 }
@@ -1965,9 +1977,9 @@ bool ScTable::CreateStarQuery(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2
         // Vierte Spalte Wert
         if (bValid)
         {
-            rtl::OUString rStr;
-            GetString(nCol1 + 3, nRow, rStr);
-            rEntry.SetQueryString(rStr);
+            rtl::OUString aStr;
+            GetString(nCol1 + 3, nRow, aStr);
+            rEntry.GetQueryItem().maString = aStr;
             rEntry.bDoQuery = true;
         }
         nIndex++;
@@ -1998,7 +2010,7 @@ bool ScTable::CreateQueryParam(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow
     {
         //  bQueryByString muss gesetzt sein
         for (i=0; i < nCount; i++)
-            rQueryParam.GetEntry(i).bQueryByString = true;
+            rQueryParam.GetEntry(i).GetQueryItem().meType = ScQueryEntry::ByString;
     }
     else
     {
diff --git a/sc/source/core/tool/doubleref.cxx b/sc/source/core/tool/doubleref.cxx
index a4e745e..15e6d53 100644
--- a/sc/source/core/tool/doubleref.cxx
+++ b/sc/source/core/tool/doubleref.cxx
@@ -142,7 +142,7 @@ bool lcl_createStarQuery(ScQueryParamBase* pParam, const ScDBRangeBase* pDBRef,
         if (bValid)
         {
             // Finally, the right-hand-side value in the 4th column.
-            rEntry.SetQueryString(pQueryRef->getString(3, nRow));
+            rEntry.GetQueryItem().maString = pQueryRef->getString(3, nRow);
             rEntry.bDoQuery = true;
         }
         nIndex++;
@@ -236,7 +236,7 @@ bool lcl_fillQueryEntries(
     {
         //  bQueryByString muss gesetzt sein
         for (SCSIZE i = 0; i < nCount; ++i)
-            pParam->GetEntry(i).bQueryByString = true;
+            pParam->GetEntry(i).GetQueryItem().meType = ScQueryEntry::ByString;
     }
     else
     {
diff --git a/sc/source/core/tool/interpr1.cxx b/sc/source/core/tool/interpr1.cxx
index 3a53890..a0a577f 100644
--- a/sc/source/core/tool/interpr1.cxx
+++ b/sc/source/core/tool/interpr1.cxx
@@ -752,7 +752,7 @@ double ScInterpreter::CompareFunc( const ScCompare& rComp, ScCompareOptions* pOp
             // is/must be identical to *rEntry.pStr, which is essential for
             // regex to work through GetSearchTextPtr().
             ScQueryEntry& rEntry = pOptions->aQueryEntry;
-            OSL_ENSURE(rEntry.GetQueryString().equals(*rComp.pVal[1]), "ScInterpreter::CompareFunc: broken options");
+            OSL_ENSURE(rEntry.GetQueryItem().maString.equals(*rComp.pVal[1]), "ScInterpreter::CompareFunc: broken options");
             if (pOptions->bRegEx)
             {
                 xub_StrLen nStart = 0;
@@ -1029,10 +1029,11 @@ ScMatrixRef ScInterpreter::QueryMat( const ScMatrixRef& pMat, ScCompareOptions&
     short nSaveCurFmtType = nCurFmtType;
     short nSaveFuncFmtType = nFuncFmtType;
     PushMatrix( pMat);
-    if (rOptions.aQueryEntry.bQueryByString)
-        PushString(rOptions.aQueryEntry.GetQueryString());
+    const ScQueryEntry::Item& rItem = rOptions.aQueryEntry.GetQueryItem();
+    if (rItem.meType == ScQueryEntry::ByString)
+        PushString(rItem.maString);
     else
-        PushDouble( rOptions.aQueryEntry.nVal);
+        PushDouble(rItem.mfVal);
     ScMatrixRef pResultMatrix = CompareMat( &rOptions);
     nCurFmtType = nSaveCurFmtType;
     nFuncFmtType = nSaveFuncFmtType;
@@ -4332,26 +4333,27 @@ static sal_Int32 lcl_CompareMatrix2Query(
     /* FIXME: what is an empty path (result of IF(false;true_path) in
      * comparisons? */
 
+    bool bByString = rEntry.GetQueryItem().meType == ScQueryEntry::ByString;
     if (rMat.IsValue(i))
     {
-        if (rEntry.bQueryByString)
+        if (bByString)
             return -1;  // numeric always less than string
 
         const double nVal1 = rMat.GetDouble(i);
-        const double nVal2 = rEntry.nVal;
+        const double nVal2 = rEntry.GetQueryItem().mfVal;
         if (nVal1 == nVal2)
             return 0;
 
         return nVal1 < nVal2 ? -1 : 1;
     }
 
-    if (!rEntry.bQueryByString)
+    if (!bByString)
         return 1;       // string always greater than numeric
 
-    const rtl::OUString rStr1 = rMat.GetString(i);
-    const rtl::OUString rStr2 = rEntry.GetQueryString();
+    const rtl::OUString aStr1 = rMat.GetString(i);
+    const rtl::OUString& rStr2 = rEntry.GetQueryItem().maString;
 
-    return ScGlobal::GetCollator()->compareString( rStr1, rStr2); // case-insensitive
+    return ScGlobal::GetCollator()->compareString(aStr1, rStr2); // case-insensitive
 }
 
 /** returns the last item with the identical value as the original item
@@ -4474,6 +4476,7 @@ void ScInterpreter::ScMatch()
             rParam.bMixedComparison = true;
 
             ScQueryEntry& rEntry = rParam.GetEntry(0);
+            ScQueryEntry::Item& rItem = rEntry.GetQueryItem();
             rEntry.bDoQuery = true;
             if (fTyp < 0.0)
                 rEntry.eOp = SC_GREATER_EQUAL;
@@ -4484,15 +4487,15 @@ void ScInterpreter::ScMatch()
                 case svDouble:
                 {
                     fVal = GetDouble();
-                    rEntry.bQueryByString = false;
-                    rEntry.nVal = fVal;
+                    rItem.mfVal = fVal;
+                    rItem.meType = ScQueryEntry::ByValue;
                 }
                 break;
                 case svString:
                 {
                     sStr = GetString();
-                    rEntry.bQueryByString = true;
-                    rEntry.SetQueryString(sStr);
+                    rItem.meType = ScQueryEntry::ByString;
+                    rItem.maString = sStr;
                 }
                 break;
                 case svDoubleRef :
@@ -4508,14 +4511,14 @@ void ScInterpreter::ScMatch()
                     if (HasCellValueData(pCell))
                     {
                         fVal = GetCellValue( aAdr, pCell );
-                        rEntry.bQueryByString = false;
-                        rEntry.nVal = fVal;
+                        rItem.meType = ScQueryEntry::ByValue;
+                        rItem.mfVal = fVal;
                     }
                     else
                     {
                         GetCellString(sStr, pCell);
-                        rEntry.bQueryByString = true;
-                        rEntry.SetQueryString(sStr);
+                        rItem.meType = ScQueryEntry::ByString;
+                        rItem.maString = sStr;
                     }
                 }
                 break;
@@ -4530,13 +4533,13 @@ void ScInterpreter::ScMatch()
                     }
                     if (pToken->GetType() == svDouble)
                     {
-                        rEntry.bQueryByString = false;
-                        rEntry.nVal = pToken->GetDouble();
+                        rItem.meType = ScQueryEntry::ByValue;
+                        rItem.mfVal = pToken->GetDouble();
                     }
                     else
                     {
-                        rEntry.bQueryByString = true;
-                        rEntry.SetQueryString(pToken->GetString());
+                        rItem.meType = ScQueryEntry::ByString;
+                        rItem.maString = pToken->GetString();
                     }
                 }
                 break;
@@ -4549,9 +4552,10 @@ void ScInterpreter::ScMatch()
                 {
                     String aStr;
                     ScMatValType nType = GetDoubleOrStringFromMatrix(
-                            rEntry.nVal, aStr);
-                    rEntry.SetQueryString(aStr);
-                    rEntry.bQueryByString = ScMatrix::IsNonValueType( nType);
+                            rItem.mfVal, aStr);
+                    rItem.maString = aStr;
+                    rItem.meType = ScMatrix::IsNonValueType(nType) ?
+                        ScQueryEntry::ByString : ScQueryEntry::ByValue;
                 }
                 break;
                 default:
@@ -4560,7 +4564,7 @@ void ScInterpreter::ScMatch()
                     return;
                 }
             }
-            if ( rEntry.bQueryByString )
+            if (rItem.meType == ScQueryEntry::ByString)
             {
                 bool bIsVBAMode = false;
                 if ( pDok )
@@ -4570,7 +4574,7 @@ void ScInterpreter::ScMatch()
                 if ( bIsVBAMode )
                     rParam.bRegExp = false;
                 else
-                    rParam.bRegExp = MayBeRegExp(rEntry.GetQueryString(), pDok);
+                    rParam.bRegExp = MayBeRegExp(rEntry.GetQueryItem().maString, pDok);
             }
 
             if (pMatSrc) // The source data is matrix array.
@@ -4903,22 +4907,23 @@ void ScInterpreter::ScCountIf()
                 rParam.nRow2       = nRow2;
 
                 ScQueryEntry& rEntry = rParam.GetEntry(0);
+                ScQueryEntry::Item& rItem = rEntry.GetQueryItem();
                 rEntry.bDoQuery = true;
                 if (!bIsString)
                 {
-                    rEntry.bQueryByString = false;
-                    rEntry.nVal = fVal;
+                    rItem.meType = ScQueryEntry::ByValue;
+                    rItem.mfVal = fVal;
                     rEntry.eOp = SC_EQUAL;
                 }
                 else
                 {
-                    rParam.FillInExcelSyntax(rtl::OUString(rString), 0);
+                    rParam.FillInExcelSyntax(rString, 0);
                     sal_uInt32 nIndex = 0;
-                    rEntry.bQueryByString =
-                        !(pFormatter->IsNumberFormat(
-                            rEntry.GetQueryString(), nIndex, rEntry.nVal));
-                    if ( rEntry.bQueryByString )
-                        rParam.bRegExp = MayBeRegExp(rEntry.GetQueryString(), pDok);
+                    bool bNumber = pFormatter->IsNumberFormat(
+                            rItem.maString, nIndex, rItem.mfVal);
+                    rItem.meType = bNumber ? ScQueryEntry::ByValue : ScQueryEntry::ByString;
+                    if (rItem.meType == ScQueryEntry::ByString)
+                        rParam.bRegExp = MayBeRegExp(rItem.maString, pDok);
                 }
                 rParam.nCol1  = nCol1;
                 rParam.nCol2  = nCol2;
@@ -5225,22 +5230,23 @@ void ScInterpreter::ScSumIf()
             rParam.nRow2       = nRow2;
 
             ScQueryEntry& rEntry = rParam.GetEntry(0);
+            ScQueryEntry::Item& rItem = rEntry.GetQueryItem();
             rEntry.bDoQuery = true;
             if (!bIsString)
             {
-                rEntry.bQueryByString = false;
-                rEntry.nVal = fVal;
+                rItem.meType = ScQueryEntry::ByValue;
+                rItem.mfVal = fVal;
                 rEntry.eOp = SC_EQUAL;
             }
             else
             {
-                rParam.FillInExcelSyntax(rtl::OUString(aString), 0);
+                rParam.FillInExcelSyntax(aString, 0);
                 sal_uInt32 nIndex = 0;
-                rEntry.bQueryByString =
-                    !(pFormatter->IsNumberFormat(
-                        rEntry.GetQueryString(), nIndex, rEntry.nVal));
-                if ( rEntry.bQueryByString )
-                    rParam.bRegExp = MayBeRegExp(rEntry.GetQueryString(), pDok);
+                bool bNumber = pFormatter->IsNumberFormat(
+                        rItem.maString, nIndex, rItem.mfVal);
+                rItem.meType = bNumber ? ScQueryEntry::ByValue : ScQueryEntry::ByString;
+                if (rItem.meType == ScQueryEntry::ByString)
+                    rParam.bRegExp = MayBeRegExp(rItem.maString, pDok);
             }
             ScAddress aAdr;
             aAdr.SetTab( nTab3 );
@@ -5545,19 +5551,21 @@ void ScInterpreter::ScLookup()
         // document it.
 
         bool bFound = false;
+        ScQueryEntry::Item& rItem = rEntry.GetQueryItem();
+
         if ( bValueData )
         {
-            if ( rEntry.bQueryByString )
+            if (rItem.meType == ScQueryEntry::ByString)
                 bFound = false;
             else
-                bFound = (fDataVal <= rEntry.nVal);
+                bFound = (fDataVal <= rItem.mfVal);
         }
         else
         {
-            if ( !rEntry.bQueryByString )
+            if (rItem.meType != ScQueryEntry::ByString)
                 bFound = false;
             else
-                bFound = (ScGlobal::GetCollator()->compareString(aDataStr, rEntry.GetQueryString()) <= 0);
+                bFound = (ScGlobal::GetCollator()->compareString(aDataStr, rItem.maString) <= 0);
         }
 
         if (!bFound)
@@ -5711,7 +5719,8 @@ void ScInterpreter::ScLookup()
             SCSIZE n = aMatAcc.GetElementCount();
             if (static_cast<SCSIZE>(i) >= n)
                 i = static_cast<SCCOLROW>(n);
-            if (static_cast<bool>(rEntry.bQueryByString) == aMatAcc.IsValue(i))
+            bool bByString = rEntry.GetQueryItem().meType == ScQueryEntry::ByString;
+            if (bByString == aMatAcc.IsValue(i))
                 bFound = false;
         }
 
@@ -5801,8 +5810,9 @@ void ScInterpreter::ScLookup()
     rEntry.bDoQuery = true;
     rEntry.eOp = SC_LESS_EQUAL;
     rEntry.nField = nCol1;
-    if ( rEntry.bQueryByString )
-        aParam.bRegExp = MayBeRegExp(rEntry.GetQueryString(), pDok);
+    ScQueryEntry::Item& rItem = rEntry.GetQueryItem();
+    if (rItem.meType == ScQueryEntry::ByString)
+        aParam.bRegExp = MayBeRegExp(rItem.maString, pDok);
 
     ScQueryCellIterator aCellIter(pDok, nTab1, aParam, false);
     SCCOL nC;
@@ -6024,18 +6034,20 @@ void ScInterpreter::CalculateLookup(bool HLookup)
                 rEntry.eOp = SC_LESS_EQUAL;
             if ( !FillEntry(rEntry) )
                 return;
-            if ( rEntry.bQueryByString )
-                rParam.bRegExp = MayBeRegExp(rEntry.GetQueryString(), pDok);
+
+            ScQueryEntry::Item& rItem = rEntry.GetQueryItem();
+            if (rItem.meType == ScQueryEntry::ByString)
+                rParam.bRegExp = MayBeRegExp(rItem.maString, pDok);
             if (pMat)
             {
                 SCSIZE nMatCount = HLookup ? nC : nR;
                 SCSIZE nDelta = SCSIZE_MAX;
-                if (rEntry.bQueryByString)
+                if (rItem.meType == ScQueryEntry::ByString)
                 {
         //!!!!!!!
         //! TODO: enable regex on matrix strings
         //!!!!!!!
-                    rtl::OUString aParamStr = rEntry.GetQueryString();
+                    const rtl::OUString& rParamStr = rItem.maString;
                     if ( bSorted )
                     {
                         static CollatorWrapper* pCollator = ScGlobal::GetCollator();
@@ -6044,7 +6056,7 @@ void ScInterpreter::CalculateLookup(bool HLookup)
                             if (HLookup ? pMat->IsString(i, 0) : pMat->IsString(0, i))
                             {
                                 sal_Int32 nRes =
-                                    pCollator->compareString( HLookup ? pMat->GetString(i,0) : pMat->GetString(0,i), aParamStr);
+                                    pCollator->compareString( HLookup ? pMat->GetString(i,0) : pMat->GetString(0,i), rParamStr);
                                 if (nRes <= 0)
                                     nDelta = i;
                                 else if (i>0)   // #i2168# ignore first mismatch
@@ -6061,7 +6073,7 @@ void ScInterpreter::CalculateLookup(bool HLookup)
                             if (HLookup ? pMat->IsString(i, 0) : pMat->IsString(0, i))
                             {
                                 if ( ScGlobal::GetpTransliteration()->isEqual(
-                                    HLookup ? pMat->GetString(i,0) : pMat->GetString(0,i), aParamStr ) )
+                                    HLookup ? pMat->GetString(i,0) : pMat->GetString(0,i), rParamStr))
                                 {
                                     nDelta = i;
                                     i = nMatCount + 1;
@@ -6079,7 +6091,7 @@ void ScInterpreter::CalculateLookup(bool HLookup)
                         {
                             if (!(HLookup ? pMat->IsString(i, 0) : pMat->IsString(0, i)))
                             {
-                                if ((HLookup ? pMat->GetDouble(i,0) : pMat->GetDouble(0,i)) <= rEntry.nVal)
+                                if ((HLookup ? pMat->GetDouble(i,0) : pMat->GetDouble(0,i)) <= rItem.mfVal)
                                     nDelta = i;
                                 else
                                     i = nMatCount+1;
@@ -6092,7 +6104,7 @@ void ScInterpreter::CalculateLookup(bool HLookup)
                         {
                             if (!(HLookup ? pMat->IsString(i, 0) : pMat->IsString(0, i)))
                             {
-                                if ((HLookup ? pMat->GetDouble(i,0) : pMat->GetDouble(0,i)) == rEntry.nVal)
+                                if ((HLookup ? pMat->GetDouble(i,0) : pMat->GetDouble(0,i)) == rItem.mfVal)
                                 {
                                     nDelta = i;
                                     i = nMatCount + 1;
@@ -6167,19 +6179,20 @@ void ScInterpreter::CalculateLookup(bool HLookup)
 bool ScInterpreter::FillEntry(ScQueryEntry& rEntry)
 {
     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::FillEntry" );
+    ScQueryEntry::Item& rItem = rEntry.GetQueryItem();
     switch ( GetStackType() )
     {
         case svDouble:
         {
-            rEntry.bQueryByString = false;
-            rEntry.nVal = GetDouble();
+            rItem.meType = ScQueryEntry::ByValue;
+            rItem.mfVal = GetDouble();
         }
         break;
         case svString:
         {
             const String& sStr = GetString();
-            rEntry.bQueryByString = true;
-            rEntry.SetQueryString(sStr);
+            rItem.meType = ScQueryEntry::ByString;
+            rItem.maString = sStr;
         }
         break;
         case svDoubleRef :
@@ -6194,22 +6207,22 @@ bool ScInterpreter::FillEntry(ScQueryEntry& rEntry)
             ScBaseCell* pCell = GetCell( aAdr );
             if (HasCellValueData(pCell))
             {
-                rEntry.bQueryByString = false;
-                rEntry.nVal = GetCellValue( aAdr, pCell );
+                rItem.meType = ScQueryEntry::ByValue;
+                rItem.mfVal = GetCellValue(aAdr, pCell);
             }
             else
             {
                 if ( GetCellType( pCell ) == CELLTYPE_NOTE )
                 {
-                    rEntry.bQueryByString = false;
-                    rEntry.nVal = 0.0;
+                    rItem.meType = ScQueryEntry::ByValue;
+                    rItem.mfVal = 0.0;
                 }
                 else
                 {
                     String sStr;
                     GetCellString(sStr, pCell);
-                    rEntry.bQueryByString = true;
-                    rEntry.SetQueryString(sStr);
+                    rItem.meType = ScQueryEntry::ByString;
+                    rItem.maString = sStr;
                 }
             }
         }
@@ -6217,9 +6230,10 @@ bool ScInterpreter::FillEntry(ScQueryEntry& rEntry)
         case svMatrix :
         {
             String aStr;
-            const ScMatValType nType = GetDoubleOrStringFromMatrix(rEntry.nVal, aStr);
-            rEntry.SetQueryString(aStr);
-            rEntry.bQueryByString = ScMatrix::IsNonValueType( nType);
+            const ScMatValType nType = GetDoubleOrStringFromMatrix(rItem.mfVal, aStr);
+            rItem.maString = aStr;
+            rItem.meType = ScMatrix::IsNonValueType(nType) ?
+                ScQueryEntry::ByString : ScQueryEntry::ByValue;
         }
         break;
         default:
@@ -6399,17 +6413,18 @@ ScDBQueryParamBase* ScInterpreter::GetDBParams( bool& rMissingField )
             for ( SCSIZE i=0; i < nCount; i++ )
             {
                 ScQueryEntry& rEntry = pParam->GetEntry(i);
-                if ( rEntry.bDoQuery )
-                {
-                    sal_uInt32 nIndex = 0;
-                    rtl::OUString aQueryStr = rEntry.GetQueryString();
-                    rEntry.bQueryByString = !pFormatter->IsNumberFormat(
-                        aQueryStr, nIndex, rEntry.nVal );
-                    if ( rEntry.bQueryByString && !pParam->bRegExp )
-                        pParam->bRegExp = MayBeRegExp(aQueryStr, pDok);
-                }
-                else
-                    break;  // for
+                if (!rEntry.bDoQuery)
+                    break;
+
+                ScQueryEntry::Item& rItem = rEntry.GetQueryItem();
+                sal_uInt32 nIndex = 0;
+                const rtl::OUString& rQueryStr = rItem.maString;
+                bool bNumber = pFormatter->IsNumberFormat(
+                    rQueryStr, nIndex, rItem.mfVal);
+                rItem.meType = bNumber ? ScQueryEntry::ByValue : ScQueryEntry::ByString;
+
+                if (!bNumber && !pParam->bRegExp)
+                    pParam->bRegExp = MayBeRegExp(rQueryStr, pDok);
             }
             return pParam.release();
         }
diff --git a/sc/source/core/tool/lookupcache.cxx b/sc/source/core/tool/lookupcache.cxx
index 3c82a2a..eaff616 100644
--- a/sc/source/core/tool/lookupcache.cxx
+++ b/sc/source/core/tool/lookupcache.cxx
@@ -51,10 +51,12 @@ ScLookupCache::QueryCriteria::QueryCriteria( const ScQueryEntry& rEntry ) :
             meOp = UNKNOWN;
             DBG_ERRORFILE( "ScLookupCache::QueryCriteria not prepared for this ScQueryOp");
     }
-    if (rEntry.bQueryByString)
-        setString(rEntry.GetQueryString());
+
+    const ScQueryEntry::Item& rItem = rEntry.GetQueryItem();
+    if (rItem.meType == ScQueryEntry::ByString)
+        setString(rItem.maString);
     else
-        setDouble( rEntry.nVal);
+        setDouble(rItem.mfVal);
 }
 
 ScLookupCache::QueryCriteria::QueryCriteria( const ScLookupCache::QueryCriteria & r ) :
diff --git a/sc/source/core/tool/queryentry.cxx b/sc/source/core/tool/queryentry.cxx
index 641bcd0..0aba519 100644
--- a/sc/source/core/tool/queryentry.cxx
+++ b/sc/source/core/tool/queryentry.cxx
@@ -32,30 +32,33 @@
 #include <unotools/transliterationwrapper.hxx>
 #include <unotools/collatorwrapper.hxx>
 
+ScQueryEntry::Item::Item() :
+    meType(ByValue), mfVal(0.0) {}
+
+bool ScQueryEntry::Item::operator== (const Item& r) const
+{
+    return meType == r.meType && mfVal == r.mfVal && maString.equals(r.maString);
+}
+
 ScQueryEntry::ScQueryEntry() :
     bDoQuery(false),
-    bQueryByString(false),
-    bQueryByDate(false),
     nField(0),
     eOp(SC_EQUAL),
     eConnect(SC_AND),
-    nVal(0.0),
     pSearchParam(NULL),
-    pSearchText(NULL)
+    pSearchText(NULL),
+    maQueryItems(1)
 {
 }
 
 ScQueryEntry::ScQueryEntry(const ScQueryEntry& r) :
     bDoQuery(r.bDoQuery),
-    bQueryByString(r.bQueryByString),
-    bQueryByDate(r.bQueryByDate),
     nField(r.nField),
     eOp(r.eOp),
     eConnect(r.eConnect),
-    nVal(r.nVal),
     pSearchParam(NULL),
     pSearchText(NULL),
-    maQueryStrings(r.maQueryStrings)
+    maQueryItems(r.maQueryItems)
 {
 }
 
@@ -68,13 +71,10 @@ ScQueryEntry::~ScQueryEntry()
 ScQueryEntry& ScQueryEntry::operator=( const ScQueryEntry& r )
 {
     bDoQuery        = r.bDoQuery;
-    bQueryByString  = r.bQueryByString;
-    bQueryByDate    = r.bQueryByDate;
     eOp             = r.eOp;
     eConnect        = r.eConnect;
     nField          = r.nField;
-    nVal            = r.nVal;
-    maQueryStrings  = r.maQueryStrings;
+    maQueryItems  = r.maQueryItems;
 
     delete pSearchParam;
     delete pSearchText;
@@ -84,9 +84,20 @@ ScQueryEntry& ScQueryEntry::operator=( const ScQueryEntry& r )
     return *this;
 }
 
-bool ScQueryEntry::IsQueryStringEmpty() const
+const ScQueryEntry::Item& ScQueryEntry::GetQueryItem() const
 {
-    return maQueryStrings.empty();
+    if (maQueryItems.size() > 1)
+        // Reset to a single query mode.
+        maQueryItems.resize(1);
+    return maQueryItems[0];
+}
+
+ScQueryEntry::Item& ScQueryEntry::GetQueryItem()
+{
+    if (maQueryItems.size() > 1)
+        // Reset to a single query mode.
+        maQueryItems.resize(1);
+    return maQueryItems[0];
 }
 
 namespace {
@@ -108,47 +119,14 @@ public:
 
 }
 
-bool ScQueryEntry::MatchByString(const rtl::OUString& rStr, bool bCaseSens) const
-{
-    QueryStringsType::const_iterator itr =
-        std::lower_bound(
-            maQueryStrings.begin(), maQueryStrings.end(), rStr, CompareString(bCaseSens));
-
-    if (itr == maQueryStrings.end())
-        return false;
-
-    utl::TransliterationWrapper* pTransliteration =
-        bCaseSens ? ScGlobal::GetCaseTransliteration() : ScGlobal::GetpTransliteration();
-    return pTransliteration->isEqual(rStr, *itr);
-}
-
-void ScQueryEntry::SortQueryStrings(bool bCaseSens)
-{
-    std::sort(maQueryStrings.begin(), maQueryStrings.end(), CompareString(bCaseSens));
-}
-
-void ScQueryEntry::SetQueryString(const rtl::OUString& rStr)
-{
-    maQueryStrings.clear();
-    if (!rStr.isEmpty())
-        maQueryStrings.push_back(rStr);
-}
-
-rtl::OUString ScQueryEntry::GetQueryString() const
-{
-    return maQueryStrings.empty() ? rtl::OUString() : maQueryStrings[0];
-}
-
 void ScQueryEntry::Clear()
 {
     bDoQuery        = false;
-    bQueryByString  = false;
-    bQueryByDate    = false;
     eOp             = SC_EQUAL;
     eConnect        = SC_AND;
     nField          = 0;
-    nVal            = 0.0;
-    maQueryStrings.clear();
+    maQueryItems.clear();
+    maQueryItems.push_back(Item());
 
     delete pSearchParam;
     delete pSearchText;
@@ -159,13 +137,10 @@ void ScQueryEntry::Clear()
 bool ScQueryEntry::operator==( const ScQueryEntry& r ) const
 {
     return bDoQuery         == r.bDoQuery
-        && bQueryByString   == r.bQueryByString
-        && bQueryByDate     == r.bQueryByDate
         && eOp              == r.eOp
         && eConnect         == r.eConnect
         && nField           == r.nField
-        && nVal             == r.nVal
-        && maQueryStrings   == r.maQueryStrings;
+        && maQueryItems   == r.maQueryItems;
     //! pSearchParam und pSearchText nicht vergleichen
 }
 
@@ -173,11 +148,9 @@ utl::TextSearch* ScQueryEntry::GetSearchTextPtr( bool bCaseSens ) const
 {
     if ( !pSearchParam )
     {
-        rtl::OUString aStr;
-        if (!maQueryStrings.empty())
-            aStr = maQueryStrings[0];
+        const rtl::OUString& rStr = maQueryItems[0].maString;
         pSearchParam = new utl::SearchParam(
-            aStr, utl::SearchParam::SRCH_REGEXP, bCaseSens, false, false);
+            rStr, utl::SearchParam::SRCH_REGEXP, bCaseSens, false, false);
         pSearchText = new utl::TextSearch( *pSearchParam, *ScGlobal::pCharClass );
     }
     return pSearchText;
diff --git a/sc/source/core/tool/queryparam.cxx b/sc/source/core/tool/queryparam.cxx
index b6cf41b..2f10046 100644
--- a/sc/source/core/tool/queryparam.cxx
+++ b/sc/source/core/tool/queryparam.cxx
@@ -119,6 +119,7 @@ void ScQueryParamBase::FillInExcelSyntax(const rtl::OUString& rStr, SCSIZE nInde
             Resize( nIndex+1 );
 
         ScQueryEntry& rEntry = GetEntry(nIndex);
+        ScQueryEntry::Item& rItem = rEntry.GetQueryItem();
 
         rEntry.bDoQuery = sal_True;
         // Operatoren herausfiltern
@@ -126,17 +127,17 @@ void ScQueryParamBase::FillInExcelSyntax(const rtl::OUString& rStr, SCSIZE nInde
         {
             if (aCellStr.GetChar(1) == '>')
             {
-                rEntry.SetQueryString(aCellStr.Copy(2));
+                rItem.maString = aCellStr.Copy(2);
                 rEntry.eOp   = SC_NOT_EQUAL;
             }
             else if (aCellStr.GetChar(1) == '=')
             {
-                rEntry.SetQueryString(aCellStr.Copy(2));
+                rItem.maString = aCellStr.Copy(2);
                 rEntry.eOp   = SC_LESS_EQUAL;
             }
             else
             {
-                rEntry.SetQueryString(aCellStr.Copy(1));
+                rItem.maString = aCellStr.Copy(1);
                 rEntry.eOp   = SC_LESS;
             }
         }
@@ -144,21 +145,21 @@ void ScQueryParamBase::FillInExcelSyntax(const rtl::OUString& rStr, SCSIZE nInde
         {
             if (aCellStr.GetChar(1) == '=')
             {
-                rEntry.SetQueryString(aCellStr.Copy(2));
+                rItem.maString = aCellStr.Copy(2);
                 rEntry.eOp   = SC_GREATER_EQUAL;
             }
             else
             {
-                rEntry.SetQueryString(aCellStr.Copy(1));
+                rItem.maString = aCellStr.Copy(1);
                 rEntry.eOp   = SC_GREATER;
             }
         }
         else
         {
             if (aCellStr.GetChar(0) == '=')
-                rEntry.SetQueryString(aCellStr.Copy(1));
+                rItem.maString = aCellStr.Copy(1);
             else
-                rEntry.SetQueryString(aCellStr);
+                rItem.maString = aCellStr;
             rEntry.eOp = SC_EQUAL;
         }
     }
diff --git a/sc/source/filter/excel/excimp8.cxx b/sc/source/filter/excel/excimp8.cxx
index 9d26eda..c1a012a 100644
--- a/sc/source/filter/excel/excimp8.cxx
+++ b/sc/source/filter/excel/excimp8.cxx
@@ -544,7 +544,7 @@ static void ExcelQueryToOooQuery( ScQueryEntry& rEntry )
     if (rEntry.eOp != SC_EQUAL && rEntry.eOp != SC_NOT_EQUAL)
         return;
 
-    String aStr = rEntry.GetQueryString();
+    String aStr = rEntry.GetQueryItem().maString;
     xub_StrLen nLen = aStr.Len();
     sal_Unicode nStart = aStr.GetChar( 0 );
     sal_Unicode nEnd   = aStr.GetChar( nLen-1 );
@@ -568,7 +568,7 @@ static void ExcelQueryToOooQuery( ScQueryEntry& rEntry )
     {
         aStr.Erase( 0, 1 );
     }
-    rEntry.SetQueryString(aStr);
+    rEntry.GetQueryItem().maString = aStr;
 }
 
 void XclImpAutoFilterData::ReadAutoFilter( XclImpStream& rStrm )
@@ -588,13 +588,15 @@ void XclImpAutoFilterData::ReadAutoFilter( XclImpStream& rStrm )
         if( nFirstEmpty < nCount )
         {
             ScQueryEntry& aEntry = aParam.GetEntry( nFirstEmpty );
-            aEntry.bDoQuery = sal_True;
-            aEntry.bQueryByString = sal_True;
+            ScQueryEntry::Item& rItem = aEntry.GetQueryItem();
+            aEntry.bDoQuery = true;
             aEntry.nField = static_cast<SCCOLROW>(StartCol() + static_cast<SCCOL>(nCol));
             aEntry.eOp = bTopOfTop10 ?
                 (bPercent ? SC_TOPPERC : SC_TOPVAL) : (bPercent ? SC_BOTPERC : SC_BOTVAL);
             aEntry.eConnect = SC_AND;
-            aEntry.SetQueryString(rtl::OUString::valueOf(static_cast<sal_Int32>(nCntOfTop10)));
+
+            rItem.meType = ScQueryEntry::ByString;
+            rItem.maString = rtl::OUString::valueOf(static_cast<sal_Int32>(nCntOfTop10));
 
             rStrm.Ignore( 20 );
             nFirstEmpty++;
@@ -605,7 +607,7 @@ void XclImpAutoFilterData::ReadAutoFilter( XclImpStream& rStrm )
         sal_uInt8   nE, nType, nOper, nBoolErr, nVal;
         sal_Int32   nRK;
         double  fVal;
-        sal_Bool    bIgnore;
+        bool bIgnore;
 
         sal_uInt8   nStrLen[ 2 ]    = { 0, 0 };
         ScQueryEntry *pQueryEntries[ 2 ] = { NULL, NULL };
@@ -615,6 +617,7 @@ void XclImpAutoFilterData::ReadAutoFilter( XclImpStream& rStrm )
             if( nFirstEmpty < nCount )
             {
                 ScQueryEntry& aEntry = aParam.GetEntry( nFirstEmpty );
+                ScQueryEntry::Item& rItem = aEntry.GetQueryItem();
                 pQueryEntries[ nE ] = &aEntry;
                 bIgnore = false;
 
@@ -650,36 +653,33 @@ void XclImpAutoFilterData::ReadAutoFilter( XclImpStream& rStrm )
                     case EXC_AFTYPE_RK:
                         rStrm >> nRK;
                         rStrm.Ignore( 4 );
-                        aStr = aEntry.GetQueryString();
-                        CreateFromDouble(aStr, XclTools::GetDoubleFromRK(nRK));
-                        aEntry.SetQueryString(aStr);
+                        CreateFromDouble(
+                            rItem.maString, XclTools::GetDoubleFromRK(nRK));
                     break;
                     case EXC_AFTYPE_DOUBLE:
                         rStrm >> fVal;
-                        aStr = aEntry.GetQueryString();
-                        CreateFromDouble(aStr, fVal);
-                        aEntry.SetQueryString(aStr);
+                        CreateFromDouble(rItem.maString, fVal);
                     break;
                     case EXC_AFTYPE_STRING:
                         rStrm.Ignore( 4 );
                         rStrm >> nStrLen[ nE ];
                         rStrm.Ignore( 3 );
-                        aEntry.SetQueryString(rtl::OUString());
+                        rItem.maString = rtl::OUString();
                     break;
                     case EXC_AFTYPE_BOOLERR:
                         rStrm >> nBoolErr >> nVal;
                         rStrm.Ignore( 6 );
-                        aEntry.SetQueryString(rtl::OUString::valueOf(static_cast<sal_Int32>(nVal)));
-                        bIgnore = (sal_Bool) nBoolErr;
+                        rItem.maString = rtl::OUString::valueOf(static_cast<sal_Int32>(nVal));
+                        bIgnore = (nBoolErr != 0);
                     break;
                     case EXC_AFTYPE_EMPTY:
-                        aEntry.bQueryByString = false;
-                        aEntry.nVal = SC_EMPTYFIELDS;
+                        rItem.meType = ScQueryEntry::ByValue;
+                        rItem.mfVal = SC_EMPTYFIELDS;
                         aEntry.eOp = SC_EQUAL;
                     break;
                     case EXC_AFTYPE_NOTEMPTY:
-                        aEntry.bQueryByString = false;
-                        aEntry.nVal = SC_NONEMPTYFIELDS;
+                        rItem.meType = ScQueryEntry::ByValue;
+                        rItem.mfVal = SC_NONEMPTYFIELDS;
                         aEntry.eOp = SC_EQUAL;
                     break;
                     default:
@@ -697,8 +697,8 @@ void XclImpAutoFilterData::ReadAutoFilter( XclImpStream& rStrm )
                     bHasConflict = sal_True;
                 if( !bHasConflict && !bIgnore )
                 {
-                    aEntry.bDoQuery = sal_True;
-                    aEntry.bQueryByString = sal_True;
+                    aEntry.bDoQuery = true;
+                    rItem.meType = ScQueryEntry::ByString;
                     aEntry.nField = static_cast<SCCOLROW>(StartCol() + static_cast<SCCOL>(nCol));
                     aEntry.eConnect = nE ? eConn : SC_AND;
                     nFirstEmpty++;
@@ -711,7 +711,7 @@ void XclImpAutoFilterData::ReadAutoFilter( XclImpStream& rStrm )
         for( nE = 0; nE < 2; nE++ )
             if( nStrLen[ nE ] && pQueryEntries[ nE ] )
             {
-                pQueryEntries[nE]->SetQueryString(rStrm.ReadUniString(nStrLen[nE]));
+                pQueryEntries[nE]->GetQueryItem().maString = rStrm.ReadUniString(nStrLen[nE]);
                 ExcelQueryToOooQuery( *pQueryEntries[ nE ] );
             }
 
diff --git a/sc/source/filter/excel/excrecds.cxx b/sc/source/filter/excel/excrecds.cxx
index 669d851..2a59124 100644
--- a/sc/source/filter/excel/excrecds.cxx
+++ b/sc/source/filter/excel/excrecds.cxx
@@ -682,10 +682,11 @@ bool XclExpAutofilter::AddEntry( const ScQueryEntry& rEntry )
 {
     bool bConflict = false;
     String  sText;
-    rtl::OUString aQueryStr = rEntry.GetQueryString();
-    if (!aQueryStr.isEmpty())
+    const ScQueryEntry::Item& rItem = rEntry.GetQueryItem();
+    const rtl::OUString& rQueryStr = rItem.maString;
+    if (!rQueryStr.isEmpty())
     {
-        sText.Assign(aQueryStr);
+        sText.Assign(rQueryStr);
         switch( rEntry.eOp )
         {
             case SC_CONTAINS:
@@ -713,9 +714,9 @@ bool XclExpAutofilter::AddEntry( const ScQueryEntry& rEntry )
     bool bLen = sText.Len() > 0;
 
     // empty/nonempty fields
-    if( !bLen && (rEntry.nVal == SC_EMPTYFIELDS) )
+    if( !bLen && (rItem.mfVal == SC_EMPTYFIELDS) )
         bConflict = !AddCondition( rEntry.eConnect, EXC_AFTYPE_EMPTY, EXC_AFOPER_NONE, 0.0, NULL, true );
-    else if( !bLen && (rEntry.nVal == SC_NONEMPTYFIELDS) )
+    else if( !bLen && (rItem.mfVal == SC_NONEMPTYFIELDS) )
         bConflict = !AddCondition( rEntry.eConnect, EXC_AFTYPE_NOTEMPTY, EXC_AFOPER_NONE, 0.0, NULL, true );
     // other conditions
     else
diff --git a/sc/source/filter/xml/XMLExportDataPilot.cxx b/sc/source/filter/xml/XMLExportDataPilot.cxx
index 39a2896..83a6d76 100644
--- a/sc/source/filter/xml/XMLExportDataPilot.cxx
+++ b/sc/source/filter/xml/XMLExportDataPilot.cxx
@@ -135,19 +135,20 @@ void ScXMLExportDataPilot::WriteDPCondition(const ScQueryEntry& aQueryEntry, boo
     rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_FIELD_NUMBER, rtl::OUString::valueOf(sal_Int32(aQueryEntry.nField)));
     if (bIsCaseSensitive)
         rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_CASE_SENSITIVE, XML_TRUE);
-    rtl::OUString aQueryStr = aQueryEntry.GetQueryString();
-    if (aQueryEntry.bQueryByString)
+    const ScQueryEntry::Item& rItem = aQueryEntry.GetQueryItem();
+    const rtl::OUString& rQueryStr = rItem.maString;
+    if (rItem.meType == ScQueryEntry::ByString)
     {
-        rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_VALUE, aQueryStr);
+        rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_VALUE, rQueryStr);
     }
     else
     {
         rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DATA_TYPE, XML_NUMBER);
-        rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_VALUE, aQueryStr);
+        rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_VALUE, rQueryStr);
     }
     rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_OPERATOR,
                          getDPOperatorXML(aQueryEntry.eOp, bUseRegularExpressions,
-                                          aQueryEntry.bQueryByString, aQueryEntry.nVal, aQueryStr));
+                                          rItem.meType == ScQueryEntry::ByString, rItem.mfVal, rQueryStr));
     SvXMLElementExport aElemC(rExport, XML_NAMESPACE_TABLE, XML_FILTER_CONDITION, true, true);
 }
 
diff --git a/sc/source/filter/xml/XMLExportDatabaseRanges.cxx b/sc/source/filter/xml/XMLExportDatabaseRanges.cxx
index c00d1bb..8ec3c44 100644
--- a/sc/source/filter/xml/XMLExportDatabaseRanges.cxx
+++ b/sc/source/filter/xml/XMLExportDatabaseRanges.cxx
@@ -406,17 +406,20 @@ private:
             case SC_ENDS_WITH:
                 return GetXMLToken(XML_ENDS_WITH);
             case SC_EQUAL:
-                if (!rEntry.bQueryByString && rEntry.GetQueryString().isEmpty())
+            {
+                const ScQueryEntry::Item& rItem = rEntry.GetQueryItem();
+                if (!rItem.meType != ScQueryEntry::ByString && rItem.maString.isEmpty())
                 {
-                    if (rEntry.nVal == SC_EMPTYFIELDS)
+                    if (rItem.mfVal == SC_EMPTYFIELDS)
                         return GetXMLToken(XML_EMPTY);
-                    else if (rEntry.nVal == SC_NONEMPTYFIELDS)
+                    else if (rItem.mfVal == SC_NONEMPTYFIELDS)
                         return GetXMLToken(XML_NOEMPTY);
                 }
                 if (bRegExp)
                     return GetXMLToken(XML_MATCH);
                 else
                     return OUString(RTL_CONSTASCII_USTRINGPARAM("="));
+            }
             case SC_GREATER:
                 return rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(">"));
             case SC_GREATER_EQUAL:
@@ -442,16 +445,17 @@ private:
 
     void writeCondition(const ScQueryEntry& rEntry, SCCOLROW nFieldStart, bool bCaseSens, bool bRegExp)
     {
+        const ScQueryEntry::Item& rItem = rEntry.GetQueryItem();
         mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_FIELD_NUMBER, OUString::valueOf(rEntry.nField - nFieldStart));
         if (bCaseSens)
             mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_CASE_SENSITIVE, XML_TRUE);
-        if (rEntry.bQueryByString)
-            mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_VALUE, rEntry.GetQueryString());
+        if (rItem.meType == ScQueryEntry::ByString)
+            mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_VALUE, rItem.maString);
         else
         {
             mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DATA_TYPE, XML_NUMBER);
             OUStringBuffer aBuf;
-            ::sax::Converter::convertDouble(aBuf, rEntry.nVal);
+            ::sax::Converter::convertDouble(aBuf, rItem.mfVal);
             mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_VALUE, aBuf.makeStringAndClear());
         }
 
diff --git a/sc/source/filter/xml/xmlfilti.cxx b/sc/source/filter/xml/xmlfilti.cxx
index 72df5ef..0b7f37a 100644
--- a/sc/source/filter/xml/xmlfilti.cxx
+++ b/sc/source/filter/xml/xmlfilti.cxx
@@ -763,22 +763,23 @@ void ScXMLDPConditionContext::EndElement()
     getOperatorXML(sOperator, aFilterField.eOp, bUseRegularExpressions, dVal);
     pFilterContext->SetUseRegularExpressions(bUseRegularExpressions);
     aFilterField.nField = nField;
+    ScQueryEntry::Item& rItem = aFilterField.GetQueryItem();
     if (IsXMLToken(sDataType, XML_NUMBER))
     {
-        aFilterField.nVal = sConditionValue.toDouble();
-        aFilterField.SetQueryString(sConditionValue);
-        aFilterField.bQueryByString = false;
+        rItem.mfVal = sConditionValue.toDouble();
+        rItem.maString = sConditionValue;
+        rItem.meType = ScQueryEntry::ByValue;
         if (dVal != 0.0)
         {
-            aFilterField.nVal = dVal;
-            aFilterField.SetQueryString(rtl::OUString());
+            rItem.mfVal = dVal;
+            rItem.maString = rtl::OUString();
         }
     }
     else
     {
-        aFilterField.SetQueryString(sConditionValue);
-        aFilterField.bQueryByString = true;
-        aFilterField.nVal = 0;
+        rItem.maString = sConditionValue;
+        rItem.meType = ScQueryEntry::ByString;
+        rItem.mfVal = 0.0;
     }
     pFilterContext->AddFilterField(aFilterField);
 }
diff --git a/sc/source/ui/dbgui/filtdlg.cxx b/sc/source/ui/dbgui/filtdlg.cxx
index db730ab..0dccddd 100644
--- a/sc/source/ui/dbgui/filtdlg.cxx
+++ b/sc/source/ui/dbgui/filtdlg.cxx
@@ -310,21 +310,22 @@ void ScFilterDlg::Init( const SfxItemSet& rArgSet )
         ScQueryEntry& rEntry = theQueryData.GetEntry(i);
         if ( rEntry.bDoQuery )
         {
+            const ScQueryEntry::Item& rItem = rEntry.GetQueryItem();
             nCondPos     = (sal_uInt16)rEntry.eOp;
             nFieldSelPos = GetFieldSelPos( static_cast<SCCOL>(rEntry.nField) );
-            bool bEmptyString = rEntry.GetQueryString().isEmpty();
-            if (rEntry.nVal == SC_EMPTYFIELDS && !rEntry.bQueryByString && bEmptyString)
+            bool bEmptyString = rItem.maString.isEmpty();
+            if (rItem.mfVal == SC_EMPTYFIELDS && rItem.meType != ScQueryEntry::ByString && bEmptyString)
             {
                 aValStr = aStrEmpty;
                 aCondLbArr[i]->Disable();
             }
-            else if (rEntry.nVal == SC_NONEMPTYFIELDS && !rEntry.bQueryByString && bEmptyString)
+            else if (rItem.mfVal == SC_NONEMPTYFIELDS && rItem.meType != ScQueryEntry::ByString && bEmptyString)
             {
                 aValStr = aStrNotEmpty;
                 aCondLbArr[i]->Disable();
             }
             else
-                aValStr = rEntry.GetQueryString();
+                aValStr = rItem.maString;
         }
         else if ( i == 0 )
         {
@@ -1140,6 +1141,7 @@ IMPL_LINK( ScFilterDlg, ValModifyHdl, ComboBox*, pEd )
             maRefreshExceptQuery.resize(nQE + 1, false);
 
         ScQueryEntry& rEntry = theQueryData.GetEntry( nQE );
+        ScQueryEntry::Item& rItem = rEntry.GetQueryItem();
         bool bDoThis = (pLbField->GetSelectEntryPos() != 0);
         rEntry.bDoQuery = bDoThis;
 
@@ -1147,21 +1149,21 @@ IMPL_LINK( ScFilterDlg, ValModifyHdl, ComboBox*, pEd )
         {
             if ( aStrEmpty.equals(aStrVal) )
             {
-                rEntry.SetQueryString(rtl::OUString());
-                rEntry.nVal = SC_EMPTYFIELDS;
-                rEntry.bQueryByString = false;
+                rItem.maString = rtl::OUString();
+                rItem.mfVal = SC_EMPTYFIELDS;
+                rItem.meType = ScQueryEntry::ByValue;
             }
             else if ( aStrNotEmpty.equals(aStrVal) )
             {
-                rEntry.SetQueryString(rtl::OUString());
-                rEntry.nVal = SC_NONEMPTYFIELDS;
-                rEntry.bQueryByString = false;
+                rItem.maString = rtl::OUString();
+                rItem.mfVal = SC_NONEMPTYFIELDS;
+                rItem.meType = ScQueryEntry::ByValue;
             }
             else
             {
-                rEntry.SetQueryString(aStrVal);
-                rEntry.nVal           = 0;
-                rEntry.bQueryByString = true;
+                rItem.maString = aStrVal;
+                rItem.mfVal = 0.0;
+                rItem.meType = ScQueryEntry::ByString;
             }
 
             sal_uInt16  nField  = pLbField->GetSelectEntryPos();
@@ -1170,8 +1172,8 @@ IMPL_LINK( ScFilterDlg, ValModifyHdl, ComboBox*, pEd )
 
             ScQueryOp eOp  = (ScQueryOp)pLbCond->GetSelectEntryPos();
             rEntry.eOp     = eOp;
-            rEntry.bQueryByDate = maHasDates[nQE];
-
+            if (maHasDates[nQE])
+                rItem.meType = ScQueryEntry::ByDate;
         }
     }
     return 0;
@@ -1219,20 +1221,21 @@ void ScFilterDlg::RefreshEditRow( size_t nOffset )
             if(rEntry.bDoQuery)
                nFieldSelPos = GetFieldSelPos( static_cast<SCCOL>(rEntry.nField) );
 
-            rtl::OUString aQueryStr = rEntry.GetQueryString();
-            if ( rEntry.nVal == SC_EMPTYFIELDS && !rEntry.bQueryByString && aQueryStr.isEmpty())
+            const ScQueryEntry::Item& rItem = rEntry.GetQueryItem();
+            const rtl::OUString& rQueryStr = rItem.maString;
+            if (rItem.mfVal == SC_EMPTYFIELDS && rItem.meType != ScQueryEntry::ByString && rQueryStr.isEmpty())
             {
                 aValStr = aStrEmpty;
                 aCondLbArr[i]->Disable();
             }
-            else if ( rEntry.nVal == SC_NONEMPTYFIELDS && !rEntry.bQueryByString && aQueryStr.isEmpty())
+            else if (rItem.mfVal == SC_NONEMPTYFIELDS && rItem.meType != ScQueryEntry::ByString && rQueryStr.isEmpty())
             {
                 aValStr = aStrNotEmpty;
                 aCondLbArr[i]->Disable();
             }
             else
             {
-                aValStr = aQueryStr;
+                aValStr = rQueryStr;
                 aCondLbArr[i]->Enable();
             }
             aFieldLbArr[i]->Enable();
diff --git a/sc/source/ui/dbgui/pfiltdlg.cxx b/sc/source/ui/dbgui/pfiltdlg.cxx
index a1a25b7..593b696 100644
--- a/sc/source/ui/dbgui/pfiltdlg.cxx
+++ b/sc/source/ui/dbgui/pfiltdlg.cxx
@@ -215,13 +215,13 @@ void ScPivotFilterDlg::Init( const SfxItemSet& rArgSet )
         if ( theQueryData.GetEntry(i).bDoQuery )
         {
             const ScQueryEntry& rEntry = theQueryData.GetEntry(i);
-
-            rtl::OUString aValStr = rEntry.GetQueryString();
-            if (!rEntry.bQueryByString && aValStr.isEmpty())
+            const ScQueryEntry::Item& rItem = rEntry.GetQueryItem();
+            rtl::OUString aValStr = rItem.maString;
+            if (rItem.meType != ScQueryEntry::ByString && aValStr.isEmpty())
             {
-                if (rEntry.nVal == SC_EMPTYFIELDS)
+                if (rItem.mfVal == SC_EMPTYFIELDS)
                     aValStr = aStrEmpty;
-                else if (rEntry.nVal == SC_NONEMPTYFIELDS)
+                else if (rItem.mfVal == SC_NONEMPTYFIELDS)
                     aValStr = aStrNotEmpty;
             }
             sal_uInt16  nCondPos     = (sal_uInt16)rEntry.eOp;
@@ -417,6 +417,7 @@ const ScQueryItem& ScPivotFilterDlg::GetOutputItem()
         if ( bDoThis )
         {
             ScQueryEntry& rEntry = theParam.GetEntry(i);
+            ScQueryEntry::Item& rItem = rEntry.GetQueryItem();
 
             String aStrVal( aValueEdArr[i]->GetText() );
 
@@ -427,21 +428,21 @@ const ScQueryItem& ScPivotFilterDlg::GetOutputItem()
              */
             if ( aStrVal == aStrEmpty )
             {
-                rEntry.SetQueryString(rtl::OUString());
-                rEntry.nVal     = SC_EMPTYFIELDS;
-                rEntry.bQueryByString = false;
+                rItem.maString = rtl::OUString();
+                rItem.mfVal = SC_EMPTYFIELDS;
+                rItem.meType = ScQueryEntry::ByValue;
             }
             else if ( aStrVal == aStrNotEmpty )
             {
-                rEntry.SetQueryString(rtl::OUString());
-                rEntry.nVal     = SC_NONEMPTYFIELDS;
-                rEntry.bQueryByString = false;
+                rItem.maString = rtl::OUString();
+                rItem.mfVal = SC_NONEMPTYFIELDS;
+                rItem.meType = ScQueryEntry::ByValue;
             }
             else
             {
-                rEntry.SetQueryString(aStrVal);
-                rEntry.nVal     = 0;
-                rEntry.bQueryByString = sal_True;
+                rItem.maString = aStrVal;
+                rItem.mfVal = 0.0;
+                rItem.meType = ScQueryEntry::ByString;
             }
 
             rEntry.nField   = nField ? (theQueryData.nCol1 +
diff --git a/sc/source/ui/unoobj/cellsuno.cxx b/sc/source/ui/unoobj/cellsuno.cxx
index 618a8f5..e1a6cc7 100644
--- a/sc/source/ui/unoobj/cellsuno.cxx
+++ b/sc/source/ui/unoobj/cellsuno.cxx
@@ -5679,12 +5679,11 @@ void SAL_CALL ScCellRangeObj::filter( const uno::Reference<sheet::XSheetFilterDe
             {
                 rEntry.nField += nFieldStart;
                 //  Im Dialog wird immer der String angezeigt -> muss zum Wert passen
-                if ( !rEntry.bQueryByString )
+                ScQueryEntry::Item& rItem = rEntry.GetQueryItem();
+                if (rItem.meType != ScQueryEntry::ByString)
                 {
-                    rtl::OUString aStr;
                     pDocSh->GetDocument()->GetFormatTable()->
-                        GetInputLineString(rEntry.nVal, 0, aStr);
-                    rEntry.SetQueryString(aStr);
+                        GetInputLineString(rItem.mfVal, 0, rItem.maString);
                 }
             }
         }
diff --git a/sc/source/ui/unoobj/datauno.cxx b/sc/source/ui/unoobj/datauno.cxx
index 5e43474..0ea4eac 100644
--- a/sc/source/ui/unoobj/datauno.cxx
+++ b/sc/source/ui/unoobj/datauno.cxx
@@ -1074,20 +1074,17 @@ void ScFilterDescriptorBase::fillQueryParam(
     for (i=0; i<nCount; i++)
     {
         ScQueryEntry& rEntry = rParam.GetEntry(i);
+        ScQueryEntry::Item& rItem = rEntry.GetQueryItem();
 
-        rEntry.bDoQuery         = sal_True;
-        rEntry.eConnect         = (pAry[i].Connection == sheet::FilterConnection_AND) ? SC_AND : SC_OR;
-        rEntry.nField           = pAry[i].Field;
-        rEntry.bQueryByString   = !pAry[i].IsNumeric;
-        rEntry.nVal             = pAry[i].NumericValue;
-        rEntry.SetQueryString(pAry[i].StringValue);
+        rEntry.bDoQuery = true;
+        rEntry.eConnect = (pAry[i].Connection == sheet::FilterConnection_AND) ? SC_AND : SC_OR;
+        rEntry.nField   = pAry[i].Field;
+        rItem.meType    = pAry[i].IsNumeric ? ScQueryEntry::ByValue : ScQueryEntry::ByString;
+        rItem.mfVal     = pAry[i].NumericValue;
+        rItem.maString  = pAry[i].StringValue;
 
-        if (!rEntry.bQueryByString && pDoc)
-        {
-            rtl::OUString aStr;
-            pDoc->GetFormatTable()->GetInputLineString(rEntry.nVal, 0, aStr);
-            rEntry.SetQueryString(aStr);
-        }
+        if (rItem.meType == ScQueryEntry::ByValue && pDoc)
+            pDoc->GetFormatTable()->GetInputLineString(rItem.mfVal, 0, rItem.maString);
 
         switch (pAry[i].Operator)           // FilterOperator
         {
@@ -1110,17 +1107,17 @@ void ScFilterDescriptorBase::fillQueryParam(
         case sheet::FilterOperator2::EMPTY:
             {
                 rEntry.eOp = SC_EQUAL;
-                rEntry.nVal = SC_EMPTYFIELDS;
-                rEntry.bQueryByString = false;
-                rEntry.SetQueryString(rtl::OUString());
+                rItem.mfVal = SC_EMPTYFIELDS;
+                rItem.meType = ScQueryEntry::ByValue;
+                rItem.maString = rtl::OUString();
             }
             break;
         case sheet::FilterOperator2::NOT_EMPTY:
             {
                 rEntry.eOp = SC_EQUAL;
-                rEntry.nVal = SC_NONEMPTYFIELDS;
-                rEntry.bQueryByString = false;
-                rEntry.SetQueryString(rtl::OUString());
+                rItem.mfVal = SC_NONEMPTYFIELDS;
+                rItem.meType = ScQueryEntry::ByValue;
+                rItem.maString = rtl::OUString();
             }
             break;
         default:
@@ -1181,29 +1178,28 @@ uno::Sequence<sheet::TableFilterField> SAL_CALL ScFilterDescriptorBase::getFilte
     for (SCSIZE i=0; i<nCount; i++)
     {
         const ScQueryEntry& rEntry = aParam.GetEntry(i);
-
-        rtl::OUString aStringValue = rEntry.GetQueryString();
+        const ScQueryEntry::Item& rItem = rEntry.GetQueryItem();
 
         aField.Connection    = (rEntry.eConnect == SC_AND) ? sheet::FilterConnection_AND :
                                                              sheet::FilterConnection_OR;
         aField.Field         = rEntry.nField;
-        aField.IsNumeric     = !rEntry.bQueryByString;
-        aField.StringValue   = aStringValue;
-        aField.NumericValue  = rEntry.nVal;
+        aField.IsNumeric     = rItem.meType != ScQueryEntry::ByString;
+        aField.StringValue   = rItem.maString;
+        aField.NumericValue  = rItem.mfVal;
 
         switch (rEntry.eOp)             // ScQueryOp
         {
             case SC_EQUAL:
                 {
                     aField.Operator = sheet::FilterOperator_EQUAL;
-                    if (!rEntry.bQueryByString && rEntry.GetQueryString().isEmpty())
+                    if (!rItem.meType != ScQueryEntry::ByString && rItem.maString.isEmpty())
                     {
-                        if (rEntry.nVal == SC_EMPTYFIELDS)
+                        if (rItem.mfVal == SC_EMPTYFIELDS)
                         {
                             aField.Operator = sheet::FilterOperator_EMPTY;
                             aField.NumericValue = 0;
                         }
-                        else if (rEntry.nVal == SC_NONEMPTYFIELDS)
+                        else if (rItem.mfVal == SC_NONEMPTYFIELDS)
                         {
                             aField.Operator = sheet::FilterOperator_NOT_EMPTY;
                             aField.NumericValue = 0;
@@ -1248,28 +1244,27 @@ throw(uno::RuntimeException)
     for (SCSIZE i=0; i<nCount; i++)
     {
         const ScQueryEntry& rEntry = aParam.GetEntry(i);
-
-        rtl::OUString aStringValue = rEntry.GetQueryString();
+        const ScQueryEntry::Item& rItem = rEntry.GetQueryItem();
 
         aField.Connection    = (rEntry.eConnect == SC_AND) ? sheet::FilterConnection_AND : sheet::FilterConnection_OR;
         aField.Field         = rEntry.nField;
-        aField.IsNumeric     = !rEntry.bQueryByString;
-        aField.StringValue   = aStringValue;
-        aField.NumericValue  = rEntry.nVal;
+        aField.IsNumeric     = !rItem.meType != ScQueryEntry::ByString;
+        aField.StringValue   = rItem.maString;
+        aField.NumericValue  = rItem.mfVal;
 
         switch (rEntry.eOp)             // ScQueryOp
         {
         case SC_EQUAL:
             {
                 aField.Operator = sheet::FilterOperator2::EQUAL;
-                if (!rEntry.bQueryByString && rEntry.GetQueryString().isEmpty())
+                if (!rItem.meType != ScQueryEntry::ByString && rItem.maString.isEmpty())
                 {
-                    if (rEntry.nVal == SC_EMPTYFIELDS)
+                    if (rItem.mfVal == SC_EMPTYFIELDS)
                     {
                         aField.Operator = sheet::FilterOperator2::EMPTY;
                         aField.NumericValue = 0;
                     }
-                    else if (rEntry.nVal == SC_NONEMPTYFIELDS)
+                    else if (rItem.mfVal == SC_NONEMPTYFIELDS)
                     {
                         aField.Operator = sheet::FilterOperator2::NOT_EMPTY;
                         aField.NumericValue = 0;

... etc. - the rest is truncated


More information about the Libreoffice-commits mailing list