1*b3f79822SAndrew Rist /**************************************************************
2cdf0e10cSrcweir *
3*b3f79822SAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one
4*b3f79822SAndrew Rist * or more contributor license agreements. See the NOTICE file
5*b3f79822SAndrew Rist * distributed with this work for additional information
6*b3f79822SAndrew Rist * regarding copyright ownership. The ASF licenses this file
7*b3f79822SAndrew Rist * to you under the Apache License, Version 2.0 (the
8*b3f79822SAndrew Rist * "License"); you may not use this file except in compliance
9*b3f79822SAndrew Rist * with the License. You may obtain a copy of the License at
10cdf0e10cSrcweir *
11*b3f79822SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0
12cdf0e10cSrcweir *
13*b3f79822SAndrew Rist * Unless required by applicable law or agreed to in writing,
14*b3f79822SAndrew Rist * software distributed under the License is distributed on an
15*b3f79822SAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*b3f79822SAndrew Rist * KIND, either express or implied. See the License for the
17*b3f79822SAndrew Rist * specific language governing permissions and limitations
18*b3f79822SAndrew Rist * under the License.
19cdf0e10cSrcweir *
20*b3f79822SAndrew Rist *************************************************************/
21*b3f79822SAndrew Rist
22*b3f79822SAndrew Rist
23cdf0e10cSrcweir
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_sc.hxx"
26cdf0e10cSrcweir
27cdf0e10cSrcweir // INCLUDE ---------------------------------------------------------------
28cdf0e10cSrcweir
29cdf0e10cSrcweir #include "doubleref.hxx"
30cdf0e10cSrcweir #include "cell.hxx"
31cdf0e10cSrcweir #include "global.hxx"
32cdf0e10cSrcweir #include "document.hxx"
33cdf0e10cSrcweir #include "queryparam.hxx"
34cdf0e10cSrcweir #include "globstr.hrc"
35cdf0e10cSrcweir
36cdf0e10cSrcweir #include <memory>
37cdf0e10cSrcweir #include <vector>
38cdf0e10cSrcweir
39cdf0e10cSrcweir using ::rtl::OUString;
40cdf0e10cSrcweir using ::std::auto_ptr;
41cdf0e10cSrcweir using ::std::vector;
42cdf0e10cSrcweir
43cdf0e10cSrcweir namespace {
44cdf0e10cSrcweir
lcl_toUpper(OUString & rStr)45cdf0e10cSrcweir void lcl_toUpper(OUString& rStr)
46cdf0e10cSrcweir {
47cdf0e10cSrcweir rStr = ScGlobal::pCharClass->toUpper(rStr.trim(), 0, static_cast<xub_StrLen>(rStr.getLength()));
48cdf0e10cSrcweir }
49cdf0e10cSrcweir
lcl_createStarQuery(ScQueryParamBase * pParam,const ScDBRangeBase * pDBRef,const ScDBRangeBase * pQueryRef)50cdf0e10cSrcweir bool lcl_createStarQuery(ScQueryParamBase* pParam, const ScDBRangeBase* pDBRef, const ScDBRangeBase* pQueryRef)
51cdf0e10cSrcweir {
52cdf0e10cSrcweir // A valid StarQuery must be at least 4 columns wide. To be precise it
53cdf0e10cSrcweir // should be exactly 4 columns ...
54cdf0e10cSrcweir // Additionally, if this wasn't checked, a formula pointing to a valid 1-3
55cdf0e10cSrcweir // column Excel style query range immediately left to itself would result
56cdf0e10cSrcweir // in a circular reference when the field name or operator or value (first
57cdf0e10cSrcweir // to third query range column) is obtained (#i58354#). Furthermore, if the
58cdf0e10cSrcweir // range wasn't sufficiently specified data changes wouldn't flag formula
59cdf0e10cSrcweir // cells for recalculation.
60cdf0e10cSrcweir
61cdf0e10cSrcweir if (pQueryRef->getColSize() < 4)
62cdf0e10cSrcweir return false;
63cdf0e10cSrcweir
64cdf0e10cSrcweir sal_Bool bValid;
65cdf0e10cSrcweir sal_Bool bFound;
66cdf0e10cSrcweir OUString aCellStr;
67cdf0e10cSrcweir SCSIZE nIndex = 0;
68cdf0e10cSrcweir SCROW nRow = 0;
69cdf0e10cSrcweir SCROW nRows = pDBRef->getRowSize();
70cdf0e10cSrcweir SCSIZE nNewEntries = static_cast<SCSIZE>(nRows);
71cdf0e10cSrcweir pParam->Resize(nNewEntries);
72cdf0e10cSrcweir
73cdf0e10cSrcweir do
74cdf0e10cSrcweir {
75cdf0e10cSrcweir ScQueryEntry& rEntry = pParam->GetEntry(nIndex);
76cdf0e10cSrcweir
77cdf0e10cSrcweir bValid = sal_False;
78cdf0e10cSrcweir
79cdf0e10cSrcweir if (nIndex > 0)
80cdf0e10cSrcweir {
81cdf0e10cSrcweir // For all entries after the first one, check the and/or connector in the first column.
82cdf0e10cSrcweir aCellStr = pQueryRef->getString(0, nRow);
83cdf0e10cSrcweir lcl_toUpper(aCellStr);
84cdf0e10cSrcweir if ( aCellStr.equals(ScGlobal::GetRscString(STR_TABLE_UND)) )
85cdf0e10cSrcweir {
86cdf0e10cSrcweir rEntry.eConnect = SC_AND;
87cdf0e10cSrcweir bValid = sal_True;
88cdf0e10cSrcweir }
89cdf0e10cSrcweir else if ( aCellStr.equals(ScGlobal::GetRscString(STR_TABLE_ODER)) )
90cdf0e10cSrcweir {
91cdf0e10cSrcweir rEntry.eConnect = SC_OR;
92cdf0e10cSrcweir bValid = sal_True;
93cdf0e10cSrcweir }
94cdf0e10cSrcweir }
95cdf0e10cSrcweir
96cdf0e10cSrcweir if ((nIndex < 1) || bValid)
97cdf0e10cSrcweir {
98cdf0e10cSrcweir // field name in the 2nd column.
99cdf0e10cSrcweir bFound = sal_False;
100cdf0e10cSrcweir aCellStr = pQueryRef->getString(1, nRow);
101cdf0e10cSrcweir SCCOL nField = pDBRef->findFieldColumn(aCellStr); // TODO: must be case insensitive comparison.
102cdf0e10cSrcweir if (ValidCol(nField))
103cdf0e10cSrcweir {
104cdf0e10cSrcweir rEntry.nField = nField;
105cdf0e10cSrcweir bValid = true;
106cdf0e10cSrcweir }
107cdf0e10cSrcweir else
108cdf0e10cSrcweir bValid = false;
109cdf0e10cSrcweir }
110cdf0e10cSrcweir
111cdf0e10cSrcweir if (bValid)
112cdf0e10cSrcweir {
113cdf0e10cSrcweir // equality, non-equality operator in the 3rd column.
114cdf0e10cSrcweir bFound = sal_False;
115cdf0e10cSrcweir aCellStr = pQueryRef->getString(2, nRow);
116cdf0e10cSrcweir lcl_toUpper(aCellStr);
117cdf0e10cSrcweir const sal_Unicode* p = aCellStr.getStr();
118cdf0e10cSrcweir if (p[0] == sal_Unicode('<'))
119cdf0e10cSrcweir {
120cdf0e10cSrcweir if (p[1] == sal_Unicode('>'))
121cdf0e10cSrcweir rEntry.eOp = SC_NOT_EQUAL;
122cdf0e10cSrcweir else if (p[1] == sal_Unicode('='))
123cdf0e10cSrcweir rEntry.eOp = SC_LESS_EQUAL;
124cdf0e10cSrcweir else
125cdf0e10cSrcweir rEntry.eOp = SC_LESS;
126cdf0e10cSrcweir }
127cdf0e10cSrcweir else if (p[0] == sal_Unicode('>'))
128cdf0e10cSrcweir {
129cdf0e10cSrcweir if (p[1] == sal_Unicode('='))
130cdf0e10cSrcweir rEntry.eOp = SC_GREATER_EQUAL;
131cdf0e10cSrcweir else
132cdf0e10cSrcweir rEntry.eOp = SC_GREATER;
133cdf0e10cSrcweir }
134cdf0e10cSrcweir else if (p[0] == sal_Unicode('='))
135cdf0e10cSrcweir rEntry.eOp = SC_EQUAL;
136cdf0e10cSrcweir
137cdf0e10cSrcweir }
138cdf0e10cSrcweir
139cdf0e10cSrcweir if (bValid)
140cdf0e10cSrcweir {
141cdf0e10cSrcweir // Finally, the right-hand-side value in the 4th column.
142cdf0e10cSrcweir *rEntry.pStr = pQueryRef->getString(3, nRow);
143cdf0e10cSrcweir rEntry.bDoQuery = sal_True;
144cdf0e10cSrcweir }
145cdf0e10cSrcweir nIndex++;
146cdf0e10cSrcweir nRow++;
147cdf0e10cSrcweir }
148cdf0e10cSrcweir while (bValid && (nRow < nRows) /* && (nIndex < MAXQUERY) */ );
149cdf0e10cSrcweir return bValid;
150cdf0e10cSrcweir }
151cdf0e10cSrcweir
lcl_createExcelQuery(ScQueryParamBase * pParam,const ScDBRangeBase * pDBRef,const ScDBRangeBase * pQueryRef)152cdf0e10cSrcweir bool lcl_createExcelQuery(
153cdf0e10cSrcweir ScQueryParamBase* pParam, const ScDBRangeBase* pDBRef, const ScDBRangeBase* pQueryRef)
154cdf0e10cSrcweir {
155cdf0e10cSrcweir bool bValid = true;
156cdf0e10cSrcweir SCCOL nCols = pQueryRef->getColSize();
157cdf0e10cSrcweir SCROW nRows = pQueryRef->getRowSize();
158cdf0e10cSrcweir vector<SCCOL> aFields(nCols);
159cdf0e10cSrcweir SCCOL nCol = 0;
160cdf0e10cSrcweir while (bValid && (nCol < nCols))
161cdf0e10cSrcweir {
162cdf0e10cSrcweir OUString aQueryStr = pQueryRef->getString(nCol, 0);
163cdf0e10cSrcweir SCCOL nField = pDBRef->findFieldColumn(aQueryStr);
164cdf0e10cSrcweir if (ValidCol(nField))
165cdf0e10cSrcweir aFields[nCol] = nField;
166cdf0e10cSrcweir else
167cdf0e10cSrcweir bValid = false;
168cdf0e10cSrcweir ++nCol;
169cdf0e10cSrcweir }
170cdf0e10cSrcweir
171cdf0e10cSrcweir if (bValid)
172cdf0e10cSrcweir {
173cdf0e10cSrcweir // sal_uLong nVisible = 0;
174cdf0e10cSrcweir // for ( nCol=nCol1; nCol<=nCol2; nCol++ )
175cdf0e10cSrcweir // nVisible += aCol[nCol].VisibleCount( nRow1+1, nRow2 );
176cdf0e10cSrcweir
177cdf0e10cSrcweir // Count the number of visible cells (excluding the header row). Each
178cdf0e10cSrcweir // visible cell corresponds with a single query.
179cdf0e10cSrcweir SCSIZE nVisible = pQueryRef->getVisibleDataCellCount();
180cdf0e10cSrcweir if ( nVisible > SCSIZE_MAX / sizeof(void*) )
181cdf0e10cSrcweir {
182cdf0e10cSrcweir DBG_ERROR("zu viele Filterkritierien");
183cdf0e10cSrcweir nVisible = 0;
184cdf0e10cSrcweir }
185cdf0e10cSrcweir
186cdf0e10cSrcweir SCSIZE nNewEntries = nVisible;
187cdf0e10cSrcweir pParam->Resize( nNewEntries );
188cdf0e10cSrcweir
189cdf0e10cSrcweir SCSIZE nIndex = 0;
190cdf0e10cSrcweir SCROW nRow = 1;
191cdf0e10cSrcweir String aCellStr;
192cdf0e10cSrcweir while (nRow < nRows)
193cdf0e10cSrcweir {
194cdf0e10cSrcweir nCol = 0;
195cdf0e10cSrcweir while (nCol < nCols)
196cdf0e10cSrcweir {
197cdf0e10cSrcweir aCellStr = pQueryRef->getString(nCol, nRow);
198cdf0e10cSrcweir ScGlobal::pCharClass->toUpper( aCellStr );
199cdf0e10cSrcweir if (aCellStr.Len() > 0)
200cdf0e10cSrcweir {
201cdf0e10cSrcweir if (nIndex < nNewEntries)
202cdf0e10cSrcweir {
203cdf0e10cSrcweir pParam->GetEntry(nIndex).nField = aFields[nCol];
204cdf0e10cSrcweir pParam->FillInExcelSyntax(aCellStr, nIndex);
205cdf0e10cSrcweir nIndex++;
206cdf0e10cSrcweir if (nIndex < nNewEntries)
207cdf0e10cSrcweir pParam->GetEntry(nIndex).eConnect = SC_AND;
208cdf0e10cSrcweir }
209cdf0e10cSrcweir else
210cdf0e10cSrcweir bValid = sal_False;
211cdf0e10cSrcweir }
212cdf0e10cSrcweir nCol++;
213cdf0e10cSrcweir }
214cdf0e10cSrcweir nRow++;
215cdf0e10cSrcweir if (nIndex < nNewEntries)
216cdf0e10cSrcweir pParam->GetEntry(nIndex).eConnect = SC_OR;
217cdf0e10cSrcweir }
218cdf0e10cSrcweir }
219cdf0e10cSrcweir return bValid;
220cdf0e10cSrcweir }
221cdf0e10cSrcweir
lcl_fillQueryEntries(ScQueryParamBase * pParam,const ScDBRangeBase * pDBRef,const ScDBRangeBase * pQueryRef)222cdf0e10cSrcweir bool lcl_fillQueryEntries(
223cdf0e10cSrcweir ScQueryParamBase* pParam, const ScDBRangeBase* pDBRef, const ScDBRangeBase* pQueryRef)
224cdf0e10cSrcweir {
225cdf0e10cSrcweir SCSIZE nCount = pParam->GetEntryCount();
226cdf0e10cSrcweir for (SCSIZE i = 0; i < nCount; ++i)
227cdf0e10cSrcweir pParam->GetEntry(i).Clear();
228cdf0e10cSrcweir
229cdf0e10cSrcweir // Standard QueryTabelle
230cdf0e10cSrcweir bool bValid = lcl_createStarQuery(pParam, pDBRef, pQueryRef);
231cdf0e10cSrcweir // Excel QueryTabelle
232cdf0e10cSrcweir if (!bValid)
233cdf0e10cSrcweir bValid = lcl_createExcelQuery(pParam, pDBRef, pQueryRef);
234cdf0e10cSrcweir
235cdf0e10cSrcweir nCount = pParam->GetEntryCount();
236cdf0e10cSrcweir if (bValid)
237cdf0e10cSrcweir {
238cdf0e10cSrcweir // bQueryByString muss gesetzt sein
239cdf0e10cSrcweir for (SCSIZE i = 0; i < nCount; ++i)
240cdf0e10cSrcweir pParam->GetEntry(i).bQueryByString = true;
241cdf0e10cSrcweir }
242cdf0e10cSrcweir else
243cdf0e10cSrcweir {
244cdf0e10cSrcweir // nix
245cdf0e10cSrcweir for (SCSIZE i = 0; i < nCount; ++i)
246cdf0e10cSrcweir pParam->GetEntry(i).Clear();
247cdf0e10cSrcweir }
248cdf0e10cSrcweir return bValid;
249cdf0e10cSrcweir }
250cdf0e10cSrcweir
251cdf0e10cSrcweir }
252cdf0e10cSrcweir
253cdf0e10cSrcweir // ============================================================================
254cdf0e10cSrcweir
ScDBRangeBase(ScDocument * pDoc,RefType eType)255cdf0e10cSrcweir ScDBRangeBase::ScDBRangeBase(ScDocument* pDoc, RefType eType) :
256cdf0e10cSrcweir mpDoc(pDoc), meType(eType)
257cdf0e10cSrcweir {
258cdf0e10cSrcweir }
259cdf0e10cSrcweir
~ScDBRangeBase()260cdf0e10cSrcweir ScDBRangeBase::~ScDBRangeBase()
261cdf0e10cSrcweir {
262cdf0e10cSrcweir }
263cdf0e10cSrcweir
fillQueryEntries(ScQueryParamBase * pParam,const ScDBRangeBase * pDBRef) const264cdf0e10cSrcweir bool ScDBRangeBase::fillQueryEntries(ScQueryParamBase* pParam, const ScDBRangeBase* pDBRef) const
265cdf0e10cSrcweir {
266cdf0e10cSrcweir if (!pDBRef)
267cdf0e10cSrcweir return false;
268cdf0e10cSrcweir
269cdf0e10cSrcweir return lcl_fillQueryEntries(pParam, pDBRef, this);
270cdf0e10cSrcweir }
271cdf0e10cSrcweir
fillQueryOptions(ScQueryParamBase * pParam)272cdf0e10cSrcweir void ScDBRangeBase::fillQueryOptions(ScQueryParamBase* pParam)
273cdf0e10cSrcweir {
274cdf0e10cSrcweir pParam->bHasHeader = true;
275cdf0e10cSrcweir pParam->bByRow = true;
276cdf0e10cSrcweir pParam->bInplace = true;
277cdf0e10cSrcweir pParam->bCaseSens = false;
278cdf0e10cSrcweir pParam->bRegExp = false;
279cdf0e10cSrcweir pParam->bDuplicate = true;
280cdf0e10cSrcweir pParam->bMixedComparison = false;
281cdf0e10cSrcweir }
282cdf0e10cSrcweir
getDoc() const283cdf0e10cSrcweir ScDocument* ScDBRangeBase::getDoc() const
284cdf0e10cSrcweir {
285cdf0e10cSrcweir return mpDoc;
286cdf0e10cSrcweir }
287cdf0e10cSrcweir
288cdf0e10cSrcweir // ============================================================================
289cdf0e10cSrcweir
ScDBInternalRange(ScDocument * pDoc,const ScRange & rRange)290cdf0e10cSrcweir ScDBInternalRange::ScDBInternalRange(ScDocument* pDoc, const ScRange& rRange) :
291cdf0e10cSrcweir ScDBRangeBase(pDoc, INTERNAL), maRange(rRange)
292cdf0e10cSrcweir {
293cdf0e10cSrcweir }
294cdf0e10cSrcweir
~ScDBInternalRange()295cdf0e10cSrcweir ScDBInternalRange::~ScDBInternalRange()
296cdf0e10cSrcweir {
297cdf0e10cSrcweir }
298cdf0e10cSrcweir
getRange() const299cdf0e10cSrcweir const ScRange& ScDBInternalRange::getRange() const
300cdf0e10cSrcweir {
301cdf0e10cSrcweir return maRange;
302cdf0e10cSrcweir }
303cdf0e10cSrcweir
getColSize() const304cdf0e10cSrcweir SCCOL ScDBInternalRange::getColSize() const
305cdf0e10cSrcweir {
306cdf0e10cSrcweir return maRange.aEnd.Col() - maRange.aStart.Col() + 1;
307cdf0e10cSrcweir }
308cdf0e10cSrcweir
getRowSize() const309cdf0e10cSrcweir SCROW ScDBInternalRange::getRowSize() const
310cdf0e10cSrcweir {
311cdf0e10cSrcweir return maRange.aEnd.Row() - maRange.aStart.Row() + 1;
312cdf0e10cSrcweir }
313cdf0e10cSrcweir
getVisibleDataCellCount() const314cdf0e10cSrcweir SCSIZE ScDBInternalRange::getVisibleDataCellCount() const
315cdf0e10cSrcweir {
316cdf0e10cSrcweir SCCOL nCols = getColSize();
317cdf0e10cSrcweir SCROW nRows = getRowSize();
318cdf0e10cSrcweir if (nRows <= 1)
319cdf0e10cSrcweir return 0;
320cdf0e10cSrcweir
321cdf0e10cSrcweir return (nRows-1)*nCols;
322cdf0e10cSrcweir }
323cdf0e10cSrcweir
getString(SCCOL nCol,SCROW nRow) const324cdf0e10cSrcweir OUString ScDBInternalRange::getString(SCCOL nCol, SCROW nRow) const
325cdf0e10cSrcweir {
326cdf0e10cSrcweir String aStr;
327cdf0e10cSrcweir const ScAddress& s = maRange.aStart;
328cdf0e10cSrcweir // #i109200# this is used in formula calculation, use GetInputString, not GetString
329cdf0e10cSrcweir // (consistent with ScDBInternalRange::getCellString)
330cdf0e10cSrcweir // GetStringForFormula is not used here, to allow querying for date values.
331cdf0e10cSrcweir getDoc()->GetInputString(s.Col() + nCol, s.Row() + nRow, maRange.aStart.Tab(), aStr);
332cdf0e10cSrcweir return aStr;
333cdf0e10cSrcweir }
334cdf0e10cSrcweir
getFirstFieldColumn() const335cdf0e10cSrcweir SCCOL ScDBInternalRange::getFirstFieldColumn() const
336cdf0e10cSrcweir {
337cdf0e10cSrcweir return getRange().aStart.Col();
338cdf0e10cSrcweir }
339cdf0e10cSrcweir
findFieldColumn(SCCOL nIndex) const340cdf0e10cSrcweir SCCOL ScDBInternalRange::findFieldColumn(SCCOL nIndex) const
341cdf0e10cSrcweir {
342cdf0e10cSrcweir const ScRange& rRange = getRange();
343cdf0e10cSrcweir const ScAddress& s = rRange.aStart;
344cdf0e10cSrcweir const ScAddress& e = rRange.aEnd;
345cdf0e10cSrcweir
346cdf0e10cSrcweir SCCOL nDBCol1 = s.Col();
347cdf0e10cSrcweir SCCOL nDBCol2 = e.Col();
348cdf0e10cSrcweir
349cdf0e10cSrcweir if ( nIndex <= 0 || nIndex > (nDBCol2 - nDBCol1 + 1) )
350cdf0e10cSrcweir return nDBCol1;
351cdf0e10cSrcweir
352cdf0e10cSrcweir return Min(nDBCol2, static_cast<SCCOL>(nDBCol1 + nIndex - 1));
353cdf0e10cSrcweir }
354cdf0e10cSrcweir
findFieldColumn(const OUString & rStr,sal_uInt16 * pErr) const355cdf0e10cSrcweir SCCOL ScDBInternalRange::findFieldColumn(const OUString& rStr, sal_uInt16* pErr) const
356cdf0e10cSrcweir {
357cdf0e10cSrcweir const ScAddress& s = maRange.aStart;
358cdf0e10cSrcweir const ScAddress& e = maRange.aEnd;
359cdf0e10cSrcweir OUString aUpper = rStr;
360cdf0e10cSrcweir lcl_toUpper(aUpper);
361cdf0e10cSrcweir
362cdf0e10cSrcweir SCCOL nDBCol1 = s.Col();
363cdf0e10cSrcweir SCROW nDBRow1 = s.Row();
364cdf0e10cSrcweir SCTAB nDBTab1 = s.Tab();
365cdf0e10cSrcweir SCCOL nDBCol2 = e.Col();
366cdf0e10cSrcweir
367cdf0e10cSrcweir SCCOL nField = nDBCol1;
368cdf0e10cSrcweir sal_Bool bFound = sal_True;
369cdf0e10cSrcweir
370cdf0e10cSrcweir bFound = sal_False;
371cdf0e10cSrcweir OUString aCellStr;
372cdf0e10cSrcweir ScAddress aLook( nDBCol1, nDBRow1, nDBTab1 );
373cdf0e10cSrcweir while (!bFound && (aLook.Col() <= nDBCol2))
374cdf0e10cSrcweir {
375cdf0e10cSrcweir sal_uInt16 nErr = getDoc()->GetStringForFormula( aLook, aCellStr );
376cdf0e10cSrcweir if (pErr)
377cdf0e10cSrcweir *pErr = nErr;
378cdf0e10cSrcweir lcl_toUpper(aCellStr);
379cdf0e10cSrcweir bFound = ScGlobal::GetpTransliteration()->isEqual(aCellStr, aUpper);
380cdf0e10cSrcweir if (!bFound)
381cdf0e10cSrcweir aLook.IncCol();
382cdf0e10cSrcweir }
383cdf0e10cSrcweir nField = aLook.Col();
384cdf0e10cSrcweir
385cdf0e10cSrcweir return bFound ? nField : -1;
386cdf0e10cSrcweir }
387cdf0e10cSrcweir
createQueryParam(const ScDBRangeBase * pQueryRef) const388cdf0e10cSrcweir ScDBQueryParamBase* ScDBInternalRange::createQueryParam(const ScDBRangeBase* pQueryRef) const
389cdf0e10cSrcweir {
390cdf0e10cSrcweir auto_ptr<ScDBQueryParamInternal> pParam(new ScDBQueryParamInternal);
391cdf0e10cSrcweir
392cdf0e10cSrcweir // Set the database range first.
393cdf0e10cSrcweir const ScAddress& s = maRange.aStart;
394cdf0e10cSrcweir const ScAddress& e = maRange.aEnd;
395cdf0e10cSrcweir pParam->nCol1 = s.Col();
396cdf0e10cSrcweir pParam->nRow1 = s.Row();
397cdf0e10cSrcweir pParam->nCol2 = e.Col();
398cdf0e10cSrcweir pParam->nRow2 = e.Row();
399cdf0e10cSrcweir pParam->nTab = s.Tab();
400cdf0e10cSrcweir
401cdf0e10cSrcweir fillQueryOptions(pParam.get());
402cdf0e10cSrcweir
403cdf0e10cSrcweir // Now construct the query entries from the query range.
404cdf0e10cSrcweir if (!pQueryRef->fillQueryEntries(pParam.get(), this))
405cdf0e10cSrcweir return NULL;
406cdf0e10cSrcweir
407cdf0e10cSrcweir return pParam.release();
408cdf0e10cSrcweir }
409cdf0e10cSrcweir
isRangeEqual(const ScRange & rRange) const410cdf0e10cSrcweir bool ScDBInternalRange::isRangeEqual(const ScRange& rRange) const
411cdf0e10cSrcweir {
412cdf0e10cSrcweir return maRange == rRange;
413cdf0e10cSrcweir }
414cdf0e10cSrcweir
415cdf0e10cSrcweir // ============================================================================
416cdf0e10cSrcweir
ScDBExternalRange(ScDocument * pDoc,const ScMatrixRef & pMat)417cdf0e10cSrcweir ScDBExternalRange::ScDBExternalRange(ScDocument* pDoc, const ScMatrixRef& pMat) :
418cdf0e10cSrcweir ScDBRangeBase(pDoc, EXTERNAL), mpMatrix(pMat)
419cdf0e10cSrcweir {
420cdf0e10cSrcweir SCSIZE nC, nR;
421cdf0e10cSrcweir mpMatrix->GetDimensions(nC, nR);
422cdf0e10cSrcweir mnCols = static_cast<SCCOL>(nC);
423cdf0e10cSrcweir mnRows = static_cast<SCROW>(nR);
424cdf0e10cSrcweir }
425cdf0e10cSrcweir
~ScDBExternalRange()426cdf0e10cSrcweir ScDBExternalRange::~ScDBExternalRange()
427cdf0e10cSrcweir {
428cdf0e10cSrcweir }
429cdf0e10cSrcweir
getColSize() const430cdf0e10cSrcweir SCCOL ScDBExternalRange::getColSize() const
431cdf0e10cSrcweir {
432cdf0e10cSrcweir return mnCols;
433cdf0e10cSrcweir }
434cdf0e10cSrcweir
getRowSize() const435cdf0e10cSrcweir SCROW ScDBExternalRange::getRowSize() const
436cdf0e10cSrcweir {
437cdf0e10cSrcweir return mnRows;
438cdf0e10cSrcweir }
439cdf0e10cSrcweir
getVisibleDataCellCount() const440cdf0e10cSrcweir SCSIZE ScDBExternalRange::getVisibleDataCellCount() const
441cdf0e10cSrcweir {
442cdf0e10cSrcweir SCCOL nCols = getColSize();
443cdf0e10cSrcweir SCROW nRows = getRowSize();
444cdf0e10cSrcweir if (nRows <= 1)
445cdf0e10cSrcweir return 0;
446cdf0e10cSrcweir
447cdf0e10cSrcweir return (nRows-1)*nCols;
448cdf0e10cSrcweir }
449cdf0e10cSrcweir
getString(SCCOL nCol,SCROW nRow) const450cdf0e10cSrcweir OUString ScDBExternalRange::getString(SCCOL nCol, SCROW nRow) const
451cdf0e10cSrcweir {
452cdf0e10cSrcweir if (nCol >= mnCols || nRow >= mnRows)
453cdf0e10cSrcweir return OUString();
454cdf0e10cSrcweir
455cdf0e10cSrcweir return mpMatrix->GetString(nCol, nRow);
456cdf0e10cSrcweir }
457cdf0e10cSrcweir
getFirstFieldColumn() const458cdf0e10cSrcweir SCCOL ScDBExternalRange::getFirstFieldColumn() const
459cdf0e10cSrcweir {
460cdf0e10cSrcweir return 0;
461cdf0e10cSrcweir }
462cdf0e10cSrcweir
findFieldColumn(SCCOL nIndex) const463cdf0e10cSrcweir SCCOL ScDBExternalRange::findFieldColumn(SCCOL nIndex) const
464cdf0e10cSrcweir {
465cdf0e10cSrcweir if (nIndex < 1)
466cdf0e10cSrcweir // 1st field
467cdf0e10cSrcweir return 0;
468cdf0e10cSrcweir
469cdf0e10cSrcweir if (nIndex > mnCols)
470cdf0e10cSrcweir // last field
471cdf0e10cSrcweir return mnCols - 1;
472cdf0e10cSrcweir
473cdf0e10cSrcweir return nIndex - 1;
474cdf0e10cSrcweir }
475cdf0e10cSrcweir
findFieldColumn(const OUString & rStr,sal_uInt16 * pErr) const476cdf0e10cSrcweir SCCOL ScDBExternalRange::findFieldColumn(const OUString& rStr, sal_uInt16* pErr) const
477cdf0e10cSrcweir {
478cdf0e10cSrcweir if (pErr)
479cdf0e10cSrcweir pErr = 0;
480cdf0e10cSrcweir
481cdf0e10cSrcweir OUString aUpper = rStr;
482cdf0e10cSrcweir lcl_toUpper(aUpper);
483cdf0e10cSrcweir for (SCCOL i = 0; i < mnCols; ++i)
484cdf0e10cSrcweir {
485cdf0e10cSrcweir OUString aUpperVal = mpMatrix->GetString(i, 0);
486cdf0e10cSrcweir lcl_toUpper(aUpperVal);
487cdf0e10cSrcweir if (aUpper.equals(aUpperVal))
488cdf0e10cSrcweir return i;
489cdf0e10cSrcweir }
490cdf0e10cSrcweir return -1;
491cdf0e10cSrcweir }
492cdf0e10cSrcweir
createQueryParam(const ScDBRangeBase * pQueryRef) const493cdf0e10cSrcweir ScDBQueryParamBase* ScDBExternalRange::createQueryParam(const ScDBRangeBase* pQueryRef) const
494cdf0e10cSrcweir {
495cdf0e10cSrcweir auto_ptr<ScDBQueryParamMatrix> pParam(new ScDBQueryParamMatrix);
496cdf0e10cSrcweir pParam->mpMatrix = mpMatrix;
497cdf0e10cSrcweir fillQueryOptions(pParam.get());
498cdf0e10cSrcweir
499cdf0e10cSrcweir // Now construct the query entries from the query range.
500cdf0e10cSrcweir if (!pQueryRef->fillQueryEntries(pParam.get(), this))
501cdf0e10cSrcweir return NULL;
502cdf0e10cSrcweir
503cdf0e10cSrcweir return pParam.release();
504cdf0e10cSrcweir }
505cdf0e10cSrcweir
isRangeEqual(const ScRange &) const506cdf0e10cSrcweir bool ScDBExternalRange::isRangeEqual(const ScRange& /*rRange*/) const
507cdf0e10cSrcweir {
508cdf0e10cSrcweir return false;
509cdf0e10cSrcweir }
510cdf0e10cSrcweir
511