1b3f79822SAndrew Rist /**************************************************************
2cdf0e10cSrcweir *
3b3f79822SAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one
4b3f79822SAndrew Rist * or more contributor license agreements. See the NOTICE file
5b3f79822SAndrew Rist * distributed with this work for additional information
6b3f79822SAndrew Rist * regarding copyright ownership. The ASF licenses this file
7b3f79822SAndrew Rist * to you under the Apache License, Version 2.0 (the
8b3f79822SAndrew Rist * "License"); you may not use this file except in compliance
9b3f79822SAndrew Rist * with the License. You may obtain a copy of the License at
10b3f79822SAndrew Rist *
11b3f79822SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0
12b3f79822SAndrew Rist *
13b3f79822SAndrew Rist * Unless required by applicable law or agreed to in writing,
14b3f79822SAndrew Rist * software distributed under the License is distributed on an
15b3f79822SAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16b3f79822SAndrew Rist * KIND, either express or implied. See the License for the
17b3f79822SAndrew Rist * specific language governing permissions and limitations
18b3f79822SAndrew Rist * under the License.
19b3f79822SAndrew Rist *
20b3f79822SAndrew Rist *************************************************************/
21b3f79822SAndrew Rist
22b3f79822SAndrew Rist
23cdf0e10cSrcweir
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_sc.hxx"
26cdf0e10cSrcweir
27cdf0e10cSrcweir // INCLUDE ---------------------------------------------------------------
28cdf0e10cSrcweir
29cdf0e10cSrcweir #include <svl/zforlist.hxx>
30cdf0e10cSrcweir
31cdf0e10cSrcweir #include "scitems.hxx"
32cdf0e10cSrcweir #include "global.hxx"
33cdf0e10cSrcweir #include "dociter.hxx"
34cdf0e10cSrcweir #include "document.hxx"
35cdf0e10cSrcweir #include "table.hxx"
36cdf0e10cSrcweir #include "column.hxx"
37cdf0e10cSrcweir #include "cell.hxx"
38cdf0e10cSrcweir #include "attarray.hxx"
39cdf0e10cSrcweir #include "patattr.hxx"
40cdf0e10cSrcweir #include "docoptio.hxx"
41cdf0e10cSrcweir #include "cellform.hxx"
42cdf0e10cSrcweir
43cdf0e10cSrcweir #include <vector>
44cdf0e10cSrcweir
45cdf0e10cSrcweir using ::rtl::math::approxEqual;
46cdf0e10cSrcweir using ::std::vector;
47cdf0e10cSrcweir using ::rtl::OUString;
48cdf0e10cSrcweir using ::std::set;
49cdf0e10cSrcweir
50cdf0e10cSrcweir // STATIC DATA -----------------------------------------------------------
51cdf0e10cSrcweir
52cdf0e10cSrcweir namespace {
53cdf0e10cSrcweir
lcl_toUpper(OUString & rStr)54cdf0e10cSrcweir void lcl_toUpper(OUString& rStr)
55cdf0e10cSrcweir {
56cdf0e10cSrcweir rStr = ScGlobal::pCharClass->toUpper(rStr.trim(), 0, static_cast<sal_uInt16>(rStr.getLength()));
57cdf0e10cSrcweir }
58cdf0e10cSrcweir
59cdf0e10cSrcweir }
60cdf0e10cSrcweir
ScDocumentIterator(ScDocument * pDocument,SCTAB nStartTable,SCTAB nEndTable)61cdf0e10cSrcweir ScDocumentIterator::ScDocumentIterator( ScDocument* pDocument,
62cdf0e10cSrcweir SCTAB nStartTable, SCTAB nEndTable ) :
63cdf0e10cSrcweir pDoc( pDocument ),
64cdf0e10cSrcweir nStartTab( nStartTable ),
65cdf0e10cSrcweir nEndTab( nEndTable )
66cdf0e10cSrcweir {
67cdf0e10cSrcweir PutInOrder( nStartTab, nEndTab );
68cdf0e10cSrcweir if (!ValidTab(nStartTab)) nStartTab = MAXTAB;
69cdf0e10cSrcweir if (!ValidTab(nEndTab)) nEndTab = MAXTAB;
70cdf0e10cSrcweir
71cdf0e10cSrcweir pDefPattern = pDoc->GetDefPattern();
72cdf0e10cSrcweir
73cdf0e10cSrcweir nCol = 0;
74cdf0e10cSrcweir nRow = 0;
75cdf0e10cSrcweir nTab = nStartTab;
76cdf0e10cSrcweir
77cdf0e10cSrcweir nColPos = 0;
78cdf0e10cSrcweir nAttrPos = 0;
79cdf0e10cSrcweir }
80cdf0e10cSrcweir
~ScDocumentIterator()81cdf0e10cSrcweir ScDocumentIterator::~ScDocumentIterator()
82cdf0e10cSrcweir {
83cdf0e10cSrcweir }
84cdf0e10cSrcweir
GetThisCol()85cdf0e10cSrcweir sal_Bool ScDocumentIterator::GetThisCol()
86cdf0e10cSrcweir {
87cdf0e10cSrcweir ScTable* pTab;
88cdf0e10cSrcweir while ( (pTab = pDoc->pTab[nTab]) == NULL )
89cdf0e10cSrcweir {
90cdf0e10cSrcweir if ( nTab == nEndTab )
91cdf0e10cSrcweir {
92cdf0e10cSrcweir nCol = MAXCOL;
93cdf0e10cSrcweir nRow = MAXROW;
94cdf0e10cSrcweir return sal_False;
95cdf0e10cSrcweir }
96cdf0e10cSrcweir ++nTab;
97cdf0e10cSrcweir }
98cdf0e10cSrcweir ScColumn* pCol = &pTab->aCol[nCol];
99cdf0e10cSrcweir ScAttrArray* pAtt = pCol->pAttrArray;
100cdf0e10cSrcweir
101cdf0e10cSrcweir sal_Bool bFound = sal_False;
102cdf0e10cSrcweir do
103cdf0e10cSrcweir {
104cdf0e10cSrcweir SCROW nColRow;
105cdf0e10cSrcweir SCROW nAttrEnd;
106cdf0e10cSrcweir
107cdf0e10cSrcweir do
108cdf0e10cSrcweir {
109cdf0e10cSrcweir nAttrEnd = pAtt->pData[nAttrPos].nRow;
110cdf0e10cSrcweir if (nAttrEnd < nRow)
111cdf0e10cSrcweir ++nAttrPos;
112cdf0e10cSrcweir }
113cdf0e10cSrcweir while (nAttrEnd < nRow);
114cdf0e10cSrcweir
115cdf0e10cSrcweir do
116cdf0e10cSrcweir {
117cdf0e10cSrcweir nColRow = (nColPos < pCol->nCount) ? pCol->pItems[nColPos].nRow : MAXROW+1;
118cdf0e10cSrcweir if (nColRow < nRow)
119cdf0e10cSrcweir ++nColPos;
120cdf0e10cSrcweir }
121cdf0e10cSrcweir while (nColRow < nRow);
122cdf0e10cSrcweir
123cdf0e10cSrcweir if (nColRow == nRow)
124cdf0e10cSrcweir {
125cdf0e10cSrcweir bFound = sal_True;
126cdf0e10cSrcweir pCell = pCol->pItems[nColPos].pCell;
127cdf0e10cSrcweir pPattern = pAtt->pData[nAttrPos].pPattern;
128cdf0e10cSrcweir }
129cdf0e10cSrcweir else if ( pAtt->pData[nAttrPos].pPattern != pDefPattern )
130cdf0e10cSrcweir {
131cdf0e10cSrcweir bFound = sal_True;
132cdf0e10cSrcweir pCell = NULL;
133cdf0e10cSrcweir pPattern = pAtt->pData[nAttrPos].pPattern;
134cdf0e10cSrcweir }
135cdf0e10cSrcweir else
136cdf0e10cSrcweir {
137cdf0e10cSrcweir nRow = Min( (SCROW)nColRow, (SCROW)(nAttrEnd+1) );
138cdf0e10cSrcweir }
139cdf0e10cSrcweir }
140cdf0e10cSrcweir while (!bFound && nRow <= MAXROW);
141cdf0e10cSrcweir
142cdf0e10cSrcweir return bFound;
143cdf0e10cSrcweir }
144cdf0e10cSrcweir
GetThis()145cdf0e10cSrcweir sal_Bool ScDocumentIterator::GetThis()
146cdf0e10cSrcweir {
147cdf0e10cSrcweir sal_Bool bEnd = sal_False;
148cdf0e10cSrcweir sal_Bool bSuccess = sal_False;
149cdf0e10cSrcweir
150cdf0e10cSrcweir while ( !bSuccess && !bEnd )
151cdf0e10cSrcweir {
152cdf0e10cSrcweir if ( nRow > MAXROW )
153cdf0e10cSrcweir bSuccess = sal_False;
154cdf0e10cSrcweir else
155cdf0e10cSrcweir bSuccess = GetThisCol();
156cdf0e10cSrcweir
157cdf0e10cSrcweir if ( !bSuccess )
158cdf0e10cSrcweir {
159cdf0e10cSrcweir ++nCol;
160cdf0e10cSrcweir if (nCol > MAXCOL)
161cdf0e10cSrcweir {
162cdf0e10cSrcweir nCol = 0;
163cdf0e10cSrcweir ++nTab;
164cdf0e10cSrcweir if (nTab > nEndTab)
165cdf0e10cSrcweir bEnd = sal_True;
166cdf0e10cSrcweir }
167cdf0e10cSrcweir nRow = 0;
168cdf0e10cSrcweir nColPos = 0;
169cdf0e10cSrcweir nAttrPos = 0;
170cdf0e10cSrcweir }
171cdf0e10cSrcweir }
172cdf0e10cSrcweir
173cdf0e10cSrcweir return !bEnd;
174cdf0e10cSrcweir }
175cdf0e10cSrcweir
GetFirst()176cdf0e10cSrcweir sal_Bool ScDocumentIterator::GetFirst()
177cdf0e10cSrcweir {
178cdf0e10cSrcweir nCol = 0;
179cdf0e10cSrcweir nTab = nStartTab;
180cdf0e10cSrcweir
181cdf0e10cSrcweir nRow = 0;
182cdf0e10cSrcweir nColPos = 0;
183cdf0e10cSrcweir nAttrPos = 0;
184cdf0e10cSrcweir
185cdf0e10cSrcweir return GetThis();
186cdf0e10cSrcweir }
187cdf0e10cSrcweir
GetNext()188cdf0e10cSrcweir sal_Bool ScDocumentIterator::GetNext()
189cdf0e10cSrcweir {
190cdf0e10cSrcweir ++nRow;
191cdf0e10cSrcweir
192cdf0e10cSrcweir return GetThis();
193cdf0e10cSrcweir }
194cdf0e10cSrcweir
195cdf0e10cSrcweir //------------------------------------------------------------------------
196cdf0e10cSrcweir
GetCell()197cdf0e10cSrcweir ScBaseCell* ScDocumentIterator::GetCell()
198cdf0e10cSrcweir {
199cdf0e10cSrcweir return pCell;
200cdf0e10cSrcweir }
201cdf0e10cSrcweir
GetPattern()202cdf0e10cSrcweir const ScPatternAttr* ScDocumentIterator::GetPattern()
203cdf0e10cSrcweir {
204cdf0e10cSrcweir return pPattern;
205cdf0e10cSrcweir }
206cdf0e10cSrcweir
GetPos(SCCOL & rCol,SCROW & rRow,SCTAB & rTab)207cdf0e10cSrcweir void ScDocumentIterator::GetPos( SCCOL& rCol, SCROW& rRow, SCTAB& rTab )
208cdf0e10cSrcweir {
209cdf0e10cSrcweir rCol = nCol;
210cdf0e10cSrcweir rRow = nRow;
211cdf0e10cSrcweir rTab = nTab;
212cdf0e10cSrcweir }
213cdf0e10cSrcweir
214cdf0e10cSrcweir
215cdf0e10cSrcweir //------------------------------------------------------------------------
216cdf0e10cSrcweir //------------------------------------------------------------------------
lcl_IterGetNumberFormat(sal_uLong & nFormat,const ScAttrArray * & rpArr,SCROW & nAttrEndRow,const ScAttrArray * pNewArr,SCROW nRow,ScDocument * pDoc)217cdf0e10cSrcweir void lcl_IterGetNumberFormat( sal_uLong& nFormat, const ScAttrArray*& rpArr,
218cdf0e10cSrcweir SCROW& nAttrEndRow, const ScAttrArray* pNewArr, SCROW nRow,
219cdf0e10cSrcweir ScDocument* pDoc )
220cdf0e10cSrcweir {
221cdf0e10cSrcweir if ( rpArr != pNewArr || nAttrEndRow < nRow )
222cdf0e10cSrcweir {
223cdf0e10cSrcweir SCSIZE nPos;
224cdf0e10cSrcweir pNewArr->Search( nRow, nPos ); // nPos 0 gueltig wenn nicht gefunden
225cdf0e10cSrcweir const ScPatternAttr* pPattern = pNewArr->pData[nPos].pPattern;
226cdf0e10cSrcweir nFormat = pPattern->GetNumberFormat( pDoc->GetFormatTable() );
227cdf0e10cSrcweir rpArr = pNewArr;
228cdf0e10cSrcweir nAttrEndRow = pNewArr->pData[nPos].nRow;
229cdf0e10cSrcweir }
230cdf0e10cSrcweir }
231cdf0e10cSrcweir
232cdf0e10cSrcweir //UNUSED2008-05 ScValueIterator::ScValueIterator( ScDocument* pDocument,
233cdf0e10cSrcweir //UNUSED2008-05 SCCOL nSCol, SCROW nSRow, SCTAB nSTab,
234cdf0e10cSrcweir //UNUSED2008-05 SCCOL nECol, SCROW nERow, SCTAB nETab,
235cdf0e10cSrcweir //UNUSED2008-05 sal_Bool bSTotal, sal_Bool bTextZero ) :
236cdf0e10cSrcweir //UNUSED2008-05 pDoc( pDocument ),
237cdf0e10cSrcweir //UNUSED2008-05 nNumFmtIndex(0),
238cdf0e10cSrcweir //UNUSED2008-05 nStartCol( nSCol),
239cdf0e10cSrcweir //UNUSED2008-05 nStartRow( nSRow),
240cdf0e10cSrcweir //UNUSED2008-05 nStartTab( nSTab ),
241cdf0e10cSrcweir //UNUSED2008-05 nEndCol( nECol ),
242cdf0e10cSrcweir //UNUSED2008-05 nEndRow( nERow),
243cdf0e10cSrcweir //UNUSED2008-05 nEndTab( nETab ),
244cdf0e10cSrcweir //UNUSED2008-05 nNumFmtType( NUMBERFORMAT_UNDEFINED ),
245cdf0e10cSrcweir //UNUSED2008-05 bNumValid( sal_False ),
246cdf0e10cSrcweir //UNUSED2008-05 bSubTotal(bSTotal),
247cdf0e10cSrcweir //UNUSED2008-05 bNextValid( sal_False ),
248cdf0e10cSrcweir //UNUSED2008-05 bCalcAsShown( pDocument->GetDocOptions().IsCalcAsShown() ),
249cdf0e10cSrcweir //UNUSED2008-05 bTextAsZero( bTextZero )
250cdf0e10cSrcweir //UNUSED2008-05 {
251cdf0e10cSrcweir //UNUSED2008-05 PutInOrder( nStartCol, nEndCol);
252cdf0e10cSrcweir //UNUSED2008-05 PutInOrder( nStartRow, nEndRow);
253cdf0e10cSrcweir //UNUSED2008-05 PutInOrder( nStartTab, nEndTab );
254cdf0e10cSrcweir //UNUSED2008-05
255cdf0e10cSrcweir //UNUSED2008-05 if (!ValidCol(nStartCol)) nStartCol = MAXCOL;
256cdf0e10cSrcweir //UNUSED2008-05 if (!ValidCol(nEndCol)) nEndCol = MAXCOL;
257cdf0e10cSrcweir //UNUSED2008-05 if (!ValidRow(nStartRow)) nStartRow = MAXROW;
258cdf0e10cSrcweir //UNUSED2008-05 if (!ValidRow(nEndRow)) nEndRow = MAXROW;
259cdf0e10cSrcweir //UNUSED2008-05 if (!ValidTab(nStartTab)) nStartTab = MAXTAB;
260cdf0e10cSrcweir //UNUSED2008-05 if (!ValidTab(nEndTab)) nEndTab = MAXTAB;
261cdf0e10cSrcweir //UNUSED2008-05
262cdf0e10cSrcweir //UNUSED2008-05 nCol = nStartCol;
263cdf0e10cSrcweir //UNUSED2008-05 nRow = nStartRow;
264cdf0e10cSrcweir //UNUSED2008-05 nTab = nStartTab;
265cdf0e10cSrcweir //UNUSED2008-05
266cdf0e10cSrcweir //UNUSED2008-05 nColRow = 0; // wird bei GetFirst initialisiert
267cdf0e10cSrcweir //UNUSED2008-05
268cdf0e10cSrcweir //UNUSED2008-05 nNumFormat = 0; // werden bei GetNumberFormat initialisiert
269cdf0e10cSrcweir //UNUSED2008-05 pAttrArray = 0;
270cdf0e10cSrcweir //UNUSED2008-05 nAttrEndRow = 0;
271cdf0e10cSrcweir //UNUSED2008-05 }
272cdf0e10cSrcweir
ScValueIterator(ScDocument * pDocument,const ScRange & rRange,sal_Bool bSTotal,sal_Bool bTextZero)273cdf0e10cSrcweir ScValueIterator::ScValueIterator( ScDocument* pDocument, const ScRange& rRange,
274cdf0e10cSrcweir sal_Bool bSTotal, sal_Bool bTextZero ) :
275cdf0e10cSrcweir pDoc( pDocument ),
276cdf0e10cSrcweir nNumFmtIndex(0),
277cdf0e10cSrcweir nStartCol( rRange.aStart.Col() ),
278cdf0e10cSrcweir nStartRow( rRange.aStart.Row() ),
279cdf0e10cSrcweir nStartTab( rRange.aStart.Tab() ),
280cdf0e10cSrcweir nEndCol( rRange.aEnd.Col() ),
281cdf0e10cSrcweir nEndRow( rRange.aEnd.Row() ),
282cdf0e10cSrcweir nEndTab( rRange.aEnd.Tab() ),
283cdf0e10cSrcweir nNumFmtType( NUMBERFORMAT_UNDEFINED ),
284cdf0e10cSrcweir bNumValid( sal_False ),
285cdf0e10cSrcweir bSubTotal(bSTotal),
286cdf0e10cSrcweir bNextValid( sal_False ),
287cdf0e10cSrcweir bCalcAsShown( pDocument->GetDocOptions().IsCalcAsShown() ),
288cdf0e10cSrcweir bTextAsZero( bTextZero )
289cdf0e10cSrcweir {
290cdf0e10cSrcweir PutInOrder( nStartCol, nEndCol);
291cdf0e10cSrcweir PutInOrder( nStartRow, nEndRow);
292cdf0e10cSrcweir PutInOrder( nStartTab, nEndTab );
293cdf0e10cSrcweir
294cdf0e10cSrcweir if (!ValidCol(nStartCol)) nStartCol = MAXCOL;
295cdf0e10cSrcweir if (!ValidCol(nEndCol)) nEndCol = MAXCOL;
296cdf0e10cSrcweir if (!ValidRow(nStartRow)) nStartRow = MAXROW;
297cdf0e10cSrcweir if (!ValidRow(nEndRow)) nEndRow = MAXROW;
298cdf0e10cSrcweir if (!ValidTab(nStartTab)) nStartTab = MAXTAB;
299cdf0e10cSrcweir if (!ValidTab(nEndTab)) nEndTab = MAXTAB;
300cdf0e10cSrcweir
301cdf0e10cSrcweir nCol = nStartCol;
302cdf0e10cSrcweir nRow = nStartRow;
303cdf0e10cSrcweir nTab = nStartTab;
304cdf0e10cSrcweir
305cdf0e10cSrcweir nColRow = 0; // wird bei GetFirst initialisiert
306cdf0e10cSrcweir
307cdf0e10cSrcweir nNumFormat = 0; // werden bei GetNumberFormat initialisiert
308cdf0e10cSrcweir pAttrArray = 0;
309cdf0e10cSrcweir nAttrEndRow = 0;
310cdf0e10cSrcweir }
311cdf0e10cSrcweir
GetThis(double & rValue,sal_uInt16 & rErr)312cdf0e10cSrcweir sal_Bool ScValueIterator::GetThis(double& rValue, sal_uInt16& rErr)
313cdf0e10cSrcweir {
314cdf0e10cSrcweir ScColumn* pCol = &(pDoc->pTab[nTab])->aCol[nCol];
315cdf0e10cSrcweir for (;;)
316cdf0e10cSrcweir {
317cdf0e10cSrcweir if ( nRow > nEndRow )
318cdf0e10cSrcweir {
319cdf0e10cSrcweir nRow = nStartRow;
320cdf0e10cSrcweir do
321cdf0e10cSrcweir {
322cdf0e10cSrcweir nCol++;
323cdf0e10cSrcweir if ( nCol > nEndCol )
324cdf0e10cSrcweir {
325cdf0e10cSrcweir nCol = nStartCol;
326cdf0e10cSrcweir nTab++;
327cdf0e10cSrcweir if ( nTab > nEndTab )
328cdf0e10cSrcweir {
329cdf0e10cSrcweir // rValue = 0.0; //! do not change caller's value!
330cdf0e10cSrcweir rErr = 0;
331cdf0e10cSrcweir return sal_False; // Ende und Aus
332cdf0e10cSrcweir }
333cdf0e10cSrcweir }
334cdf0e10cSrcweir pCol = &(pDoc->pTab[nTab])->aCol[nCol];
335cdf0e10cSrcweir } while ( pCol->nCount == 0 );
336cdf0e10cSrcweir pCol->Search( nRow, nColRow );
337cdf0e10cSrcweir }
338cdf0e10cSrcweir
339cdf0e10cSrcweir while (( nColRow < pCol->nCount ) && ( pCol->pItems[nColRow].nRow < nRow ))
340cdf0e10cSrcweir nColRow++;
341cdf0e10cSrcweir
342cdf0e10cSrcweir if ( nColRow < pCol->nCount && pCol->pItems[nColRow].nRow <= nEndRow )
343cdf0e10cSrcweir {
344cdf0e10cSrcweir nRow = pCol->pItems[nColRow].nRow + 1;
345cdf0e10cSrcweir if ( !bSubTotal || !pDoc->pTab[nTab]->RowFiltered( nRow-1 ) )
346cdf0e10cSrcweir {
347cdf0e10cSrcweir ScBaseCell* pCell = pCol->pItems[nColRow].pCell;
348cdf0e10cSrcweir ++nColRow;
349cdf0e10cSrcweir switch (pCell->GetCellType())
350cdf0e10cSrcweir {
351cdf0e10cSrcweir case CELLTYPE_VALUE:
352cdf0e10cSrcweir {
353cdf0e10cSrcweir bNumValid = sal_False;
354cdf0e10cSrcweir rValue = ((ScValueCell*)pCell)->GetValue();
355cdf0e10cSrcweir rErr = 0;
356cdf0e10cSrcweir --nRow;
357cdf0e10cSrcweir if ( bCalcAsShown )
358cdf0e10cSrcweir {
359cdf0e10cSrcweir lcl_IterGetNumberFormat( nNumFormat, pAttrArray,
360cdf0e10cSrcweir nAttrEndRow, pCol->pAttrArray, nRow, pDoc );
361cdf0e10cSrcweir rValue = pDoc->RoundValueAsShown( rValue, nNumFormat );
362cdf0e10cSrcweir }
363cdf0e10cSrcweir //
364cdf0e10cSrcweir // wenn in der selben Spalte gleich noch eine Value-Cell folgt, die
365cdf0e10cSrcweir // auch noch im Block liegt, den Wert jetzt schon holen
366cdf0e10cSrcweir //
367cdf0e10cSrcweir if ( nColRow < pCol->nCount &&
368cdf0e10cSrcweir pCol->pItems[nColRow].nRow <= nEndRow &&
369cdf0e10cSrcweir pCol->pItems[nColRow].pCell->GetCellType() == CELLTYPE_VALUE &&
370cdf0e10cSrcweir !bSubTotal )
371cdf0e10cSrcweir {
372cdf0e10cSrcweir fNextValue = ((ScValueCell*)pCol->pItems[nColRow].pCell)->GetValue();
373cdf0e10cSrcweir nNextRow = pCol->pItems[nColRow].nRow;
374cdf0e10cSrcweir bNextValid = sal_True;
375cdf0e10cSrcweir if ( bCalcAsShown )
376cdf0e10cSrcweir {
377cdf0e10cSrcweir lcl_IterGetNumberFormat( nNumFormat, pAttrArray,
378cdf0e10cSrcweir nAttrEndRow, pCol->pAttrArray, nNextRow, pDoc );
379cdf0e10cSrcweir fNextValue = pDoc->RoundValueAsShown( fNextValue, nNumFormat );
380cdf0e10cSrcweir }
381cdf0e10cSrcweir }
382cdf0e10cSrcweir
383cdf0e10cSrcweir return sal_True; // gefunden
384cdf0e10cSrcweir }
385cdf0e10cSrcweir // break;
386cdf0e10cSrcweir case CELLTYPE_FORMULA:
387cdf0e10cSrcweir {
388cdf0e10cSrcweir if (!bSubTotal || !((ScFormulaCell*)pCell)->IsSubTotal())
389cdf0e10cSrcweir {
390cdf0e10cSrcweir rErr = ((ScFormulaCell*)pCell)->GetErrCode();
391cdf0e10cSrcweir if ( rErr || ((ScFormulaCell*)pCell)->IsValue() )
392cdf0e10cSrcweir {
393cdf0e10cSrcweir rValue = ((ScFormulaCell*)pCell)->GetValue();
394cdf0e10cSrcweir nRow--;
395cdf0e10cSrcweir bNumValid = sal_False;
396cdf0e10cSrcweir return sal_True; // gefunden
397cdf0e10cSrcweir }
398cdf0e10cSrcweir else if ( bTextAsZero )
399cdf0e10cSrcweir {
400cdf0e10cSrcweir rValue = 0.0;
401cdf0e10cSrcweir nRow--;
402cdf0e10cSrcweir bNumValid = sal_False;
403cdf0e10cSrcweir return sal_True;
404cdf0e10cSrcweir }
405cdf0e10cSrcweir }
406cdf0e10cSrcweir }
407cdf0e10cSrcweir break;
408cdf0e10cSrcweir case CELLTYPE_STRING :
409cdf0e10cSrcweir case CELLTYPE_EDIT :
410cdf0e10cSrcweir {
411cdf0e10cSrcweir if ( bTextAsZero )
412cdf0e10cSrcweir {
413cdf0e10cSrcweir rErr = 0;
414cdf0e10cSrcweir rValue = 0.0;
415cdf0e10cSrcweir nNumFmtType = NUMBERFORMAT_NUMBER;
416cdf0e10cSrcweir nNumFmtIndex = 0;
417cdf0e10cSrcweir bNumValid = sal_True;
418cdf0e10cSrcweir --nRow;
419cdf0e10cSrcweir return sal_True;
420cdf0e10cSrcweir }
421cdf0e10cSrcweir }
422cdf0e10cSrcweir break;
423cdf0e10cSrcweir default:
424cdf0e10cSrcweir {
425cdf0e10cSrcweir // added to avoid warnings
426cdf0e10cSrcweir }
427cdf0e10cSrcweir }
428cdf0e10cSrcweir }
429cdf0e10cSrcweir }
430cdf0e10cSrcweir else
431cdf0e10cSrcweir nRow = nEndRow + 1; // naechste Spalte
432cdf0e10cSrcweir }
433cdf0e10cSrcweir }
434cdf0e10cSrcweir
GetCurNumFmtInfo(short & nType,sal_uLong & nIndex)435cdf0e10cSrcweir void ScValueIterator::GetCurNumFmtInfo( short& nType, sal_uLong& nIndex )
436cdf0e10cSrcweir {
437cdf0e10cSrcweir if (!bNumValid)
438cdf0e10cSrcweir {
439cdf0e10cSrcweir const ScColumn* pCol = &(pDoc->pTab[nTab])->aCol[nCol];
440cdf0e10cSrcweir nNumFmtIndex = pCol->GetNumberFormat( nRow );
441cdf0e10cSrcweir if ( (nNumFmtIndex % SV_COUNTRY_LANGUAGE_OFFSET) == 0 )
442cdf0e10cSrcweir {
443cdf0e10cSrcweir const ScBaseCell* pCell;
444cdf0e10cSrcweir SCSIZE nIdx = nColRow - 1;
445cdf0e10cSrcweir // there might be rearranged something, so be on the safe side
446cdf0e10cSrcweir if ( nIdx < pCol->nCount && pCol->pItems[nIdx].nRow == nRow )
447cdf0e10cSrcweir pCell = pCol->pItems[nIdx].pCell;
448cdf0e10cSrcweir else
449cdf0e10cSrcweir {
450cdf0e10cSrcweir if ( pCol->Search( nRow, nIdx ) )
451cdf0e10cSrcweir pCell = pCol->pItems[nIdx].pCell;
452cdf0e10cSrcweir else
453cdf0e10cSrcweir pCell = NULL;
454cdf0e10cSrcweir }
455cdf0e10cSrcweir if ( pCell && pCell->GetCellType() == CELLTYPE_FORMULA )
456cdf0e10cSrcweir ((const ScFormulaCell*)pCell)->GetFormatInfo( nNumFmtType, nNumFmtIndex );
457cdf0e10cSrcweir else
458cdf0e10cSrcweir nNumFmtType = pDoc->GetFormatTable()->GetType( nNumFmtIndex );
459cdf0e10cSrcweir }
460cdf0e10cSrcweir else
461cdf0e10cSrcweir nNumFmtType = pDoc->GetFormatTable()->GetType( nNumFmtIndex );
462cdf0e10cSrcweir bNumValid = sal_True;
463cdf0e10cSrcweir }
464cdf0e10cSrcweir nType = nNumFmtType;
465cdf0e10cSrcweir nIndex = nNumFmtIndex;
466cdf0e10cSrcweir }
467cdf0e10cSrcweir
GetFirst(double & rValue,sal_uInt16 & rErr)468cdf0e10cSrcweir sal_Bool ScValueIterator::GetFirst(double& rValue, sal_uInt16& rErr)
469cdf0e10cSrcweir {
470cdf0e10cSrcweir nCol = nStartCol;
471cdf0e10cSrcweir nRow = nStartRow;
472cdf0e10cSrcweir nTab = nStartTab;
473cdf0e10cSrcweir
474cdf0e10cSrcweir // nColRow = 0;
475cdf0e10cSrcweir ScColumn* pCol = &(pDoc->pTab[nTab])->aCol[nCol];
476cdf0e10cSrcweir pCol->Search( nRow, nColRow );
477cdf0e10cSrcweir
478cdf0e10cSrcweir nNumFormat = 0; // werden bei GetNumberFormat initialisiert
479cdf0e10cSrcweir pAttrArray = 0;
480cdf0e10cSrcweir nAttrEndRow = 0;
481cdf0e10cSrcweir
482cdf0e10cSrcweir return GetThis(rValue, rErr);
483cdf0e10cSrcweir }
484cdf0e10cSrcweir
485cdf0e10cSrcweir /* ist inline:
486cdf0e10cSrcweir sal_Bool ScValueIterator::GetNext(double& rValue, sal_uInt16& rErr)
487cdf0e10cSrcweir {
488cdf0e10cSrcweir ++nRow;
489cdf0e10cSrcweir return GetThis(rValue, rErr);
490cdf0e10cSrcweir }
491cdf0e10cSrcweir */
492cdf0e10cSrcweir
493cdf0e10cSrcweir // ============================================================================
494cdf0e10cSrcweir
DataAccess(const ScDBQueryDataIterator * pParent)495cdf0e10cSrcweir ScDBQueryDataIterator::DataAccess::DataAccess(const ScDBQueryDataIterator* pParent) :
496cdf0e10cSrcweir mpParent(pParent)
497cdf0e10cSrcweir {
498cdf0e10cSrcweir }
499cdf0e10cSrcweir
~DataAccess()500cdf0e10cSrcweir ScDBQueryDataIterator::DataAccess::~DataAccess()
501cdf0e10cSrcweir {
502cdf0e10cSrcweir }
503cdf0e10cSrcweir
GetRowByColEntryIndex(ScDocument & rDoc,SCTAB nTab,SCCOL nCol,SCSIZE nColRow)504cdf0e10cSrcweir SCROW ScDBQueryDataIterator::GetRowByColEntryIndex(ScDocument& rDoc, SCTAB nTab, SCCOL nCol, SCSIZE nColRow)
505cdf0e10cSrcweir {
506cdf0e10cSrcweir ScColumn* pCol = &rDoc.pTab[nTab]->aCol[nCol];
507cdf0e10cSrcweir return pCol->pItems[nColRow].nRow;
508cdf0e10cSrcweir }
509cdf0e10cSrcweir
GetCellByColEntryIndex(ScDocument & rDoc,SCTAB nTab,SCCOL nCol,SCSIZE nColRow)510cdf0e10cSrcweir ScBaseCell* ScDBQueryDataIterator::GetCellByColEntryIndex(ScDocument& rDoc, SCTAB nTab, SCCOL nCol, SCSIZE nColRow)
511cdf0e10cSrcweir {
512cdf0e10cSrcweir ScColumn* pCol = &rDoc.pTab[nTab]->aCol[nCol];
513cdf0e10cSrcweir return pCol->pItems[nColRow].pCell;
514cdf0e10cSrcweir }
515cdf0e10cSrcweir
GetAttrArrayByCol(ScDocument & rDoc,SCTAB nTab,SCCOL nCol)516cdf0e10cSrcweir ScAttrArray* ScDBQueryDataIterator::GetAttrArrayByCol(ScDocument& rDoc, SCTAB nTab, SCCOL nCol)
517cdf0e10cSrcweir {
518cdf0e10cSrcweir ScColumn* pCol = &rDoc.pTab[nTab]->aCol[nCol];
519cdf0e10cSrcweir return pCol->pAttrArray;
520cdf0e10cSrcweir }
521cdf0e10cSrcweir
IsQueryValid(ScDocument & rDoc,const ScQueryParam & rParam,SCTAB nTab,SCROW nRow,ScBaseCell * pCell)522cdf0e10cSrcweir bool ScDBQueryDataIterator::IsQueryValid(ScDocument& rDoc, const ScQueryParam& rParam, SCTAB nTab, SCROW nRow, ScBaseCell* pCell)
523cdf0e10cSrcweir {
524cdf0e10cSrcweir return rDoc.pTab[nTab]->ValidQuery(nRow, rParam, NULL, pCell);
525cdf0e10cSrcweir }
526cdf0e10cSrcweir
SearchColEntryIndex(ScDocument & rDoc,SCTAB nTab,SCROW nRow,SCCOL nCol)527cdf0e10cSrcweir SCSIZE ScDBQueryDataIterator::SearchColEntryIndex(ScDocument& rDoc, SCTAB nTab, SCROW nRow, SCCOL nCol)
528cdf0e10cSrcweir {
529cdf0e10cSrcweir ScColumn* pCol = &rDoc.pTab[nTab]->aCol[nCol];
530cdf0e10cSrcweir SCSIZE nColRow;
531cdf0e10cSrcweir pCol->Search(nRow, nColRow);
532cdf0e10cSrcweir return nColRow;
533cdf0e10cSrcweir }
534cdf0e10cSrcweir
535cdf0e10cSrcweir // ----------------------------------------------------------------------------
536cdf0e10cSrcweir
DataAccessInternal(const ScDBQueryDataIterator * pParent,ScDBQueryParamInternal * pParam,ScDocument * pDoc)537cdf0e10cSrcweir ScDBQueryDataIterator::DataAccessInternal::DataAccessInternal(const ScDBQueryDataIterator* pParent, ScDBQueryParamInternal* pParam, ScDocument* pDoc) :
538cdf0e10cSrcweir DataAccess(pParent),
539cdf0e10cSrcweir mpParam(pParam),
540cdf0e10cSrcweir mpDoc(pDoc),
541cdf0e10cSrcweir bCalcAsShown( pDoc->GetDocOptions().IsCalcAsShown() )
542cdf0e10cSrcweir {
543cdf0e10cSrcweir nCol = mpParam->mnField;
544cdf0e10cSrcweir nRow = mpParam->nRow1;
545cdf0e10cSrcweir nTab = mpParam->nTab;
546cdf0e10cSrcweir
547cdf0e10cSrcweir nColRow = 0; // wird bei GetFirst initialisiert
548cdf0e10cSrcweir SCSIZE i;
549cdf0e10cSrcweir SCSIZE nCount = mpParam->GetEntryCount();
550cdf0e10cSrcweir for (i=0; (i<nCount) && (mpParam->GetEntry(i).bDoQuery); i++)
551cdf0e10cSrcweir {
552cdf0e10cSrcweir ScQueryEntry& rEntry = mpParam->GetEntry(i);
553cdf0e10cSrcweir sal_uInt32 nIndex = 0;
554cdf0e10cSrcweir rEntry.bQueryByString =
555cdf0e10cSrcweir !(mpDoc->GetFormatTable()->IsNumberFormat(*rEntry.pStr, nIndex, rEntry.nVal));
556cdf0e10cSrcweir }
557cdf0e10cSrcweir nNumFormat = 0; // werden bei GetNumberFormat initialisiert
558cdf0e10cSrcweir pAttrArray = 0;
559cdf0e10cSrcweir nAttrEndRow = 0;
560cdf0e10cSrcweir }
561cdf0e10cSrcweir
~DataAccessInternal()562cdf0e10cSrcweir ScDBQueryDataIterator::DataAccessInternal::~DataAccessInternal()
563cdf0e10cSrcweir {
564cdf0e10cSrcweir }
565cdf0e10cSrcweir
getCurrent(Value & rValue)566cdf0e10cSrcweir bool ScDBQueryDataIterator::DataAccessInternal::getCurrent(Value& rValue)
567cdf0e10cSrcweir {
568cdf0e10cSrcweir SCCOLROW nFirstQueryField = mpParam->GetEntry(0).nField;
569cdf0e10cSrcweir for ( ;; )
570cdf0e10cSrcweir {
571cdf0e10cSrcweir if (nRow > mpParam->nRow2)
572cdf0e10cSrcweir {
573cdf0e10cSrcweir // Bottom of the range reached. Bail out.
574cdf0e10cSrcweir rValue.mnError = 0;
575cdf0e10cSrcweir return false;
576cdf0e10cSrcweir }
577cdf0e10cSrcweir
578cdf0e10cSrcweir SCSIZE nCellCount = mpDoc->GetCellCount(nTab, nCol);
579cdf0e10cSrcweir SCROW nThisRow = ScDBQueryDataIterator::GetRowByColEntryIndex(*mpDoc, nTab, nCol, nColRow);
580cdf0e10cSrcweir while ( (nColRow < nCellCount) && (nThisRow < nRow) )
581cdf0e10cSrcweir nThisRow = ScDBQueryDataIterator::GetRowByColEntryIndex(*mpDoc, nTab, nCol, ++nColRow);
582cdf0e10cSrcweir
583cdf0e10cSrcweir if ( nColRow < nCellCount && nThisRow <= mpParam->nRow2 )
584cdf0e10cSrcweir {
585cdf0e10cSrcweir nRow = nThisRow;
586cdf0e10cSrcweir ScBaseCell* pCell = NULL;
587cdf0e10cSrcweir if (nCol == static_cast<SCCOL>(nFirstQueryField))
588cdf0e10cSrcweir pCell = ScDBQueryDataIterator::GetCellByColEntryIndex(*mpDoc, nTab, nCol, nColRow);
589cdf0e10cSrcweir
590cdf0e10cSrcweir if (ScDBQueryDataIterator::IsQueryValid(*mpDoc, *mpParam, nTab, nRow, pCell))
591cdf0e10cSrcweir {
592cdf0e10cSrcweir // #i109812# get cell here if it wasn't done above
593cdf0e10cSrcweir if (nCol != static_cast<SCCOL>(nFirstQueryField))
594cdf0e10cSrcweir pCell = ScDBQueryDataIterator::GetCellByColEntryIndex(*mpDoc, nTab, nCol, nColRow);
595cdf0e10cSrcweir
596cdf0e10cSrcweir switch (pCell ? pCell->GetCellType() : CELLTYPE_NONE)
597cdf0e10cSrcweir {
598cdf0e10cSrcweir case CELLTYPE_VALUE:
599cdf0e10cSrcweir {
600cdf0e10cSrcweir rValue.mfValue = ((ScValueCell*)pCell)->GetValue();
601cdf0e10cSrcweir rValue.mbIsNumber = true;
602cdf0e10cSrcweir if ( bCalcAsShown )
603cdf0e10cSrcweir {
604cdf0e10cSrcweir const ScAttrArray* pNewAttrArray =
605cdf0e10cSrcweir ScDBQueryDataIterator::GetAttrArrayByCol(*mpDoc, nTab, nCol);
606cdf0e10cSrcweir lcl_IterGetNumberFormat( nNumFormat, pAttrArray,
607cdf0e10cSrcweir nAttrEndRow, pNewAttrArray, nRow, mpDoc );
608cdf0e10cSrcweir rValue.mfValue = mpDoc->RoundValueAsShown( rValue.mfValue, nNumFormat );
609cdf0e10cSrcweir }
610cdf0e10cSrcweir nNumFmtType = NUMBERFORMAT_NUMBER;
611cdf0e10cSrcweir nNumFmtIndex = 0;
612cdf0e10cSrcweir rValue.mnError = 0;
613cdf0e10cSrcweir return sal_True; // gefunden
614cdf0e10cSrcweir }
615cdf0e10cSrcweir // break;
616cdf0e10cSrcweir case CELLTYPE_FORMULA:
617cdf0e10cSrcweir {
618cdf0e10cSrcweir if (((ScFormulaCell*)pCell)->IsValue())
619cdf0e10cSrcweir {
620cdf0e10cSrcweir rValue.mfValue = ((ScFormulaCell*)pCell)->GetValue();
621cdf0e10cSrcweir rValue.mbIsNumber = true;
622cdf0e10cSrcweir mpDoc->GetNumberFormatInfo( nNumFmtType,
623cdf0e10cSrcweir nNumFmtIndex, ScAddress( nCol, nRow, nTab ),
624cdf0e10cSrcweir pCell );
625cdf0e10cSrcweir rValue.mnError = ((ScFormulaCell*)pCell)->GetErrCode();
626cdf0e10cSrcweir return sal_True; // gefunden
627cdf0e10cSrcweir }
628cdf0e10cSrcweir else
629*f689a31bSAndrea Pescetti {
630*f689a31bSAndrea Pescetti if (mpParam->mbSkipString)
631*f689a31bSAndrea Pescetti ++nRow;
632*f689a31bSAndrea Pescetti else
633*f689a31bSAndrea Pescetti {
634*f689a31bSAndrea Pescetti rValue.maString = ((ScFormulaCell*)pCell)->GetStringData();
635*f689a31bSAndrea Pescetti rValue.mbIsNumber = false;
636*f689a31bSAndrea Pescetti rValue.mnError = ((ScFormulaCell*)pCell)->GetErrCode();
637*f689a31bSAndrea Pescetti return sal_True;
638*f689a31bSAndrea Pescetti }
639*f689a31bSAndrea Pescetti }
640cdf0e10cSrcweir }
641cdf0e10cSrcweir break;
642cdf0e10cSrcweir case CELLTYPE_STRING:
643cdf0e10cSrcweir case CELLTYPE_EDIT:
644cdf0e10cSrcweir if (mpParam->mbSkipString)
645cdf0e10cSrcweir ++nRow;
646cdf0e10cSrcweir else
647cdf0e10cSrcweir {
648cdf0e10cSrcweir rValue.maString = pCell->GetStringData();
649cdf0e10cSrcweir rValue.mfValue = 0.0;
650cdf0e10cSrcweir rValue.mnError = 0;
651cdf0e10cSrcweir rValue.mbIsNumber = false;
652cdf0e10cSrcweir return true;
653cdf0e10cSrcweir }
654cdf0e10cSrcweir break;
655cdf0e10cSrcweir default:
656cdf0e10cSrcweir nRow++;
657cdf0e10cSrcweir break;
658cdf0e10cSrcweir }
659cdf0e10cSrcweir }
660cdf0e10cSrcweir else
661cdf0e10cSrcweir nRow++;
662cdf0e10cSrcweir }
663cdf0e10cSrcweir else
664cdf0e10cSrcweir nRow = mpParam->nRow2 + 1; // Naechste Spalte
665cdf0e10cSrcweir }
666cdf0e10cSrcweir // statement unreachable
667cdf0e10cSrcweir // return false;
668cdf0e10cSrcweir }
669cdf0e10cSrcweir
getFirst(Value & rValue)670cdf0e10cSrcweir bool ScDBQueryDataIterator::DataAccessInternal::getFirst(Value& rValue)
671cdf0e10cSrcweir {
672cdf0e10cSrcweir if (mpParam->bHasHeader)
673cdf0e10cSrcweir nRow++;
674cdf0e10cSrcweir
675cdf0e10cSrcweir nColRow = ScDBQueryDataIterator::SearchColEntryIndex(*mpDoc, nTab, nRow, nCol);
676cdf0e10cSrcweir return getCurrent(rValue);
677cdf0e10cSrcweir }
678cdf0e10cSrcweir
getNext(Value & rValue)679cdf0e10cSrcweir bool ScDBQueryDataIterator::DataAccessInternal::getNext(Value& rValue)
680cdf0e10cSrcweir {
681cdf0e10cSrcweir ++nRow;
682cdf0e10cSrcweir return getCurrent(rValue);
683cdf0e10cSrcweir }
684cdf0e10cSrcweir
685cdf0e10cSrcweir // ----------------------------------------------------------------------------
686cdf0e10cSrcweir
DataAccessMatrix(const ScDBQueryDataIterator * pParent,ScDBQueryParamMatrix * pParam)687cdf0e10cSrcweir ScDBQueryDataIterator::DataAccessMatrix::DataAccessMatrix(const ScDBQueryDataIterator* pParent, ScDBQueryParamMatrix* pParam) :
688cdf0e10cSrcweir DataAccess(pParent),
689cdf0e10cSrcweir mpParam(pParam)
690cdf0e10cSrcweir {
691cdf0e10cSrcweir SCSIZE nC, nR;
692cdf0e10cSrcweir mpParam->mpMatrix->GetDimensions(nC, nR);
693cdf0e10cSrcweir mnRows = static_cast<SCROW>(nR);
694cdf0e10cSrcweir mnCols = static_cast<SCCOL>(nC);
695cdf0e10cSrcweir }
696cdf0e10cSrcweir
~DataAccessMatrix()697cdf0e10cSrcweir ScDBQueryDataIterator::DataAccessMatrix::~DataAccessMatrix()
698cdf0e10cSrcweir {
699cdf0e10cSrcweir }
700cdf0e10cSrcweir
getCurrent(Value & rValue)701cdf0e10cSrcweir bool ScDBQueryDataIterator::DataAccessMatrix::getCurrent(Value& rValue)
702cdf0e10cSrcweir {
703cdf0e10cSrcweir // Starting from row == mnCurRow, get the first row that satisfies all the
704cdf0e10cSrcweir // query parameters.
705cdf0e10cSrcweir for ( ;mnCurRow < mnRows; ++mnCurRow)
706cdf0e10cSrcweir {
707cdf0e10cSrcweir const ScMatrix& rMat = *mpParam->mpMatrix;
708cdf0e10cSrcweir if (rMat.IsEmpty(mpParam->mnField, mnCurRow))
709cdf0e10cSrcweir // Don't take empty values into account.
710cdf0e10cSrcweir continue;
711cdf0e10cSrcweir
712cdf0e10cSrcweir bool bIsStrVal = rMat.IsString(mpParam->mnField, mnCurRow);
713cdf0e10cSrcweir if (bIsStrVal && mpParam->mbSkipString)
714cdf0e10cSrcweir continue;
715cdf0e10cSrcweir
716cdf0e10cSrcweir if (isValidQuery(mnCurRow, rMat))
717cdf0e10cSrcweir {
718cdf0e10cSrcweir rValue.maString = rMat.GetString(mpParam->mnField, mnCurRow);
719cdf0e10cSrcweir rValue.mfValue = rMat.GetDouble(mpParam->mnField, mnCurRow);
720cdf0e10cSrcweir rValue.mbIsNumber = !bIsStrVal;
721cdf0e10cSrcweir rValue.mnError = 0;
722cdf0e10cSrcweir return true;
723cdf0e10cSrcweir }
724cdf0e10cSrcweir }
725cdf0e10cSrcweir return false;
726cdf0e10cSrcweir }
727cdf0e10cSrcweir
getFirst(Value & rValue)728cdf0e10cSrcweir bool ScDBQueryDataIterator::DataAccessMatrix::getFirst(Value& rValue)
729cdf0e10cSrcweir {
730cdf0e10cSrcweir mnCurRow = mpParam->bHasHeader ? 1 : 0;
731cdf0e10cSrcweir return getCurrent(rValue);
732cdf0e10cSrcweir }
733cdf0e10cSrcweir
getNext(Value & rValue)734cdf0e10cSrcweir bool ScDBQueryDataIterator::DataAccessMatrix::getNext(Value& rValue)
735cdf0e10cSrcweir {
736cdf0e10cSrcweir ++mnCurRow;
737cdf0e10cSrcweir return getCurrent(rValue);
738cdf0e10cSrcweir }
739cdf0e10cSrcweir
740cdf0e10cSrcweir namespace {
741cdf0e10cSrcweir
lcl_isQueryByValue(const ScQueryEntry & rEntry,const ScMatrix & rMat,SCSIZE nCol,SCSIZE nRow)742cdf0e10cSrcweir bool lcl_isQueryByValue(const ScQueryEntry& rEntry, const ScMatrix& rMat, SCSIZE nCol, SCSIZE nRow)
743cdf0e10cSrcweir {
744cdf0e10cSrcweir if (rEntry.bQueryByString)
745cdf0e10cSrcweir return false;
746cdf0e10cSrcweir
747cdf0e10cSrcweir if (!rMat.IsValueOrEmpty(nCol, nRow))
748cdf0e10cSrcweir return false;
749cdf0e10cSrcweir
750cdf0e10cSrcweir return true;
751cdf0e10cSrcweir }
752cdf0e10cSrcweir
lcl_isQueryByString(const ScQueryEntry & rEntry,const ScMatrix & rMat,SCSIZE nCol,SCSIZE nRow)753cdf0e10cSrcweir bool lcl_isQueryByString(const ScQueryEntry& rEntry, const ScMatrix& rMat, SCSIZE nCol, SCSIZE nRow)
754cdf0e10cSrcweir {
755cdf0e10cSrcweir switch (rEntry.eOp)
756cdf0e10cSrcweir {
757cdf0e10cSrcweir case SC_EQUAL:
758cdf0e10cSrcweir case SC_NOT_EQUAL:
759cdf0e10cSrcweir case SC_CONTAINS:
760cdf0e10cSrcweir case SC_DOES_NOT_CONTAIN:
761cdf0e10cSrcweir case SC_BEGINS_WITH:
762cdf0e10cSrcweir case SC_ENDS_WITH:
763cdf0e10cSrcweir case SC_DOES_NOT_BEGIN_WITH:
764cdf0e10cSrcweir case SC_DOES_NOT_END_WITH:
765cdf0e10cSrcweir return true;
766cdf0e10cSrcweir default:
767cdf0e10cSrcweir ;
768cdf0e10cSrcweir }
769cdf0e10cSrcweir
770cdf0e10cSrcweir if (rEntry.bQueryByString && rMat.IsString(nCol, nRow))
771cdf0e10cSrcweir return true;
772cdf0e10cSrcweir
773cdf0e10cSrcweir return false;
774cdf0e10cSrcweir }
775cdf0e10cSrcweir
776cdf0e10cSrcweir }
777cdf0e10cSrcweir
isValidQuery(SCROW nRow,const ScMatrix & rMat) const778cdf0e10cSrcweir bool ScDBQueryDataIterator::DataAccessMatrix::isValidQuery(SCROW nRow, const ScMatrix& rMat) const
779cdf0e10cSrcweir {
780cdf0e10cSrcweir SCSIZE nEntryCount = mpParam->GetEntryCount();
781cdf0e10cSrcweir vector<bool> aResults;
782cdf0e10cSrcweir aResults.reserve(nEntryCount);
783cdf0e10cSrcweir
784cdf0e10cSrcweir const CollatorWrapper& rCollator =
785cdf0e10cSrcweir mpParam->bCaseSens ? *ScGlobal::GetCaseCollator() : *ScGlobal::GetCollator();
786cdf0e10cSrcweir
787cdf0e10cSrcweir for (SCSIZE i = 0; i < nEntryCount; ++i)
788cdf0e10cSrcweir {
789cdf0e10cSrcweir const ScQueryEntry& rEntry = mpParam->GetEntry(i);
790cdf0e10cSrcweir if (!rEntry.bDoQuery)
791cdf0e10cSrcweir continue;
792cdf0e10cSrcweir
793cdf0e10cSrcweir switch (rEntry.eOp)
794cdf0e10cSrcweir {
795cdf0e10cSrcweir case SC_EQUAL:
796cdf0e10cSrcweir case SC_LESS:
797cdf0e10cSrcweir case SC_GREATER:
798cdf0e10cSrcweir case SC_LESS_EQUAL:
799cdf0e10cSrcweir case SC_GREATER_EQUAL:
800cdf0e10cSrcweir case SC_NOT_EQUAL:
801cdf0e10cSrcweir break;
802cdf0e10cSrcweir default:
803cdf0e10cSrcweir // Only the above operators are supported.
804cdf0e10cSrcweir continue;
805cdf0e10cSrcweir }
806cdf0e10cSrcweir
807cdf0e10cSrcweir bool bValid = false;
808cdf0e10cSrcweir
809cdf0e10cSrcweir SCSIZE nField = static_cast<SCSIZE>(rEntry.nField);
810cdf0e10cSrcweir if (lcl_isQueryByValue(rEntry, rMat, nField, nRow))
811cdf0e10cSrcweir {
812cdf0e10cSrcweir // By value
813cdf0e10cSrcweir double fMatVal = rMat.GetDouble(nField, nRow);
814cdf0e10cSrcweir bool bEqual = approxEqual(fMatVal, rEntry.nVal);
815cdf0e10cSrcweir switch (rEntry.eOp)
816cdf0e10cSrcweir {
817cdf0e10cSrcweir case SC_EQUAL:
818cdf0e10cSrcweir bValid = bEqual;
819cdf0e10cSrcweir break;
820cdf0e10cSrcweir case SC_LESS:
821cdf0e10cSrcweir bValid = (fMatVal < rEntry.nVal) && !bEqual;
822cdf0e10cSrcweir break;
823cdf0e10cSrcweir case SC_GREATER:
824cdf0e10cSrcweir bValid = (fMatVal > rEntry.nVal) && !bEqual;
825cdf0e10cSrcweir break;
826cdf0e10cSrcweir case SC_LESS_EQUAL:
827cdf0e10cSrcweir bValid = (fMatVal < rEntry.nVal) || bEqual;
828cdf0e10cSrcweir break;
829cdf0e10cSrcweir case SC_GREATER_EQUAL:
830cdf0e10cSrcweir bValid = (fMatVal > rEntry.nVal) || bEqual;
831cdf0e10cSrcweir break;
832cdf0e10cSrcweir case SC_NOT_EQUAL:
833cdf0e10cSrcweir bValid = !bEqual;
834cdf0e10cSrcweir break;
835cdf0e10cSrcweir default:
836cdf0e10cSrcweir ;
837cdf0e10cSrcweir }
838cdf0e10cSrcweir }
839cdf0e10cSrcweir else if (lcl_isQueryByString(rEntry, rMat, nField, nRow))
840cdf0e10cSrcweir {
841cdf0e10cSrcweir // By string
842cdf0e10cSrcweir do
843cdf0e10cSrcweir {
844cdf0e10cSrcweir if (!rEntry.pStr)
845cdf0e10cSrcweir break;
846cdf0e10cSrcweir
847cdf0e10cSrcweir // Equality check first.
848cdf0e10cSrcweir
849cdf0e10cSrcweir OUString aMatStr = rMat.GetString(nField, nRow);
850cdf0e10cSrcweir lcl_toUpper(aMatStr);
851cdf0e10cSrcweir OUString aQueryStr = *rEntry.pStr;
852cdf0e10cSrcweir lcl_toUpper(aQueryStr);
853cdf0e10cSrcweir bool bDone = false;
854cdf0e10cSrcweir switch (rEntry.eOp)
855cdf0e10cSrcweir {
856cdf0e10cSrcweir case SC_EQUAL:
857cdf0e10cSrcweir bValid = aMatStr.equals(aQueryStr);
858cdf0e10cSrcweir bDone = true;
859cdf0e10cSrcweir break;
860cdf0e10cSrcweir case SC_NOT_EQUAL:
861cdf0e10cSrcweir bValid = !aMatStr.equals(aQueryStr);
862cdf0e10cSrcweir bDone = true;
863cdf0e10cSrcweir break;
864cdf0e10cSrcweir default:
865cdf0e10cSrcweir ;
866cdf0e10cSrcweir }
867cdf0e10cSrcweir
868cdf0e10cSrcweir if (bDone)
869cdf0e10cSrcweir break;
870cdf0e10cSrcweir
871cdf0e10cSrcweir // Unequality check using collator.
872cdf0e10cSrcweir
873cdf0e10cSrcweir sal_Int32 nCompare = rCollator.compareString(aMatStr, aQueryStr);
874cdf0e10cSrcweir switch (rEntry.eOp)
875cdf0e10cSrcweir {
876cdf0e10cSrcweir case SC_LESS :
877cdf0e10cSrcweir bValid = (nCompare < 0);
878cdf0e10cSrcweir break;
879cdf0e10cSrcweir case SC_GREATER :
880cdf0e10cSrcweir bValid = (nCompare > 0);
881cdf0e10cSrcweir break;
882cdf0e10cSrcweir case SC_LESS_EQUAL :
883cdf0e10cSrcweir bValid = (nCompare <= 0);
884cdf0e10cSrcweir break;
885cdf0e10cSrcweir case SC_GREATER_EQUAL :
886cdf0e10cSrcweir bValid = (nCompare >= 0);
887cdf0e10cSrcweir break;
888cdf0e10cSrcweir default:
889cdf0e10cSrcweir ;
890cdf0e10cSrcweir }
891cdf0e10cSrcweir }
892cdf0e10cSrcweir while (false);
893cdf0e10cSrcweir }
894cdf0e10cSrcweir else if (mpParam->bMixedComparison)
895cdf0e10cSrcweir {
896cdf0e10cSrcweir // Not used at the moment.
897cdf0e10cSrcweir }
898cdf0e10cSrcweir
899cdf0e10cSrcweir if (aResults.empty())
900cdf0e10cSrcweir // First query entry.
901cdf0e10cSrcweir aResults.push_back(bValid);
902cdf0e10cSrcweir else if (rEntry.eConnect == SC_AND)
903cdf0e10cSrcweir {
904cdf0e10cSrcweir // For AND op, tuck the result into the last result value.
905cdf0e10cSrcweir size_t n = aResults.size();
906cdf0e10cSrcweir aResults[n-1] = aResults[n-1] && bValid;
907cdf0e10cSrcweir }
908cdf0e10cSrcweir else
909cdf0e10cSrcweir // For OR op, store its own result.
910cdf0e10cSrcweir aResults.push_back(bValid);
911cdf0e10cSrcweir }
912cdf0e10cSrcweir
913cdf0e10cSrcweir // Row is valid as long as there is at least one result being true.
914cdf0e10cSrcweir vector<bool>::const_iterator itr = aResults.begin(), itrEnd = aResults.end();
915cdf0e10cSrcweir for (; itr != itrEnd; ++itr)
916cdf0e10cSrcweir if (*itr)
917cdf0e10cSrcweir return true;
918cdf0e10cSrcweir
919cdf0e10cSrcweir return false;
920cdf0e10cSrcweir }
921cdf0e10cSrcweir
922cdf0e10cSrcweir // ----------------------------------------------------------------------------
923cdf0e10cSrcweir
Value()924cdf0e10cSrcweir ScDBQueryDataIterator::Value::Value() :
925cdf0e10cSrcweir mnError(0), mbIsNumber(true)
926cdf0e10cSrcweir {
927cdf0e10cSrcweir ::rtl::math::setNan(&mfValue);
928cdf0e10cSrcweir }
929cdf0e10cSrcweir
930cdf0e10cSrcweir // ----------------------------------------------------------------------------
931cdf0e10cSrcweir
ScDBQueryDataIterator(ScDocument * pDocument,ScDBQueryParamBase * pParam)932cdf0e10cSrcweir ScDBQueryDataIterator::ScDBQueryDataIterator(ScDocument* pDocument, ScDBQueryParamBase* pParam) :
933cdf0e10cSrcweir mpParam (pParam)
934cdf0e10cSrcweir {
935cdf0e10cSrcweir switch (mpParam->GetType())
936cdf0e10cSrcweir {
937cdf0e10cSrcweir case ScDBQueryParamBase::INTERNAL:
938cdf0e10cSrcweir {
939cdf0e10cSrcweir ScDBQueryParamInternal* p = static_cast<ScDBQueryParamInternal*>(pParam);
940cdf0e10cSrcweir mpData.reset(new DataAccessInternal(this, p, pDocument));
941cdf0e10cSrcweir }
942cdf0e10cSrcweir break;
943cdf0e10cSrcweir case ScDBQueryParamBase::MATRIX:
944cdf0e10cSrcweir {
945cdf0e10cSrcweir ScDBQueryParamMatrix* p = static_cast<ScDBQueryParamMatrix*>(pParam);
946cdf0e10cSrcweir mpData.reset(new DataAccessMatrix(this, p));
947cdf0e10cSrcweir }
948cdf0e10cSrcweir }
949cdf0e10cSrcweir }
950cdf0e10cSrcweir
GetFirst(Value & rValue)951cdf0e10cSrcweir bool ScDBQueryDataIterator::GetFirst(Value& rValue)
952cdf0e10cSrcweir {
953cdf0e10cSrcweir return mpData->getFirst(rValue);
954cdf0e10cSrcweir }
955cdf0e10cSrcweir
GetNext(Value & rValue)956cdf0e10cSrcweir bool ScDBQueryDataIterator::GetNext(Value& rValue)
957cdf0e10cSrcweir {
958cdf0e10cSrcweir return mpData->getNext(rValue);
959cdf0e10cSrcweir }
960cdf0e10cSrcweir
961cdf0e10cSrcweir // ============================================================================
962cdf0e10cSrcweir
ScCellIterator(ScDocument * pDocument,SCCOL nSCol,SCROW nSRow,SCTAB nSTab,SCCOL nECol,SCROW nERow,SCTAB nETab,sal_Bool bSTotal)963cdf0e10cSrcweir ScCellIterator::ScCellIterator( ScDocument* pDocument,
964cdf0e10cSrcweir SCCOL nSCol, SCROW nSRow, SCTAB nSTab,
965cdf0e10cSrcweir SCCOL nECol, SCROW nERow, SCTAB nETab, sal_Bool bSTotal ) :
966cdf0e10cSrcweir pDoc( pDocument ),
967cdf0e10cSrcweir nStartCol( nSCol),
968cdf0e10cSrcweir nStartRow( nSRow),
969cdf0e10cSrcweir nStartTab( nSTab ),
970cdf0e10cSrcweir nEndCol( nECol ),
971cdf0e10cSrcweir nEndRow( nERow),
972cdf0e10cSrcweir nEndTab( nETab ),
973cdf0e10cSrcweir bSubTotal(bSTotal)
974cdf0e10cSrcweir
975cdf0e10cSrcweir {
976cdf0e10cSrcweir PutInOrder( nStartCol, nEndCol);
977cdf0e10cSrcweir PutInOrder( nStartRow, nEndRow);
978cdf0e10cSrcweir PutInOrder( nStartTab, nEndTab );
979cdf0e10cSrcweir
980cdf0e10cSrcweir if (!ValidCol(nStartCol)) nStartCol = MAXCOL;
981cdf0e10cSrcweir if (!ValidCol(nEndCol)) nEndCol = MAXCOL;
982cdf0e10cSrcweir if (!ValidRow(nStartRow)) nStartRow = MAXROW;
983cdf0e10cSrcweir if (!ValidRow(nEndRow)) nEndRow = MAXROW;
984cdf0e10cSrcweir if (!ValidTab(nStartTab)) nStartTab = MAXTAB;
985cdf0e10cSrcweir if (!ValidTab(nEndTab)) nEndTab = MAXTAB;
986cdf0e10cSrcweir
987cdf0e10cSrcweir while (nEndTab>0 && !pDoc->pTab[nEndTab])
988cdf0e10cSrcweir --nEndTab; // nur benutzte Tabellen
989cdf0e10cSrcweir if (nStartTab>nEndTab)
990cdf0e10cSrcweir nStartTab = nEndTab;
991cdf0e10cSrcweir
992cdf0e10cSrcweir nCol = nStartCol;
993cdf0e10cSrcweir nRow = nStartRow;
994cdf0e10cSrcweir nTab = nStartTab;
995cdf0e10cSrcweir nColRow = 0; // wird bei GetFirst initialisiert
996cdf0e10cSrcweir
997cdf0e10cSrcweir if (!pDoc->pTab[nTab])
998cdf0e10cSrcweir {
999cdf0e10cSrcweir DBG_ERROR("Tabelle nicht gefunden");
1000cdf0e10cSrcweir nStartCol = nCol = MAXCOL+1;
1001cdf0e10cSrcweir nStartRow = nRow = MAXROW+1;
1002cdf0e10cSrcweir nStartTab = nTab = MAXTAB+1; // -> Abbruch bei GetFirst
1003cdf0e10cSrcweir }
1004cdf0e10cSrcweir }
1005cdf0e10cSrcweir
ScCellIterator(ScDocument * pDocument,const ScRange & rRange,sal_Bool bSTotal)1006cdf0e10cSrcweir ScCellIterator::ScCellIterator
1007cdf0e10cSrcweir ( ScDocument* pDocument, const ScRange& rRange, sal_Bool bSTotal ) :
1008cdf0e10cSrcweir pDoc( pDocument ),
1009cdf0e10cSrcweir nStartCol( rRange.aStart.Col() ),
1010cdf0e10cSrcweir nStartRow( rRange.aStart.Row() ),
1011cdf0e10cSrcweir nStartTab( rRange.aStart.Tab() ),
1012cdf0e10cSrcweir nEndCol( rRange.aEnd.Col() ),
1013cdf0e10cSrcweir nEndRow( rRange.aEnd.Row() ),
1014cdf0e10cSrcweir nEndTab( rRange.aEnd.Tab() ),
1015cdf0e10cSrcweir bSubTotal(bSTotal)
1016cdf0e10cSrcweir
1017cdf0e10cSrcweir {
1018cdf0e10cSrcweir PutInOrder( nStartCol, nEndCol);
1019cdf0e10cSrcweir PutInOrder( nStartRow, nEndRow);
1020cdf0e10cSrcweir PutInOrder( nStartTab, nEndTab );
1021cdf0e10cSrcweir
1022cdf0e10cSrcweir if (!ValidCol(nStartCol)) nStartCol = MAXCOL;
1023cdf0e10cSrcweir if (!ValidCol(nEndCol)) nEndCol = MAXCOL;
1024cdf0e10cSrcweir if (!ValidRow(nStartRow)) nStartRow = MAXROW;
1025cdf0e10cSrcweir if (!ValidRow(nEndRow)) nEndRow = MAXROW;
1026cdf0e10cSrcweir if (!ValidTab(nStartTab)) nStartTab = MAXTAB;
1027cdf0e10cSrcweir if (!ValidTab(nEndTab)) nEndTab = MAXTAB;
1028cdf0e10cSrcweir
1029cdf0e10cSrcweir while (nEndTab>0 && !pDoc->pTab[nEndTab])
1030cdf0e10cSrcweir --nEndTab; // nur benutzte Tabellen
1031cdf0e10cSrcweir if (nStartTab>nEndTab)
1032cdf0e10cSrcweir nStartTab = nEndTab;
1033cdf0e10cSrcweir
1034cdf0e10cSrcweir nCol = nStartCol;
1035cdf0e10cSrcweir nRow = nStartRow;
1036cdf0e10cSrcweir nTab = nStartTab;
1037cdf0e10cSrcweir nColRow = 0; // wird bei GetFirst initialisiert
1038cdf0e10cSrcweir
1039cdf0e10cSrcweir if (!pDoc->pTab[nTab])
1040cdf0e10cSrcweir {
1041cdf0e10cSrcweir DBG_ERROR("Tabelle nicht gefunden");
1042cdf0e10cSrcweir nStartCol = nCol = MAXCOL+1;
1043cdf0e10cSrcweir nStartRow = nRow = MAXROW+1;
1044cdf0e10cSrcweir nStartTab = nTab = MAXTAB+1; // -> Abbruch bei GetFirst
1045cdf0e10cSrcweir }
1046cdf0e10cSrcweir }
1047cdf0e10cSrcweir
GetThis()1048cdf0e10cSrcweir ScBaseCell* ScCellIterator::GetThis()
1049cdf0e10cSrcweir {
1050cdf0e10cSrcweir ScColumn* pCol = &(pDoc->pTab[nTab])->aCol[nCol];
1051cdf0e10cSrcweir for ( ;; )
1052cdf0e10cSrcweir {
1053cdf0e10cSrcweir if ( nRow > nEndRow )
1054cdf0e10cSrcweir {
1055cdf0e10cSrcweir nRow = nStartRow;
1056cdf0e10cSrcweir do
1057cdf0e10cSrcweir {
1058cdf0e10cSrcweir nCol++;
1059cdf0e10cSrcweir if ( nCol > nEndCol )
1060cdf0e10cSrcweir {
1061cdf0e10cSrcweir nCol = nStartCol;
1062cdf0e10cSrcweir nTab++;
1063cdf0e10cSrcweir if ( nTab > nEndTab )
1064cdf0e10cSrcweir return NULL; // Ende und Aus
1065cdf0e10cSrcweir }
1066cdf0e10cSrcweir pCol = &(pDoc->pTab[nTab])->aCol[nCol];
1067cdf0e10cSrcweir } while ( pCol->nCount == 0 );
1068cdf0e10cSrcweir pCol->Search( nRow, nColRow );
1069cdf0e10cSrcweir }
1070cdf0e10cSrcweir
1071cdf0e10cSrcweir while ( (nColRow < pCol->nCount) && (pCol->pItems[nColRow].nRow < nRow) )
1072cdf0e10cSrcweir nColRow++;
1073cdf0e10cSrcweir
1074cdf0e10cSrcweir if ( nColRow < pCol->nCount && pCol->pItems[nColRow].nRow <= nEndRow )
1075cdf0e10cSrcweir {
1076cdf0e10cSrcweir nRow = pCol->pItems[nColRow].nRow;
1077cdf0e10cSrcweir if ( !bSubTotal || !pDoc->pTab[nTab]->RowFiltered( nRow ) )
1078cdf0e10cSrcweir {
1079cdf0e10cSrcweir ScBaseCell* pCell = pCol->pItems[nColRow].pCell;
1080cdf0e10cSrcweir
1081cdf0e10cSrcweir if ( bSubTotal && pCell->GetCellType() == CELLTYPE_FORMULA
1082cdf0e10cSrcweir && ((ScFormulaCell*)pCell)->IsSubTotal() )
1083cdf0e10cSrcweir nRow++; // Sub-Total-Zeilen nicht
1084cdf0e10cSrcweir else
1085cdf0e10cSrcweir return pCell; // gefunden
1086cdf0e10cSrcweir }
1087cdf0e10cSrcweir else
1088cdf0e10cSrcweir nRow++;
1089cdf0e10cSrcweir }
1090cdf0e10cSrcweir else
1091cdf0e10cSrcweir nRow = nEndRow + 1; // Naechste Spalte
1092cdf0e10cSrcweir }
1093cdf0e10cSrcweir }
1094cdf0e10cSrcweir
GetFirst()1095cdf0e10cSrcweir ScBaseCell* ScCellIterator::GetFirst()
1096cdf0e10cSrcweir {
1097cdf0e10cSrcweir if ( !ValidTab(nTab) )
1098cdf0e10cSrcweir return NULL;
1099cdf0e10cSrcweir nCol = nStartCol;
1100cdf0e10cSrcweir nRow = nStartRow;
1101cdf0e10cSrcweir nTab = nStartTab;
1102cdf0e10cSrcweir // nColRow = 0;
1103cdf0e10cSrcweir ScColumn* pCol = &(pDoc->pTab[nTab])->aCol[nCol];
1104cdf0e10cSrcweir pCol->Search( nRow, nColRow );
1105cdf0e10cSrcweir return GetThis();
1106cdf0e10cSrcweir }
1107cdf0e10cSrcweir
GetNext()1108cdf0e10cSrcweir ScBaseCell* ScCellIterator::GetNext()
1109cdf0e10cSrcweir {
1110cdf0e10cSrcweir ++nRow;
1111cdf0e10cSrcweir return GetThis();
1112cdf0e10cSrcweir }
1113cdf0e10cSrcweir
1114cdf0e10cSrcweir //-------------------------------------------------------------------------------
1115cdf0e10cSrcweir
ScQueryCellIterator(ScDocument * pDocument,SCTAB nTable,const ScQueryParam & rParam,sal_Bool bMod)1116cdf0e10cSrcweir ScQueryCellIterator::ScQueryCellIterator(ScDocument* pDocument, SCTAB nTable,
1117cdf0e10cSrcweir const ScQueryParam& rParam, sal_Bool bMod ) :
1118cdf0e10cSrcweir aParam (rParam),
1119cdf0e10cSrcweir pDoc( pDocument ),
1120cdf0e10cSrcweir nTab( nTable),
1121cdf0e10cSrcweir nStopOnMismatch( nStopOnMismatchDisabled ),
1122cdf0e10cSrcweir nTestEqualCondition( nTestEqualConditionDisabled ),
1123cdf0e10cSrcweir bAdvanceQuery( sal_False ),
1124cdf0e10cSrcweir bIgnoreMismatchOnLeadingStrings( sal_False )
1125cdf0e10cSrcweir {
1126cdf0e10cSrcweir nCol = aParam.nCol1;
1127cdf0e10cSrcweir nRow = aParam.nRow1;
1128cdf0e10cSrcweir nColRow = 0; // wird bei GetFirst initialisiert
1129cdf0e10cSrcweir SCSIZE i;
1130cdf0e10cSrcweir if (bMod) // sonst schon eingetragen
1131cdf0e10cSrcweir {
1132cdf0e10cSrcweir for (i=0; (i<MAXQUERY) && (aParam.GetEntry(i).bDoQuery); i++)
1133cdf0e10cSrcweir {
1134cdf0e10cSrcweir ScQueryEntry& rEntry = aParam.GetEntry(i);
1135cdf0e10cSrcweir sal_uInt32 nIndex = 0;
1136cdf0e10cSrcweir rEntry.bQueryByString =
1137cdf0e10cSrcweir !(pDoc->GetFormatTable()->IsNumberFormat(*rEntry.pStr,
1138cdf0e10cSrcweir nIndex, rEntry.nVal));
1139cdf0e10cSrcweir }
1140cdf0e10cSrcweir }
1141cdf0e10cSrcweir nNumFormat = 0; // werden bei GetNumberFormat initialisiert
1142cdf0e10cSrcweir pAttrArray = 0;
1143cdf0e10cSrcweir nAttrEndRow = 0;
1144cdf0e10cSrcweir }
1145cdf0e10cSrcweir
GetThis()1146cdf0e10cSrcweir ScBaseCell* ScQueryCellIterator::GetThis()
1147cdf0e10cSrcweir {
1148cdf0e10cSrcweir ScColumn* pCol = &(pDoc->pTab[nTab])->aCol[nCol];
1149cdf0e10cSrcweir const ScQueryEntry& rEntry = aParam.GetEntry(0);
1150cdf0e10cSrcweir SCCOLROW nFirstQueryField = rEntry.nField;
1151cdf0e10cSrcweir bool bAllStringIgnore = bIgnoreMismatchOnLeadingStrings &&
1152cdf0e10cSrcweir !rEntry.bQueryByString;
1153cdf0e10cSrcweir bool bFirstStringIgnore = bIgnoreMismatchOnLeadingStrings &&
1154cdf0e10cSrcweir !aParam.bHasHeader && rEntry.bQueryByString &&
1155cdf0e10cSrcweir ((aParam.bByRow && nRow == aParam.nRow1) ||
1156cdf0e10cSrcweir (!aParam.bByRow && nCol == aParam.nCol1));
1157cdf0e10cSrcweir for ( ;; )
1158cdf0e10cSrcweir {
1159cdf0e10cSrcweir if ( nRow > aParam.nRow2 )
1160cdf0e10cSrcweir {
1161cdf0e10cSrcweir nRow = aParam.nRow1;
1162cdf0e10cSrcweir if (aParam.bHasHeader && aParam.bByRow)
1163cdf0e10cSrcweir nRow++;
1164cdf0e10cSrcweir do
1165cdf0e10cSrcweir {
1166cdf0e10cSrcweir if ( ++nCol > aParam.nCol2 )
1167cdf0e10cSrcweir return NULL; // Ende und Aus
1168cdf0e10cSrcweir if ( bAdvanceQuery )
1169cdf0e10cSrcweir {
1170cdf0e10cSrcweir AdvanceQueryParamEntryField();
1171cdf0e10cSrcweir nFirstQueryField = rEntry.nField;
1172cdf0e10cSrcweir }
1173cdf0e10cSrcweir pCol = &(pDoc->pTab[nTab])->aCol[nCol];
1174cdf0e10cSrcweir } while ( pCol->nCount == 0 );
1175cdf0e10cSrcweir pCol->Search( nRow, nColRow );
1176cdf0e10cSrcweir bFirstStringIgnore = bIgnoreMismatchOnLeadingStrings &&
1177cdf0e10cSrcweir !aParam.bHasHeader && rEntry.bQueryByString &&
1178cdf0e10cSrcweir aParam.bByRow;
1179cdf0e10cSrcweir }
1180cdf0e10cSrcweir
1181cdf0e10cSrcweir while ( nColRow < pCol->nCount && pCol->pItems[nColRow].nRow < nRow )
1182cdf0e10cSrcweir nColRow++;
1183cdf0e10cSrcweir
1184cdf0e10cSrcweir if ( nColRow < pCol->nCount &&
1185cdf0e10cSrcweir (nRow = pCol->pItems[nColRow].nRow) <= aParam.nRow2 )
1186cdf0e10cSrcweir {
1187cdf0e10cSrcweir ScBaseCell* pCell = pCol->pItems[nColRow].pCell;
1188cdf0e10cSrcweir if ( pCell->GetCellType() == CELLTYPE_NOTE )
1189cdf0e10cSrcweir ++nRow;
1190cdf0e10cSrcweir else if (bAllStringIgnore && pCell->HasStringData())
1191cdf0e10cSrcweir ++nRow;
1192cdf0e10cSrcweir else
1193cdf0e10cSrcweir {
1194cdf0e10cSrcweir sal_Bool bTestEqualCondition;
1195cdf0e10cSrcweir if ( (pDoc->pTab[nTab])->ValidQuery( nRow, aParam, NULL,
1196cdf0e10cSrcweir (nCol == static_cast<SCCOL>(nFirstQueryField) ? pCell : NULL),
1197cdf0e10cSrcweir (nTestEqualCondition ? &bTestEqualCondition : NULL) ) )
1198cdf0e10cSrcweir {
1199cdf0e10cSrcweir if ( nTestEqualCondition && bTestEqualCondition )
1200cdf0e10cSrcweir nTestEqualCondition |= nTestEqualConditionMatched;
1201cdf0e10cSrcweir return pCell; // found
1202cdf0e10cSrcweir }
1203cdf0e10cSrcweir else if ( nStopOnMismatch )
1204cdf0e10cSrcweir {
1205cdf0e10cSrcweir // Yes, even a mismatch may have a fulfilled equal
1206cdf0e10cSrcweir // condition if regular expressions were involved and
1207cdf0e10cSrcweir // SC_LESS_EQUAL or SC_GREATER_EQUAL were queried.
1208cdf0e10cSrcweir if ( nTestEqualCondition && bTestEqualCondition )
1209cdf0e10cSrcweir {
1210cdf0e10cSrcweir nTestEqualCondition |= nTestEqualConditionMatched;
1211cdf0e10cSrcweir nStopOnMismatch |= nStopOnMismatchOccured;
1212cdf0e10cSrcweir return NULL;
1213cdf0e10cSrcweir }
1214cdf0e10cSrcweir bool bStop;
1215cdf0e10cSrcweir if (bFirstStringIgnore)
1216cdf0e10cSrcweir {
1217cdf0e10cSrcweir if (pCell->HasStringData())
1218cdf0e10cSrcweir {
1219cdf0e10cSrcweir ++nRow;
1220cdf0e10cSrcweir bStop = false;
1221cdf0e10cSrcweir }
1222cdf0e10cSrcweir else
1223cdf0e10cSrcweir bStop = true;
1224cdf0e10cSrcweir }
1225cdf0e10cSrcweir else
1226cdf0e10cSrcweir bStop = true;
1227cdf0e10cSrcweir if (bStop)
1228cdf0e10cSrcweir {
1229cdf0e10cSrcweir nStopOnMismatch |= nStopOnMismatchOccured;
1230cdf0e10cSrcweir return NULL;
1231cdf0e10cSrcweir }
1232cdf0e10cSrcweir }
1233cdf0e10cSrcweir else
1234cdf0e10cSrcweir nRow++;
1235cdf0e10cSrcweir }
1236cdf0e10cSrcweir }
1237cdf0e10cSrcweir else
1238cdf0e10cSrcweir nRow = aParam.nRow2 + 1; // Naechste Spalte
1239cdf0e10cSrcweir bFirstStringIgnore = false;
1240cdf0e10cSrcweir }
1241cdf0e10cSrcweir }
1242cdf0e10cSrcweir
GetFirst()1243cdf0e10cSrcweir ScBaseCell* ScQueryCellIterator::GetFirst()
1244cdf0e10cSrcweir {
1245cdf0e10cSrcweir nCol = aParam.nCol1;
1246cdf0e10cSrcweir nRow = aParam.nRow1;
1247cdf0e10cSrcweir if (aParam.bHasHeader)
1248cdf0e10cSrcweir nRow++;
1249cdf0e10cSrcweir // nColRow = 0;
1250cdf0e10cSrcweir ScColumn* pCol = &(pDoc->pTab[nTab])->aCol[nCol];
1251cdf0e10cSrcweir pCol->Search( nRow, nColRow );
1252cdf0e10cSrcweir return GetThis();
1253cdf0e10cSrcweir }
1254cdf0e10cSrcweir
GetNext()1255cdf0e10cSrcweir ScBaseCell* ScQueryCellIterator::GetNext()
1256cdf0e10cSrcweir {
1257cdf0e10cSrcweir ++nRow;
1258cdf0e10cSrcweir if ( nStopOnMismatch )
1259cdf0e10cSrcweir nStopOnMismatch = nStopOnMismatchEnabled;
1260cdf0e10cSrcweir if ( nTestEqualCondition )
1261cdf0e10cSrcweir nTestEqualCondition = nTestEqualConditionEnabled;
1262cdf0e10cSrcweir return GetThis();
1263cdf0e10cSrcweir }
1264cdf0e10cSrcweir
AdvanceQueryParamEntryField()1265cdf0e10cSrcweir void ScQueryCellIterator::AdvanceQueryParamEntryField()
1266cdf0e10cSrcweir {
1267cdf0e10cSrcweir SCSIZE nEntries = aParam.GetEntryCount();
1268cdf0e10cSrcweir for ( SCSIZE j = 0; j < nEntries; j++ )
1269cdf0e10cSrcweir {
1270cdf0e10cSrcweir ScQueryEntry& rEntry = aParam.GetEntry( j );
1271cdf0e10cSrcweir if ( rEntry.bDoQuery )
1272cdf0e10cSrcweir {
1273cdf0e10cSrcweir if ( rEntry.nField < MAXCOL )
1274cdf0e10cSrcweir rEntry.nField++;
1275cdf0e10cSrcweir else
1276cdf0e10cSrcweir {
1277cdf0e10cSrcweir DBG_ERRORFILE( "AdvanceQueryParamEntryField: ++rEntry.nField > MAXCOL" );
1278cdf0e10cSrcweir }
1279cdf0e10cSrcweir }
1280cdf0e10cSrcweir else
1281cdf0e10cSrcweir break; // for
1282cdf0e10cSrcweir }
1283cdf0e10cSrcweir }
1284cdf0e10cSrcweir
1285cdf0e10cSrcweir
FindEqualOrSortedLastInRange(SCCOL & nFoundCol,SCROW & nFoundRow,sal_Bool bSearchForEqualAfterMismatch,sal_Bool bIgnoreMismatchOnLeadingStringsP)1286cdf0e10cSrcweir sal_Bool ScQueryCellIterator::FindEqualOrSortedLastInRange( SCCOL& nFoundCol,
1287cdf0e10cSrcweir SCROW& nFoundRow, sal_Bool bSearchForEqualAfterMismatch,
1288cdf0e10cSrcweir sal_Bool bIgnoreMismatchOnLeadingStringsP )
1289cdf0e10cSrcweir {
1290cdf0e10cSrcweir nFoundCol = MAXCOL+1;
1291cdf0e10cSrcweir nFoundRow = MAXROW+1;
1292cdf0e10cSrcweir SetStopOnMismatch( sal_True ); // assume sorted keys
1293cdf0e10cSrcweir SetTestEqualCondition( sal_True );
1294cdf0e10cSrcweir bIgnoreMismatchOnLeadingStrings = bIgnoreMismatchOnLeadingStringsP;
1295cdf0e10cSrcweir bool bRegExp = aParam.bRegExp && aParam.GetEntry(0).bQueryByString;
1296cdf0e10cSrcweir bool bBinary = !bRegExp && aParam.bByRow && (aParam.GetEntry(0).eOp ==
1297cdf0e10cSrcweir SC_LESS_EQUAL || aParam.GetEntry(0).eOp == SC_GREATER_EQUAL);
1298cdf0e10cSrcweir if (bBinary ? (BinarySearch() ? GetThis() : 0) : GetFirst())
1299cdf0e10cSrcweir {
1300cdf0e10cSrcweir // First equal entry or last smaller than (greater than) entry.
1301cdf0e10cSrcweir SCSIZE nColRowSave;
1302cdf0e10cSrcweir ScBaseCell* pNext = 0;
1303cdf0e10cSrcweir do
1304cdf0e10cSrcweir {
1305cdf0e10cSrcweir nFoundCol = GetCol();
1306cdf0e10cSrcweir nFoundRow = GetRow();
1307cdf0e10cSrcweir nColRowSave = nColRow;
1308cdf0e10cSrcweir } while ( !IsEqualConditionFulfilled() && (pNext = GetNext()) != NULL );
1309cdf0e10cSrcweir // There may be no pNext but equal condition fulfilled if regular
1310cdf0e10cSrcweir // expressions are involved. Keep the found entry and proceed.
1311cdf0e10cSrcweir if (!pNext && !IsEqualConditionFulfilled())
1312cdf0e10cSrcweir {
1313cdf0e10cSrcweir // Step back to last in range and adjust position markers for
1314cdf0e10cSrcweir // GetNumberFormat() or similar.
1315cdf0e10cSrcweir nCol = nFoundCol;
1316cdf0e10cSrcweir nRow = nFoundRow;
1317cdf0e10cSrcweir nColRow = nColRowSave;
1318cdf0e10cSrcweir }
1319cdf0e10cSrcweir }
1320cdf0e10cSrcweir if ( IsEqualConditionFulfilled() )
1321cdf0e10cSrcweir {
1322cdf0e10cSrcweir // Position on last equal entry.
1323cdf0e10cSrcweir SCSIZE nEntries = aParam.GetEntryCount();
1324cdf0e10cSrcweir for ( SCSIZE j = 0; j < nEntries; j++ )
1325cdf0e10cSrcweir {
1326cdf0e10cSrcweir ScQueryEntry& rEntry = aParam.GetEntry( j );
1327cdf0e10cSrcweir if ( rEntry.bDoQuery )
1328cdf0e10cSrcweir {
1329cdf0e10cSrcweir switch ( rEntry.eOp )
1330cdf0e10cSrcweir {
1331cdf0e10cSrcweir case SC_LESS_EQUAL :
1332cdf0e10cSrcweir case SC_GREATER_EQUAL :
1333cdf0e10cSrcweir rEntry.eOp = SC_EQUAL;
1334cdf0e10cSrcweir break;
1335cdf0e10cSrcweir default:
1336cdf0e10cSrcweir {
1337cdf0e10cSrcweir // added to avoid warnings
1338cdf0e10cSrcweir }
1339cdf0e10cSrcweir }
1340cdf0e10cSrcweir }
1341cdf0e10cSrcweir else
1342cdf0e10cSrcweir break; // for
1343cdf0e10cSrcweir }
1344cdf0e10cSrcweir SCSIZE nColRowSave;
1345cdf0e10cSrcweir bIgnoreMismatchOnLeadingStrings = sal_False;
1346cdf0e10cSrcweir SetTestEqualCondition( sal_False );
1347cdf0e10cSrcweir do
1348cdf0e10cSrcweir {
1349cdf0e10cSrcweir nFoundCol = GetCol();
1350cdf0e10cSrcweir nFoundRow = GetRow();
1351cdf0e10cSrcweir nColRowSave = nColRow;
1352cdf0e10cSrcweir } while (GetNext());
1353cdf0e10cSrcweir // Step back conditions same as above
1354cdf0e10cSrcweir nCol = nFoundCol;
1355cdf0e10cSrcweir nRow = nFoundRow;
1356cdf0e10cSrcweir nColRow = nColRowSave;
1357cdf0e10cSrcweir return sal_True;
1358cdf0e10cSrcweir }
1359cdf0e10cSrcweir if ( (bSearchForEqualAfterMismatch || aParam.bRegExp) &&
1360cdf0e10cSrcweir StoppedOnMismatch() )
1361cdf0e10cSrcweir {
1362cdf0e10cSrcweir // Assume found entry to be the last value less than respectively
1363cdf0e10cSrcweir // greater than the query. But keep on searching for an equal match.
1364cdf0e10cSrcweir SCSIZE nEntries = aParam.GetEntryCount();
1365cdf0e10cSrcweir for ( SCSIZE j = 0; j < nEntries; j++ )
1366cdf0e10cSrcweir {
1367cdf0e10cSrcweir ScQueryEntry& rEntry = aParam.GetEntry( j );
1368cdf0e10cSrcweir if ( rEntry.bDoQuery )
1369cdf0e10cSrcweir {
1370cdf0e10cSrcweir switch ( rEntry.eOp )
1371cdf0e10cSrcweir {
1372cdf0e10cSrcweir case SC_LESS_EQUAL :
1373cdf0e10cSrcweir case SC_GREATER_EQUAL :
1374cdf0e10cSrcweir rEntry.eOp = SC_EQUAL;
1375cdf0e10cSrcweir break;
1376cdf0e10cSrcweir default:
1377cdf0e10cSrcweir {
1378cdf0e10cSrcweir // added to avoid warnings
1379cdf0e10cSrcweir }
1380cdf0e10cSrcweir }
1381cdf0e10cSrcweir }
1382cdf0e10cSrcweir else
1383cdf0e10cSrcweir break; // for
1384cdf0e10cSrcweir }
1385cdf0e10cSrcweir SetStopOnMismatch( sal_False );
1386cdf0e10cSrcweir SetTestEqualCondition( sal_False );
1387cdf0e10cSrcweir if (GetNext())
1388cdf0e10cSrcweir {
1389cdf0e10cSrcweir // Last of a consecutive area, avoid searching the entire parameter
1390cdf0e10cSrcweir // range as it is a real performance bottleneck in case of regular
1391cdf0e10cSrcweir // expressions.
1392cdf0e10cSrcweir SCSIZE nColRowSave;
1393cdf0e10cSrcweir do
1394cdf0e10cSrcweir {
1395cdf0e10cSrcweir nFoundCol = GetCol();
1396cdf0e10cSrcweir nFoundRow = GetRow();
1397cdf0e10cSrcweir nColRowSave = nColRow;
1398cdf0e10cSrcweir SetStopOnMismatch( sal_True );
1399cdf0e10cSrcweir } while (GetNext());
1400cdf0e10cSrcweir nCol = nFoundCol;
1401cdf0e10cSrcweir nRow = nFoundRow;
1402cdf0e10cSrcweir nColRow = nColRowSave;
1403cdf0e10cSrcweir }
1404cdf0e10cSrcweir }
1405cdf0e10cSrcweir return (nFoundCol <= MAXCOL) && (nFoundRow <= MAXROW);
1406cdf0e10cSrcweir }
1407cdf0e10cSrcweir
1408cdf0e10cSrcweir
BinarySearch()1409cdf0e10cSrcweir ScBaseCell* ScQueryCellIterator::BinarySearch()
1410cdf0e10cSrcweir {
1411cdf0e10cSrcweir nCol = aParam.nCol1;
1412cdf0e10cSrcweir ScColumn* pCol = &(pDoc->pTab[nTab])->aCol[nCol];
1413cdf0e10cSrcweir if (!pCol->nCount)
1414cdf0e10cSrcweir return 0;
1415cdf0e10cSrcweir
1416cdf0e10cSrcweir ScBaseCell* pCell;
1417cdf0e10cSrcweir SCSIZE nHi, nLo;
1418cdf0e10cSrcweir CollatorWrapper* pCollator = (aParam.bCaseSens ? ScGlobal::GetCaseCollator() :
1419cdf0e10cSrcweir ScGlobal::GetCollator());
1420cdf0e10cSrcweir SvNumberFormatter& rFormatter = *(pDoc->GetFormatTable());
1421cdf0e10cSrcweir const ScQueryEntry& rEntry = aParam.GetEntry(0);
1422cdf0e10cSrcweir bool bLessEqual = rEntry.eOp == SC_LESS_EQUAL;
1423cdf0e10cSrcweir bool bByString = rEntry.bQueryByString;
1424cdf0e10cSrcweir bool bAllStringIgnore = bIgnoreMismatchOnLeadingStrings && !bByString;
1425cdf0e10cSrcweir bool bFirstStringIgnore = bIgnoreMismatchOnLeadingStrings &&
1426cdf0e10cSrcweir !aParam.bHasHeader && bByString;
1427cdf0e10cSrcweir
1428cdf0e10cSrcweir nRow = aParam.nRow1;
1429cdf0e10cSrcweir if (aParam.bHasHeader)
1430cdf0e10cSrcweir nRow++;
1431cdf0e10cSrcweir const ColEntry* pItems = pCol->pItems;
1432cdf0e10cSrcweir if (pCol->Search( nRow, nLo ) && bFirstStringIgnore &&
1433cdf0e10cSrcweir pItems[nLo].pCell->HasStringData())
1434cdf0e10cSrcweir {
1435cdf0e10cSrcweir String aCellStr;
1436cdf0e10cSrcweir sal_uLong nFormat = pCol->GetNumberFormat( pItems[nLo].nRow);
1437cdf0e10cSrcweir ScCellFormat::GetInputString( pItems[nLo].pCell, nFormat, aCellStr,
1438cdf0e10cSrcweir rFormatter);
1439cdf0e10cSrcweir sal_Int32 nTmp = pCollator->compareString( aCellStr, *rEntry.pStr);
1440cdf0e10cSrcweir if ((rEntry.eOp == SC_LESS_EQUAL && nTmp > 0) ||
1441cdf0e10cSrcweir (rEntry.eOp == SC_GREATER_EQUAL && nTmp < 0) ||
1442cdf0e10cSrcweir (rEntry.eOp == SC_EQUAL && nTmp != 0))
1443cdf0e10cSrcweir ++nLo;
1444cdf0e10cSrcweir }
1445cdf0e10cSrcweir if (!pCol->Search( aParam.nRow2, nHi ) && nHi>0)
1446cdf0e10cSrcweir --nHi;
1447cdf0e10cSrcweir while (bAllStringIgnore && nLo <= nHi && nLo < pCol->nCount &&
1448cdf0e10cSrcweir pItems[nLo].pCell->HasStringData())
1449cdf0e10cSrcweir ++nLo;
1450cdf0e10cSrcweir
1451cdf0e10cSrcweir // Bookkeeping values for breaking up the binary search in case the data
1452cdf0e10cSrcweir // range isn't strictly sorted.
1453cdf0e10cSrcweir SCSIZE nLastInRange = nLo;
1454cdf0e10cSrcweir SCSIZE nFirstLastInRange = nLastInRange;
1455cdf0e10cSrcweir double fLastInRangeValue = bLessEqual ?
1456cdf0e10cSrcweir -(::std::numeric_limits<double>::max()) :
1457cdf0e10cSrcweir ::std::numeric_limits<double>::max();
1458cdf0e10cSrcweir String aLastInRangeString;
1459cdf0e10cSrcweir if (!bLessEqual)
1460cdf0e10cSrcweir aLastInRangeString.Assign( sal_Unicode(0xFFFF));
1461cdf0e10cSrcweir if (nLastInRange < pCol->nCount)
1462cdf0e10cSrcweir {
1463cdf0e10cSrcweir pCell = pItems[nLastInRange].pCell;
1464cdf0e10cSrcweir if (pCell->HasStringData())
1465cdf0e10cSrcweir {
1466cdf0e10cSrcweir sal_uLong nFormat = pCol->GetNumberFormat( pItems[nLastInRange].nRow);
1467cdf0e10cSrcweir ScCellFormat::GetInputString( pCell, nFormat, aLastInRangeString,
1468cdf0e10cSrcweir rFormatter);
1469cdf0e10cSrcweir }
1470cdf0e10cSrcweir else
1471cdf0e10cSrcweir {
1472cdf0e10cSrcweir switch ( pCell->GetCellType() )
1473cdf0e10cSrcweir {
1474cdf0e10cSrcweir case CELLTYPE_VALUE :
1475cdf0e10cSrcweir fLastInRangeValue =
1476cdf0e10cSrcweir static_cast<ScValueCell*>(pCell)->GetValue();
1477cdf0e10cSrcweir break;
1478cdf0e10cSrcweir case CELLTYPE_FORMULA :
1479cdf0e10cSrcweir fLastInRangeValue =
1480cdf0e10cSrcweir static_cast<ScFormulaCell*>(pCell)->GetValue();
1481cdf0e10cSrcweir break;
1482cdf0e10cSrcweir default:
1483cdf0e10cSrcweir {
1484cdf0e10cSrcweir // added to avoid warnings
1485cdf0e10cSrcweir }
1486cdf0e10cSrcweir }
1487cdf0e10cSrcweir }
1488cdf0e10cSrcweir }
1489cdf0e10cSrcweir
1490cdf0e10cSrcweir sal_Int32 nRes = 0;
1491cdf0e10cSrcweir bool bFound = false;
1492cdf0e10cSrcweir bool bDone = false;
1493cdf0e10cSrcweir while (nLo <= nHi && !bDone)
1494cdf0e10cSrcweir {
1495cdf0e10cSrcweir SCSIZE nMid = (nLo+nHi)/2;
1496cdf0e10cSrcweir SCSIZE i = nMid;
1497cdf0e10cSrcweir while (i <= nHi && pItems[i].pCell->GetCellType() == CELLTYPE_NOTE)
1498cdf0e10cSrcweir ++i;
1499cdf0e10cSrcweir if (i > nHi)
1500cdf0e10cSrcweir {
1501cdf0e10cSrcweir if (nMid > 0)
1502cdf0e10cSrcweir nHi = nMid - 1;
1503cdf0e10cSrcweir else
1504cdf0e10cSrcweir bDone = true;
1505cdf0e10cSrcweir continue; // while
1506cdf0e10cSrcweir }
1507cdf0e10cSrcweir sal_Bool bStr = pItems[i].pCell->HasStringData();
1508cdf0e10cSrcweir nRes = 0;
1509cdf0e10cSrcweir // compares are content<query:-1, content>query:1
1510cdf0e10cSrcweir // Cell value comparison similar to ScTable::ValidQuery()
1511cdf0e10cSrcweir if (!bStr && !bByString)
1512cdf0e10cSrcweir {
1513cdf0e10cSrcweir double nCellVal;
1514cdf0e10cSrcweir pCell = pItems[i].pCell;
1515cdf0e10cSrcweir switch ( pCell->GetCellType() )
1516cdf0e10cSrcweir {
1517cdf0e10cSrcweir case CELLTYPE_VALUE :
1518cdf0e10cSrcweir nCellVal = static_cast<ScValueCell*>(pCell)->GetValue();
1519cdf0e10cSrcweir break;
1520cdf0e10cSrcweir case CELLTYPE_FORMULA :
1521cdf0e10cSrcweir nCellVal = static_cast<ScFormulaCell*>(pCell)->GetValue();
1522cdf0e10cSrcweir break;
1523cdf0e10cSrcweir default:
1524cdf0e10cSrcweir nCellVal = 0.0;
1525cdf0e10cSrcweir }
1526cdf0e10cSrcweir if ((nCellVal < rEntry.nVal) && !::rtl::math::approxEqual(
1527cdf0e10cSrcweir nCellVal, rEntry.nVal))
1528cdf0e10cSrcweir {
1529cdf0e10cSrcweir nRes = -1;
1530cdf0e10cSrcweir if (bLessEqual)
1531cdf0e10cSrcweir {
1532cdf0e10cSrcweir if (fLastInRangeValue < nCellVal)
1533cdf0e10cSrcweir {
1534cdf0e10cSrcweir fLastInRangeValue = nCellVal;
1535cdf0e10cSrcweir nLastInRange = i;
1536cdf0e10cSrcweir }
1537cdf0e10cSrcweir else if (fLastInRangeValue > nCellVal)
1538cdf0e10cSrcweir {
1539cdf0e10cSrcweir // not strictly sorted, continue with GetThis()
1540cdf0e10cSrcweir nLastInRange = nFirstLastInRange;
1541cdf0e10cSrcweir bDone = true;
1542cdf0e10cSrcweir }
1543cdf0e10cSrcweir }
1544cdf0e10cSrcweir }
1545cdf0e10cSrcweir else if ((nCellVal > rEntry.nVal) && !::rtl::math::approxEqual(
1546cdf0e10cSrcweir nCellVal, rEntry.nVal))
1547cdf0e10cSrcweir {
1548cdf0e10cSrcweir nRes = 1;
1549cdf0e10cSrcweir if (!bLessEqual)
1550cdf0e10cSrcweir {
1551cdf0e10cSrcweir if (fLastInRangeValue > nCellVal)
1552cdf0e10cSrcweir {
1553cdf0e10cSrcweir fLastInRangeValue = nCellVal;
1554cdf0e10cSrcweir nLastInRange = i;
1555cdf0e10cSrcweir }
1556cdf0e10cSrcweir else if (fLastInRangeValue < nCellVal)
1557cdf0e10cSrcweir {
1558cdf0e10cSrcweir // not strictly sorted, continue with GetThis()
1559cdf0e10cSrcweir nLastInRange = nFirstLastInRange;
1560cdf0e10cSrcweir bDone = true;
1561cdf0e10cSrcweir }
1562cdf0e10cSrcweir }
1563cdf0e10cSrcweir }
1564cdf0e10cSrcweir }
1565cdf0e10cSrcweir else if (bStr && bByString)
1566cdf0e10cSrcweir {
1567cdf0e10cSrcweir String aCellStr;
1568cdf0e10cSrcweir sal_uLong nFormat = pCol->GetNumberFormat( pItems[i].nRow);
1569cdf0e10cSrcweir ScCellFormat::GetInputString( pItems[i].pCell, nFormat, aCellStr,
1570cdf0e10cSrcweir rFormatter);
1571cdf0e10cSrcweir nRes = pCollator->compareString( aCellStr, *rEntry.pStr);
1572cdf0e10cSrcweir if (nRes < 0 && bLessEqual)
1573cdf0e10cSrcweir {
1574cdf0e10cSrcweir sal_Int32 nTmp = pCollator->compareString( aLastInRangeString,
1575cdf0e10cSrcweir aCellStr);
1576cdf0e10cSrcweir if (nTmp < 0)
1577cdf0e10cSrcweir {
1578cdf0e10cSrcweir aLastInRangeString = aCellStr;
1579cdf0e10cSrcweir nLastInRange = i;
1580cdf0e10cSrcweir }
1581cdf0e10cSrcweir else if (nTmp > 0)
1582cdf0e10cSrcweir {
1583cdf0e10cSrcweir // not strictly sorted, continue with GetThis()
1584cdf0e10cSrcweir nLastInRange = nFirstLastInRange;
1585cdf0e10cSrcweir bDone = true;
1586cdf0e10cSrcweir }
1587cdf0e10cSrcweir }
1588cdf0e10cSrcweir else if (nRes > 0 && !bLessEqual)
1589cdf0e10cSrcweir {
1590cdf0e10cSrcweir sal_Int32 nTmp = pCollator->compareString( aLastInRangeString,
1591cdf0e10cSrcweir aCellStr);
1592cdf0e10cSrcweir if (nTmp > 0)
1593cdf0e10cSrcweir {
1594cdf0e10cSrcweir aLastInRangeString = aCellStr;
1595cdf0e10cSrcweir nLastInRange = i;
1596cdf0e10cSrcweir }
1597cdf0e10cSrcweir else if (nTmp < 0)
1598cdf0e10cSrcweir {
1599cdf0e10cSrcweir // not strictly sorted, continue with GetThis()
1600cdf0e10cSrcweir nLastInRange = nFirstLastInRange;
1601cdf0e10cSrcweir bDone = true;
1602cdf0e10cSrcweir }
1603cdf0e10cSrcweir }
1604cdf0e10cSrcweir }
1605cdf0e10cSrcweir else if (!bStr && bByString)
1606cdf0e10cSrcweir {
1607cdf0e10cSrcweir nRes = -1; // numeric < string
1608cdf0e10cSrcweir if (bLessEqual)
1609cdf0e10cSrcweir nLastInRange = i;
1610cdf0e10cSrcweir }
1611cdf0e10cSrcweir else // if (bStr && !bByString)
1612cdf0e10cSrcweir {
1613cdf0e10cSrcweir nRes = 1; // string > numeric
1614cdf0e10cSrcweir if (!bLessEqual)
1615cdf0e10cSrcweir nLastInRange = i;
1616cdf0e10cSrcweir }
1617cdf0e10cSrcweir if (nRes < 0)
1618cdf0e10cSrcweir {
1619cdf0e10cSrcweir if (bLessEqual)
1620cdf0e10cSrcweir nLo = nMid + 1;
1621cdf0e10cSrcweir else // assumed to be SC_GREATER_EQUAL
1622cdf0e10cSrcweir {
1623cdf0e10cSrcweir if (nMid > 0)
1624cdf0e10cSrcweir nHi = nMid - 1;
1625cdf0e10cSrcweir else
1626cdf0e10cSrcweir bDone = true;
1627cdf0e10cSrcweir }
1628cdf0e10cSrcweir }
1629cdf0e10cSrcweir else if (nRes > 0)
1630cdf0e10cSrcweir {
1631cdf0e10cSrcweir if (bLessEqual)
1632cdf0e10cSrcweir {
1633cdf0e10cSrcweir if (nMid > 0)
1634cdf0e10cSrcweir nHi = nMid - 1;
1635cdf0e10cSrcweir else
1636cdf0e10cSrcweir bDone = true;
1637cdf0e10cSrcweir }
1638cdf0e10cSrcweir else // assumed to be SC_GREATER_EQUAL
1639cdf0e10cSrcweir nLo = nMid + 1;
1640cdf0e10cSrcweir }
1641cdf0e10cSrcweir else
1642cdf0e10cSrcweir {
1643cdf0e10cSrcweir nLo = i;
1644cdf0e10cSrcweir bDone = bFound = true;
1645cdf0e10cSrcweir }
1646cdf0e10cSrcweir }
1647cdf0e10cSrcweir if (!bFound)
1648cdf0e10cSrcweir {
1649cdf0e10cSrcweir // If all hits didn't result in a moving limit there's something
1650cdf0e10cSrcweir // strange, e.g. data range not properly sorted, or only identical
1651cdf0e10cSrcweir // values encountered, which doesn't mean there aren't any others in
1652cdf0e10cSrcweir // between.. leave it to GetThis(). The condition for this would be
1653cdf0e10cSrcweir // if (nLastInRange == nFirstLastInRange) nLo = nFirstLastInRange;
1654cdf0e10cSrcweir // Else, in case no exact match was found, we step back for a
1655cdf0e10cSrcweir // subsequent GetThis() to find the last in range. Effectively this is
1656cdf0e10cSrcweir // --nLo with nLastInRange == nLo-1. Both conditions combined yield:
1657cdf0e10cSrcweir nLo = nLastInRange;
1658cdf0e10cSrcweir }
1659cdf0e10cSrcweir if (nLo < pCol->nCount && pCol->pItems[nLo].nRow <= aParam.nRow2)
1660cdf0e10cSrcweir {
1661cdf0e10cSrcweir nRow = pItems[nLo].nRow;
1662cdf0e10cSrcweir pCell = pItems[nLo].pCell;
1663cdf0e10cSrcweir nColRow = nLo;
1664cdf0e10cSrcweir }
1665cdf0e10cSrcweir else
1666cdf0e10cSrcweir {
1667cdf0e10cSrcweir nRow = aParam.nRow2 + 1;
1668cdf0e10cSrcweir pCell = 0;
1669cdf0e10cSrcweir nColRow = pCol->nCount - 1;
1670cdf0e10cSrcweir }
1671cdf0e10cSrcweir return pCell;
1672cdf0e10cSrcweir }
1673cdf0e10cSrcweir
1674cdf0e10cSrcweir
1675cdf0e10cSrcweir //-------------------------------------------------------------------------------
1676cdf0e10cSrcweir
ScHorizontalCellIterator(ScDocument * pDocument,SCTAB nTable,SCCOL nCol1,SCROW nRow1,SCCOL nCol2,SCROW nRow2)1677cdf0e10cSrcweir ScHorizontalCellIterator::ScHorizontalCellIterator(ScDocument* pDocument, SCTAB nTable,
1678cdf0e10cSrcweir SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 ) :
1679cdf0e10cSrcweir pDoc( pDocument ),
1680cdf0e10cSrcweir nTab( nTable ),
1681cdf0e10cSrcweir nStartCol( nCol1 ),
1682cdf0e10cSrcweir nEndCol( nCol2 ),
1683cdf0e10cSrcweir nStartRow( nRow1 ),
1684cdf0e10cSrcweir nEndRow( nRow2 ),
1685cdf0e10cSrcweir nCol( nCol1 ),
1686cdf0e10cSrcweir nRow( nRow1 ),
1687cdf0e10cSrcweir bMore( sal_True )
1688cdf0e10cSrcweir {
1689cdf0e10cSrcweir
1690cdf0e10cSrcweir pNextRows = new SCROW[ nCol2-nCol1+1 ];
1691cdf0e10cSrcweir pNextIndices = new SCSIZE[ nCol2-nCol1+1 ];
1692cdf0e10cSrcweir
1693cdf0e10cSrcweir SetTab( nTab );
1694cdf0e10cSrcweir }
1695cdf0e10cSrcweir
~ScHorizontalCellIterator()1696cdf0e10cSrcweir ScHorizontalCellIterator::~ScHorizontalCellIterator()
1697cdf0e10cSrcweir {
1698cdf0e10cSrcweir delete [] pNextRows;
1699cdf0e10cSrcweir delete [] pNextIndices;
1700cdf0e10cSrcweir }
1701cdf0e10cSrcweir
SetTab(SCTAB nTabP)1702cdf0e10cSrcweir void ScHorizontalCellIterator::SetTab( SCTAB nTabP )
1703cdf0e10cSrcweir {
1704cdf0e10cSrcweir nTab = nTabP;
1705cdf0e10cSrcweir nRow = nStartRow;
1706cdf0e10cSrcweir nCol = nStartCol;
1707cdf0e10cSrcweir bMore = sal_True;
1708cdf0e10cSrcweir
1709cdf0e10cSrcweir for (SCCOL i=nStartCol; i<=nEndCol; i++)
1710cdf0e10cSrcweir {
1711cdf0e10cSrcweir ScColumn* pCol = &pDoc->pTab[nTab]->aCol[i];
1712cdf0e10cSrcweir
1713cdf0e10cSrcweir SCSIZE nIndex;
1714cdf0e10cSrcweir pCol->Search( nStartRow, nIndex );
1715cdf0e10cSrcweir if ( nIndex < pCol->nCount )
1716cdf0e10cSrcweir {
1717cdf0e10cSrcweir pNextRows[i-nStartCol] = pCol->pItems[nIndex].nRow;
1718cdf0e10cSrcweir pNextIndices[i-nStartCol] = nIndex;
1719cdf0e10cSrcweir }
1720cdf0e10cSrcweir else
1721cdf0e10cSrcweir {
1722cdf0e10cSrcweir pNextRows[i-nStartCol] = MAXROWCOUNT; // nichts gefunden
1723cdf0e10cSrcweir pNextIndices[i-nStartCol] = MAXROWCOUNT;
1724cdf0e10cSrcweir }
1725cdf0e10cSrcweir }
1726cdf0e10cSrcweir
1727cdf0e10cSrcweir if (pNextRows[0] != nStartRow)
1728cdf0e10cSrcweir Advance();
1729cdf0e10cSrcweir }
1730cdf0e10cSrcweir
GetNext(SCCOL & rCol,SCROW & rRow)1731cdf0e10cSrcweir ScBaseCell* ScHorizontalCellIterator::GetNext( SCCOL& rCol, SCROW& rRow )
1732cdf0e10cSrcweir {
1733cdf0e10cSrcweir if ( bMore )
1734cdf0e10cSrcweir {
1735cdf0e10cSrcweir rCol = nCol;
1736cdf0e10cSrcweir rRow = nRow;
1737cdf0e10cSrcweir
1738cdf0e10cSrcweir ScColumn* pCol = &pDoc->pTab[nTab]->aCol[nCol];
1739cdf0e10cSrcweir SCSIZE nIndex = pNextIndices[nCol-nStartCol];
1740cdf0e10cSrcweir DBG_ASSERT( nIndex < pCol->nCount, "ScHorizontalCellIterator::GetNext: nIndex out of range" );
1741cdf0e10cSrcweir ScBaseCell* pCell = pCol->pItems[nIndex].pCell;
1742cdf0e10cSrcweir if ( ++nIndex < pCol->nCount )
1743cdf0e10cSrcweir {
1744cdf0e10cSrcweir pNextRows[nCol-nStartCol] = pCol->pItems[nIndex].nRow;
1745cdf0e10cSrcweir pNextIndices[nCol-nStartCol] = nIndex;
1746cdf0e10cSrcweir }
1747cdf0e10cSrcweir else
1748cdf0e10cSrcweir {
1749cdf0e10cSrcweir pNextRows[nCol-nStartCol] = MAXROWCOUNT; // nichts gefunden
1750cdf0e10cSrcweir pNextIndices[nCol-nStartCol] = MAXROWCOUNT;
1751cdf0e10cSrcweir }
1752cdf0e10cSrcweir
1753cdf0e10cSrcweir Advance();
1754cdf0e10cSrcweir return pCell;
1755cdf0e10cSrcweir }
1756cdf0e10cSrcweir else
1757cdf0e10cSrcweir return NULL;
1758cdf0e10cSrcweir }
1759cdf0e10cSrcweir
ReturnNext(SCCOL & rCol,SCROW & rRow)1760cdf0e10cSrcweir sal_Bool ScHorizontalCellIterator::ReturnNext( SCCOL& rCol, SCROW& rRow )
1761cdf0e10cSrcweir {
1762cdf0e10cSrcweir rCol = nCol;
1763cdf0e10cSrcweir rRow = nRow;
1764cdf0e10cSrcweir return bMore;
1765cdf0e10cSrcweir }
1766cdf0e10cSrcweir
Advance()1767cdf0e10cSrcweir void ScHorizontalCellIterator::Advance()
1768cdf0e10cSrcweir {
1769cdf0e10cSrcweir sal_Bool bFound = sal_False;
1770cdf0e10cSrcweir SCCOL i;
1771cdf0e10cSrcweir
1772cdf0e10cSrcweir for (i=nCol+1; i<=nEndCol && !bFound; i++)
1773cdf0e10cSrcweir if (pNextRows[i-nStartCol] == nRow)
1774cdf0e10cSrcweir {
1775cdf0e10cSrcweir nCol = i;
1776cdf0e10cSrcweir bFound = sal_True;
1777cdf0e10cSrcweir }
1778cdf0e10cSrcweir
1779cdf0e10cSrcweir if (!bFound)
1780cdf0e10cSrcweir {
1781cdf0e10cSrcweir SCROW nMinRow = MAXROW+1;
1782cdf0e10cSrcweir for (i=nStartCol; i<=nEndCol; i++)
1783cdf0e10cSrcweir if (pNextRows[i-nStartCol] < nMinRow)
1784cdf0e10cSrcweir {
1785cdf0e10cSrcweir nCol = i;
1786cdf0e10cSrcweir nMinRow = pNextRows[i-nStartCol];
1787cdf0e10cSrcweir }
1788cdf0e10cSrcweir
1789cdf0e10cSrcweir if (nMinRow <= nEndRow)
1790cdf0e10cSrcweir {
1791cdf0e10cSrcweir nRow = nMinRow;
1792cdf0e10cSrcweir bFound = sal_True;
1793cdf0e10cSrcweir }
1794cdf0e10cSrcweir }
1795cdf0e10cSrcweir
1796cdf0e10cSrcweir if ( !bFound )
1797cdf0e10cSrcweir bMore = sal_False;
1798cdf0e10cSrcweir }
1799cdf0e10cSrcweir
1800cdf0e10cSrcweir //------------------------------------------------------------------------
1801cdf0e10cSrcweir
ScHorizontalValueIterator(ScDocument * pDocument,const ScRange & rRange,bool bSTotal,bool bTextZero)1802cdf0e10cSrcweir ScHorizontalValueIterator::ScHorizontalValueIterator( ScDocument* pDocument,
1803cdf0e10cSrcweir const ScRange& rRange, bool bSTotal, bool bTextZero ) :
1804cdf0e10cSrcweir pDoc( pDocument ),
1805cdf0e10cSrcweir nNumFmtIndex(0),
1806cdf0e10cSrcweir nEndTab( rRange.aEnd.Tab() ),
1807cdf0e10cSrcweir nNumFmtType( NUMBERFORMAT_UNDEFINED ),
1808cdf0e10cSrcweir bNumValid( false ),
1809cdf0e10cSrcweir bSubTotal( bSTotal ),
1810cdf0e10cSrcweir bCalcAsShown( pDocument->GetDocOptions().IsCalcAsShown() ),
1811cdf0e10cSrcweir bTextAsZero( bTextZero )
1812cdf0e10cSrcweir {
1813cdf0e10cSrcweir SCCOL nStartCol = rRange.aStart.Col();
1814cdf0e10cSrcweir SCROW nStartRow = rRange.aStart.Row();
1815cdf0e10cSrcweir SCTAB nStartTab = rRange.aStart.Tab();
1816cdf0e10cSrcweir SCCOL nEndCol = rRange.aEnd.Col();
1817cdf0e10cSrcweir SCROW nEndRow = rRange.aEnd.Row();
1818cdf0e10cSrcweir PutInOrder( nStartCol, nEndCol);
1819cdf0e10cSrcweir PutInOrder( nStartRow, nEndRow);
1820cdf0e10cSrcweir PutInOrder( nStartTab, nEndTab );
1821cdf0e10cSrcweir
1822cdf0e10cSrcweir if (!ValidCol(nStartCol)) nStartCol = MAXCOL;
1823cdf0e10cSrcweir if (!ValidCol(nEndCol)) nEndCol = MAXCOL;
1824cdf0e10cSrcweir if (!ValidRow(nStartRow)) nStartRow = MAXROW;
1825cdf0e10cSrcweir if (!ValidRow(nEndRow)) nEndRow = MAXROW;
1826cdf0e10cSrcweir if (!ValidTab(nStartTab)) nStartTab = MAXTAB;
1827cdf0e10cSrcweir if (!ValidTab(nEndTab)) nEndTab = MAXTAB;
1828cdf0e10cSrcweir
1829cdf0e10cSrcweir nCurCol = nStartCol;
1830cdf0e10cSrcweir nCurRow = nStartRow;
1831cdf0e10cSrcweir nCurTab = nStartTab;
1832cdf0e10cSrcweir
1833cdf0e10cSrcweir nNumFormat = 0; // will be initialized in GetNumberFormat()
1834cdf0e10cSrcweir pAttrArray = 0;
1835cdf0e10cSrcweir nAttrEndRow = 0;
1836cdf0e10cSrcweir
1837cdf0e10cSrcweir pCellIter = new ScHorizontalCellIterator( pDoc, nStartTab, nStartCol,
1838cdf0e10cSrcweir nStartRow, nEndCol, nEndRow );
1839cdf0e10cSrcweir }
1840cdf0e10cSrcweir
~ScHorizontalValueIterator()1841cdf0e10cSrcweir ScHorizontalValueIterator::~ScHorizontalValueIterator()
1842cdf0e10cSrcweir {
1843cdf0e10cSrcweir delete pCellIter;
1844cdf0e10cSrcweir }
1845cdf0e10cSrcweir
GetNext(double & rValue,sal_uInt16 & rErr)1846cdf0e10cSrcweir bool ScHorizontalValueIterator::GetNext( double& rValue, sal_uInt16& rErr )
1847cdf0e10cSrcweir {
1848cdf0e10cSrcweir bool bFound = false;
1849cdf0e10cSrcweir while ( !bFound )
1850cdf0e10cSrcweir {
1851cdf0e10cSrcweir ScBaseCell* pCell = pCellIter->GetNext( nCurCol, nCurRow );
1852cdf0e10cSrcweir while ( !pCell )
1853cdf0e10cSrcweir {
1854cdf0e10cSrcweir if ( nCurTab < nEndTab )
1855cdf0e10cSrcweir {
1856cdf0e10cSrcweir pCellIter->SetTab( ++nCurTab);
1857cdf0e10cSrcweir pCell = pCellIter->GetNext( nCurCol, nCurRow );
1858cdf0e10cSrcweir }
1859cdf0e10cSrcweir else
1860cdf0e10cSrcweir return false;
1861cdf0e10cSrcweir }
1862cdf0e10cSrcweir if ( !bSubTotal || !pDoc->pTab[nCurTab]->RowFiltered( nCurRow ) )
1863cdf0e10cSrcweir {
1864cdf0e10cSrcweir switch (pCell->GetCellType())
1865cdf0e10cSrcweir {
1866cdf0e10cSrcweir case CELLTYPE_VALUE:
1867cdf0e10cSrcweir {
1868cdf0e10cSrcweir bNumValid = false;
1869cdf0e10cSrcweir rValue = ((ScValueCell*)pCell)->GetValue();
1870cdf0e10cSrcweir rErr = 0;
1871cdf0e10cSrcweir if ( bCalcAsShown )
1872cdf0e10cSrcweir {
1873cdf0e10cSrcweir ScColumn* pCol = &pDoc->pTab[nCurTab]->aCol[nCurCol];
1874cdf0e10cSrcweir lcl_IterGetNumberFormat( nNumFormat, pAttrArray,
1875cdf0e10cSrcweir nAttrEndRow, pCol->pAttrArray, nCurRow, pDoc );
1876cdf0e10cSrcweir rValue = pDoc->RoundValueAsShown( rValue, nNumFormat );
1877cdf0e10cSrcweir }
1878cdf0e10cSrcweir bFound = true;
1879cdf0e10cSrcweir }
1880cdf0e10cSrcweir break;
1881cdf0e10cSrcweir case CELLTYPE_FORMULA:
1882cdf0e10cSrcweir {
1883cdf0e10cSrcweir if (!bSubTotal || !((ScFormulaCell*)pCell)->IsSubTotal())
1884cdf0e10cSrcweir {
1885cdf0e10cSrcweir rErr = ((ScFormulaCell*)pCell)->GetErrCode();
1886cdf0e10cSrcweir if ( rErr || ((ScFormulaCell*)pCell)->IsValue() )
1887cdf0e10cSrcweir {
1888cdf0e10cSrcweir rValue = ((ScFormulaCell*)pCell)->GetValue();
1889cdf0e10cSrcweir bNumValid = false;
1890cdf0e10cSrcweir bFound = true;
1891cdf0e10cSrcweir }
1892cdf0e10cSrcweir else if ( bTextAsZero )
1893cdf0e10cSrcweir {
1894cdf0e10cSrcweir rValue = 0.0;
1895cdf0e10cSrcweir bNumValid = false;
1896cdf0e10cSrcweir bFound = true;
1897cdf0e10cSrcweir }
1898cdf0e10cSrcweir }
1899cdf0e10cSrcweir }
1900cdf0e10cSrcweir break;
1901cdf0e10cSrcweir case CELLTYPE_STRING :
1902cdf0e10cSrcweir case CELLTYPE_EDIT :
1903cdf0e10cSrcweir {
1904cdf0e10cSrcweir if ( bTextAsZero )
1905cdf0e10cSrcweir {
1906cdf0e10cSrcweir rErr = 0;
1907cdf0e10cSrcweir rValue = 0.0;
1908cdf0e10cSrcweir nNumFmtType = NUMBERFORMAT_NUMBER;
1909cdf0e10cSrcweir nNumFmtIndex = 0;
1910cdf0e10cSrcweir bNumValid = true;
1911cdf0e10cSrcweir bFound = true;
1912cdf0e10cSrcweir }
1913cdf0e10cSrcweir }
1914cdf0e10cSrcweir break;
1915cdf0e10cSrcweir default:
1916cdf0e10cSrcweir ; // nothing
1917cdf0e10cSrcweir }
1918cdf0e10cSrcweir }
1919cdf0e10cSrcweir }
1920cdf0e10cSrcweir return bFound;
1921cdf0e10cSrcweir }
1922cdf0e10cSrcweir
GetCurNumFmtInfo(short & nType,sal_uLong & nIndex)1923cdf0e10cSrcweir void ScHorizontalValueIterator::GetCurNumFmtInfo( short& nType, sal_uLong& nIndex )
1924cdf0e10cSrcweir {
1925cdf0e10cSrcweir if (!bNumValid)
1926cdf0e10cSrcweir {
1927cdf0e10cSrcweir const ScColumn* pCol = &(pDoc->pTab[nCurTab])->aCol[nCurCol];
1928cdf0e10cSrcweir nNumFmtIndex = pCol->GetNumberFormat( nCurRow );
1929cdf0e10cSrcweir if ( (nNumFmtIndex % SV_COUNTRY_LANGUAGE_OFFSET) == 0 )
1930cdf0e10cSrcweir {
1931cdf0e10cSrcweir const ScBaseCell* pCell;
1932cdf0e10cSrcweir SCSIZE nCurIndex;
1933cdf0e10cSrcweir if ( pCol->Search( nCurRow, nCurIndex ) )
1934cdf0e10cSrcweir pCell = pCol->pItems[nCurIndex].pCell;
1935cdf0e10cSrcweir else
1936cdf0e10cSrcweir pCell = NULL;
1937cdf0e10cSrcweir if ( pCell && pCell->GetCellType() == CELLTYPE_FORMULA )
1938cdf0e10cSrcweir ((const ScFormulaCell*)pCell)->GetFormatInfo( nNumFmtType, nNumFmtIndex );
1939cdf0e10cSrcweir else
1940cdf0e10cSrcweir nNumFmtType = pDoc->GetFormatTable()->GetType( nNumFmtIndex );
1941cdf0e10cSrcweir }
1942cdf0e10cSrcweir else
1943cdf0e10cSrcweir nNumFmtType = pDoc->GetFormatTable()->GetType( nNumFmtIndex );
1944cdf0e10cSrcweir bNumValid = true;
1945cdf0e10cSrcweir }
1946cdf0e10cSrcweir nType = nNumFmtType;
1947cdf0e10cSrcweir nIndex = nNumFmtIndex;
1948cdf0e10cSrcweir }
1949cdf0e10cSrcweir
1950cdf0e10cSrcweir //-------------------------------------------------------------------------------
1951cdf0e10cSrcweir
ScHorizontalAttrIterator(ScDocument * pDocument,SCTAB nTable,SCCOL nCol1,SCROW nRow1,SCCOL nCol2,SCROW nRow2)1952cdf0e10cSrcweir ScHorizontalAttrIterator::ScHorizontalAttrIterator( ScDocument* pDocument, SCTAB nTable,
1953cdf0e10cSrcweir SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 ) :
1954cdf0e10cSrcweir pDoc( pDocument ),
1955cdf0e10cSrcweir nTab( nTable ),
1956cdf0e10cSrcweir nStartCol( nCol1 ),
1957cdf0e10cSrcweir nStartRow( nRow1 ),
1958cdf0e10cSrcweir nEndCol( nCol2 ),
1959cdf0e10cSrcweir nEndRow( nRow2 )
1960cdf0e10cSrcweir {
1961cdf0e10cSrcweir DBG_ASSERT( pDoc->pTab[nTab], "Tabelle nicht da" );
1962cdf0e10cSrcweir
1963cdf0e10cSrcweir SCCOL i;
1964cdf0e10cSrcweir
1965cdf0e10cSrcweir nRow = nStartRow;
1966cdf0e10cSrcweir nCol = nStartCol;
1967cdf0e10cSrcweir bRowEmpty = sal_False;
1968cdf0e10cSrcweir
1969cdf0e10cSrcweir pIndices = new SCSIZE[nEndCol-nStartCol+1];
1970cdf0e10cSrcweir pNextEnd = new SCROW[nEndCol-nStartCol+1];
1971cdf0e10cSrcweir ppPatterns = new const ScPatternAttr*[nEndCol-nStartCol+1];
1972cdf0e10cSrcweir
1973cdf0e10cSrcweir SCROW nSkipTo = MAXROW;
1974cdf0e10cSrcweir sal_Bool bEmpty = sal_True;
1975cdf0e10cSrcweir for (i=nStartCol; i<=nEndCol; i++)
1976cdf0e10cSrcweir {
1977cdf0e10cSrcweir SCCOL nPos = i - nStartCol;
1978cdf0e10cSrcweir ScAttrArray* pArray = pDoc->pTab[nTab]->aCol[i].pAttrArray;
1979cdf0e10cSrcweir DBG_ASSERT( pArray, "pArray == 0" );
1980cdf0e10cSrcweir
1981cdf0e10cSrcweir SCSIZE nIndex;
1982cdf0e10cSrcweir pArray->Search( nStartRow, nIndex );
1983cdf0e10cSrcweir
1984cdf0e10cSrcweir const ScPatternAttr* pPattern = pArray->pData[nIndex].pPattern;
1985cdf0e10cSrcweir SCROW nThisEnd = pArray->pData[nIndex].nRow;
1986cdf0e10cSrcweir if ( IsDefaultItem( pPattern ) )
1987cdf0e10cSrcweir {
1988cdf0e10cSrcweir pPattern = NULL;
1989cdf0e10cSrcweir if ( nThisEnd < nSkipTo )
1990cdf0e10cSrcweir nSkipTo = nThisEnd; // nSkipTo kann gleich hier gesetzt werden
1991cdf0e10cSrcweir }
1992cdf0e10cSrcweir else
1993cdf0e10cSrcweir bEmpty = sal_False; // Attribute gefunden
1994cdf0e10cSrcweir
1995cdf0e10cSrcweir pIndices[nPos] = nIndex;
1996cdf0e10cSrcweir pNextEnd[nPos] = nThisEnd;
1997cdf0e10cSrcweir ppPatterns[nPos] = pPattern;
1998cdf0e10cSrcweir }
1999cdf0e10cSrcweir
2000cdf0e10cSrcweir if (bEmpty)
2001cdf0e10cSrcweir nRow = nSkipTo; // bis zum naechsten Bereichsende ueberspringen
2002cdf0e10cSrcweir bRowEmpty = bEmpty;
2003cdf0e10cSrcweir }
2004cdf0e10cSrcweir
~ScHorizontalAttrIterator()2005cdf0e10cSrcweir ScHorizontalAttrIterator::~ScHorizontalAttrIterator()
2006cdf0e10cSrcweir {
2007cdf0e10cSrcweir delete[] (ScPatternAttr**)ppPatterns;
2008cdf0e10cSrcweir delete[] pNextEnd;
2009cdf0e10cSrcweir delete[] pIndices;
2010cdf0e10cSrcweir }
2011cdf0e10cSrcweir
GetNext(SCCOL & rCol1,SCCOL & rCol2,SCROW & rRow)2012cdf0e10cSrcweir const ScPatternAttr* ScHorizontalAttrIterator::GetNext( SCCOL& rCol1, SCCOL& rCol2, SCROW& rRow )
2013cdf0e10cSrcweir {
2014cdf0e10cSrcweir for (;;)
2015cdf0e10cSrcweir {
2016cdf0e10cSrcweir if (!bRowEmpty)
2017cdf0e10cSrcweir {
2018cdf0e10cSrcweir // in dieser Zeile suchen
2019cdf0e10cSrcweir
2020cdf0e10cSrcweir while ( nCol <= nEndCol && !ppPatterns[nCol-nStartCol] )
2021cdf0e10cSrcweir ++nCol;
2022cdf0e10cSrcweir
2023cdf0e10cSrcweir if ( nCol <= nEndCol )
2024cdf0e10cSrcweir {
2025cdf0e10cSrcweir const ScPatternAttr* pPat = ppPatterns[nCol-nStartCol];
2026cdf0e10cSrcweir rRow = nRow;
2027cdf0e10cSrcweir rCol1 = nCol;
2028cdf0e10cSrcweir while ( nCol < nEndCol && ppPatterns[nCol+1-nStartCol] == pPat )
2029cdf0e10cSrcweir ++nCol;
2030cdf0e10cSrcweir rCol2 = nCol;
2031cdf0e10cSrcweir ++nCol; // hochzaehlen fuer naechsten Aufruf
2032cdf0e10cSrcweir return pPat; // gefunden
2033cdf0e10cSrcweir }
2034cdf0e10cSrcweir }
2035cdf0e10cSrcweir
2036cdf0e10cSrcweir // naechste Zeile
2037cdf0e10cSrcweir
2038cdf0e10cSrcweir ++nRow;
2039cdf0e10cSrcweir if ( nRow > nEndRow ) // schon am Ende?
2040cdf0e10cSrcweir return NULL; // nichts gefunden
2041cdf0e10cSrcweir
2042cdf0e10cSrcweir sal_Bool bEmpty = sal_True;
2043cdf0e10cSrcweir SCCOL i;
2044cdf0e10cSrcweir
2045cdf0e10cSrcweir for ( i = nStartCol; i <= nEndCol; i++)
2046cdf0e10cSrcweir {
2047cdf0e10cSrcweir SCCOL nPos = i-nStartCol;
2048cdf0e10cSrcweir if ( pNextEnd[nPos] < nRow )
2049cdf0e10cSrcweir {
2050cdf0e10cSrcweir ScAttrArray* pArray = pDoc->pTab[nTab]->aCol[i].pAttrArray;
2051cdf0e10cSrcweir
2052cdf0e10cSrcweir SCSIZE nIndex = ++pIndices[nPos];
2053cdf0e10cSrcweir if ( nIndex < pArray->nCount )
2054cdf0e10cSrcweir {
2055cdf0e10cSrcweir const ScPatternAttr* pPattern = pArray->pData[nIndex].pPattern;
2056cdf0e10cSrcweir SCROW nThisEnd = pArray->pData[nIndex].nRow;
2057cdf0e10cSrcweir if ( IsDefaultItem( pPattern ) )
2058cdf0e10cSrcweir pPattern = NULL;
2059cdf0e10cSrcweir else
2060cdf0e10cSrcweir bEmpty = sal_False; // Attribute gefunden
2061cdf0e10cSrcweir
2062cdf0e10cSrcweir pNextEnd[nPos] = nThisEnd;
2063cdf0e10cSrcweir ppPatterns[nPos] = pPattern;
2064cdf0e10cSrcweir
2065cdf0e10cSrcweir DBG_ASSERT( pNextEnd[nPos] >= nRow, "Reihenfolge durcheinander" );
2066cdf0e10cSrcweir }
2067cdf0e10cSrcweir else
2068cdf0e10cSrcweir {
2069cdf0e10cSrcweir DBG_ERROR("AttrArray reicht nicht bis MAXROW");
2070cdf0e10cSrcweir pNextEnd[nPos] = MAXROW;
2071cdf0e10cSrcweir ppPatterns[nPos] = NULL;
2072cdf0e10cSrcweir }
2073cdf0e10cSrcweir }
2074cdf0e10cSrcweir else if ( ppPatterns[nPos] )
2075cdf0e10cSrcweir bEmpty = sal_False; // Bereich noch nicht zuende
2076cdf0e10cSrcweir }
2077cdf0e10cSrcweir
2078cdf0e10cSrcweir if (bEmpty)
2079cdf0e10cSrcweir {
2080cdf0e10cSrcweir SCCOL nCount = nEndCol-nStartCol+1;
2081cdf0e10cSrcweir SCROW nSkipTo = pNextEnd[0]; // naechstes Bereichsende suchen
2082cdf0e10cSrcweir for (i=1; i<nCount; i++)
2083cdf0e10cSrcweir if ( pNextEnd[i] < nSkipTo )
2084cdf0e10cSrcweir nSkipTo = pNextEnd[i];
2085cdf0e10cSrcweir nRow = nSkipTo; // leere Zeilen ueberspringen
2086cdf0e10cSrcweir }
2087cdf0e10cSrcweir bRowEmpty = bEmpty;
2088cdf0e10cSrcweir nCol = nStartCol; // wieder links anfangen
2089cdf0e10cSrcweir }
2090cdf0e10cSrcweir
2091cdf0e10cSrcweir // return NULL;
2092cdf0e10cSrcweir }
2093cdf0e10cSrcweir
2094cdf0e10cSrcweir //-------------------------------------------------------------------------------
2095cdf0e10cSrcweir
IsGreater(SCCOL nCol1,SCROW nRow1,SCCOL nCol2,SCROW nRow2)2096cdf0e10cSrcweir inline sal_Bool IsGreater( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 )
2097cdf0e10cSrcweir {
2098cdf0e10cSrcweir return ( nRow1 > nRow2 ) || ( nRow1 == nRow2 && nCol1 > nCol2 );
2099cdf0e10cSrcweir }
2100cdf0e10cSrcweir
ScUsedAreaIterator(ScDocument * pDocument,SCTAB nTable,SCCOL nCol1,SCROW nRow1,SCCOL nCol2,SCROW nRow2)2101cdf0e10cSrcweir ScUsedAreaIterator::ScUsedAreaIterator( ScDocument* pDocument, SCTAB nTable,
2102cdf0e10cSrcweir SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 ) :
2103cdf0e10cSrcweir aCellIter( pDocument, nTable, nCol1, nRow1, nCol2, nRow2 ),
2104cdf0e10cSrcweir aAttrIter( pDocument, nTable, nCol1, nRow1, nCol2, nRow2 ),
2105cdf0e10cSrcweir nNextCol( nCol1 ),
2106cdf0e10cSrcweir nNextRow( nRow1 )
2107cdf0e10cSrcweir {
2108cdf0e10cSrcweir pCell = aCellIter.GetNext( nCellCol, nCellRow );
2109cdf0e10cSrcweir pPattern = aAttrIter.GetNext( nAttrCol1, nAttrCol2, nAttrRow );
2110cdf0e10cSrcweir }
2111cdf0e10cSrcweir
~ScUsedAreaIterator()2112cdf0e10cSrcweir ScUsedAreaIterator::~ScUsedAreaIterator()
2113cdf0e10cSrcweir {
2114cdf0e10cSrcweir }
2115cdf0e10cSrcweir
GetNext()2116cdf0e10cSrcweir sal_Bool ScUsedAreaIterator::GetNext()
2117cdf0e10cSrcweir {
2118cdf0e10cSrcweir // Iteratoren weiterzaehlen
2119cdf0e10cSrcweir
2120cdf0e10cSrcweir if ( pCell && IsGreater( nNextCol, nNextRow, nCellCol, nCellRow ) )
2121cdf0e10cSrcweir pCell = aCellIter.GetNext( nCellCol, nCellRow );
2122cdf0e10cSrcweir
2123cdf0e10cSrcweir while ( pCell && pCell->IsBlank() )
2124cdf0e10cSrcweir pCell = aCellIter.GetNext( nCellCol, nCellRow );
2125cdf0e10cSrcweir
2126cdf0e10cSrcweir if ( pPattern && IsGreater( nNextCol, nNextRow, nAttrCol2, nAttrRow ) )
2127cdf0e10cSrcweir pPattern = aAttrIter.GetNext( nAttrCol1, nAttrCol2, nAttrRow );
2128cdf0e10cSrcweir
2129cdf0e10cSrcweir if ( pPattern && nAttrRow == nNextRow && nAttrCol1 < nNextCol )
2130cdf0e10cSrcweir nAttrCol1 = nNextCol;
2131cdf0e10cSrcweir
2132cdf0e10cSrcweir // naechsten Abschnitt heraussuchen
2133cdf0e10cSrcweir
2134cdf0e10cSrcweir sal_Bool bFound = sal_True;
2135cdf0e10cSrcweir sal_Bool bUseCell = sal_False;
2136cdf0e10cSrcweir
2137cdf0e10cSrcweir if ( pCell && pPattern )
2138cdf0e10cSrcweir {
2139cdf0e10cSrcweir if ( IsGreater( nCellCol, nCellRow, nAttrCol1, nAttrRow ) ) // vorne nur Attribute ?
2140cdf0e10cSrcweir {
2141cdf0e10cSrcweir pFoundCell = NULL;
2142cdf0e10cSrcweir pFoundPattern = pPattern;
2143cdf0e10cSrcweir nFoundRow = nAttrRow;
2144cdf0e10cSrcweir nFoundStartCol = nAttrCol1;
2145cdf0e10cSrcweir if ( nCellRow == nAttrRow && nCellCol <= nAttrCol2 ) // auch Zelle im Bereich ?
2146cdf0e10cSrcweir nFoundEndCol = nCellCol - 1; // nur bis vor der Zelle
2147cdf0e10cSrcweir else
2148cdf0e10cSrcweir nFoundEndCol = nAttrCol2; // alles
2149cdf0e10cSrcweir }
2150cdf0e10cSrcweir else
2151cdf0e10cSrcweir {
2152cdf0e10cSrcweir bUseCell = sal_True;
2153cdf0e10cSrcweir if ( nAttrRow == nCellRow && nAttrCol1 == nCellCol ) // Attribute auf der Zelle ?
2154cdf0e10cSrcweir pFoundPattern = pPattern;
2155cdf0e10cSrcweir else
2156cdf0e10cSrcweir pFoundPattern = NULL;
2157cdf0e10cSrcweir }
2158cdf0e10cSrcweir }
2159cdf0e10cSrcweir else if ( pCell ) // nur Zelle -> direkt uebernehmen
2160cdf0e10cSrcweir {
2161cdf0e10cSrcweir pFoundPattern = NULL;
2162cdf0e10cSrcweir bUseCell = sal_True; // Position von Zelle
2163cdf0e10cSrcweir }
2164cdf0e10cSrcweir else if ( pPattern ) // nur Attribute -> direkt uebernehmen
2165cdf0e10cSrcweir {
2166cdf0e10cSrcweir pFoundCell = NULL;
2167cdf0e10cSrcweir pFoundPattern = pPattern;
2168cdf0e10cSrcweir nFoundRow = nAttrRow;
2169cdf0e10cSrcweir nFoundStartCol = nAttrCol1;
2170cdf0e10cSrcweir nFoundEndCol = nAttrCol2;
2171cdf0e10cSrcweir }
2172cdf0e10cSrcweir else // gar nichts
2173cdf0e10cSrcweir bFound = sal_False;
2174cdf0e10cSrcweir
2175cdf0e10cSrcweir if ( bUseCell ) // Position von Zelle
2176cdf0e10cSrcweir {
2177cdf0e10cSrcweir pFoundCell = pCell;
2178cdf0e10cSrcweir nFoundRow = nCellRow;
2179cdf0e10cSrcweir nFoundStartCol = nFoundEndCol = nCellCol;
2180cdf0e10cSrcweir }
2181cdf0e10cSrcweir
2182cdf0e10cSrcweir if (bFound)
2183cdf0e10cSrcweir {
2184cdf0e10cSrcweir nNextRow = nFoundRow;
2185cdf0e10cSrcweir nNextCol = nFoundEndCol + 1;
2186cdf0e10cSrcweir }
2187cdf0e10cSrcweir
2188cdf0e10cSrcweir return bFound;
2189cdf0e10cSrcweir }
2190cdf0e10cSrcweir
2191cdf0e10cSrcweir //-------------------------------------------------------------------------------
2192cdf0e10cSrcweir
ScDocAttrIterator(ScDocument * pDocument,SCTAB nTable,SCCOL nCol1,SCROW nRow1,SCCOL nCol2,SCROW nRow2)2193cdf0e10cSrcweir ScDocAttrIterator::ScDocAttrIterator(ScDocument* pDocument, SCTAB nTable,
2194cdf0e10cSrcweir SCCOL nCol1, SCROW nRow1,
2195cdf0e10cSrcweir SCCOL nCol2, SCROW nRow2) :
2196cdf0e10cSrcweir pDoc( pDocument ),
2197cdf0e10cSrcweir nTab( nTable ),
2198cdf0e10cSrcweir nEndCol( nCol2 ),
2199cdf0e10cSrcweir nStartRow( nRow1 ),
2200cdf0e10cSrcweir nEndRow( nRow2 ),
2201cdf0e10cSrcweir nCol( nCol1 )
2202cdf0e10cSrcweir {
2203cdf0e10cSrcweir if ( ValidTab(nTab) && pDoc->pTab[nTab] )
2204cdf0e10cSrcweir pColIter = pDoc->pTab[nTab]->aCol[nCol].CreateAttrIterator( nStartRow, nEndRow );
2205cdf0e10cSrcweir else
2206cdf0e10cSrcweir pColIter = NULL;
2207cdf0e10cSrcweir }
2208cdf0e10cSrcweir
~ScDocAttrIterator()2209cdf0e10cSrcweir ScDocAttrIterator::~ScDocAttrIterator()
2210cdf0e10cSrcweir {
2211cdf0e10cSrcweir delete pColIter;
2212cdf0e10cSrcweir }
2213cdf0e10cSrcweir
GetNext(SCCOL & rCol,SCROW & rRow1,SCROW & rRow2)2214cdf0e10cSrcweir const ScPatternAttr* ScDocAttrIterator::GetNext( SCCOL& rCol, SCROW& rRow1, SCROW& rRow2 )
2215cdf0e10cSrcweir {
2216cdf0e10cSrcweir while ( pColIter )
2217cdf0e10cSrcweir {
2218cdf0e10cSrcweir const ScPatternAttr* pPattern = pColIter->Next( rRow1, rRow2 );
2219cdf0e10cSrcweir if ( pPattern )
2220cdf0e10cSrcweir {
2221cdf0e10cSrcweir rCol = nCol;
2222cdf0e10cSrcweir return pPattern;
2223cdf0e10cSrcweir }
2224cdf0e10cSrcweir
2225cdf0e10cSrcweir delete pColIter;
2226cdf0e10cSrcweir ++nCol;
2227cdf0e10cSrcweir if ( nCol <= nEndCol )
2228cdf0e10cSrcweir pColIter = pDoc->pTab[nTab]->aCol[nCol].CreateAttrIterator( nStartRow, nEndRow );
2229cdf0e10cSrcweir else
2230cdf0e10cSrcweir pColIter = NULL;
2231cdf0e10cSrcweir }
2232cdf0e10cSrcweir return NULL; // is nix mehr
2233cdf0e10cSrcweir }
2234cdf0e10cSrcweir
2235cdf0e10cSrcweir //-------------------------------------------------------------------------------
2236cdf0e10cSrcweir
ScAttrRectIterator(ScDocument * pDocument,SCTAB nTable,SCCOL nCol1,SCROW nRow1,SCCOL nCol2,SCROW nRow2)2237cdf0e10cSrcweir ScAttrRectIterator::ScAttrRectIterator(ScDocument* pDocument, SCTAB nTable,
2238cdf0e10cSrcweir SCCOL nCol1, SCROW nRow1,
2239cdf0e10cSrcweir SCCOL nCol2, SCROW nRow2) :
2240cdf0e10cSrcweir pDoc( pDocument ),
2241cdf0e10cSrcweir nTab( nTable ),
2242cdf0e10cSrcweir nEndCol( nCol2 ),
2243cdf0e10cSrcweir nStartRow( nRow1 ),
2244cdf0e10cSrcweir nEndRow( nRow2 ),
2245cdf0e10cSrcweir nIterStartCol( nCol1 ),
2246cdf0e10cSrcweir nIterEndCol( nCol1 )
2247cdf0e10cSrcweir {
2248cdf0e10cSrcweir if ( ValidTab(nTab) && pDoc->pTab[nTab] )
2249cdf0e10cSrcweir {
2250cdf0e10cSrcweir pColIter = pDoc->pTab[nTab]->aCol[nIterStartCol].CreateAttrIterator( nStartRow, nEndRow );
2251cdf0e10cSrcweir while ( nIterEndCol < nEndCol &&
2252cdf0e10cSrcweir pDoc->pTab[nTab]->aCol[nIterEndCol].IsAllAttrEqual(
2253cdf0e10cSrcweir pDoc->pTab[nTab]->aCol[nIterEndCol+1], nStartRow, nEndRow ) )
2254cdf0e10cSrcweir ++nIterEndCol;
2255cdf0e10cSrcweir }
2256cdf0e10cSrcweir else
2257cdf0e10cSrcweir pColIter = NULL;
2258cdf0e10cSrcweir }
2259cdf0e10cSrcweir
~ScAttrRectIterator()2260cdf0e10cSrcweir ScAttrRectIterator::~ScAttrRectIterator()
2261cdf0e10cSrcweir {
2262cdf0e10cSrcweir delete pColIter;
2263cdf0e10cSrcweir }
2264cdf0e10cSrcweir
DataChanged()2265cdf0e10cSrcweir void ScAttrRectIterator::DataChanged()
2266cdf0e10cSrcweir {
2267cdf0e10cSrcweir if (pColIter)
2268cdf0e10cSrcweir {
2269cdf0e10cSrcweir SCROW nNextRow = pColIter->GetNextRow();
2270cdf0e10cSrcweir delete pColIter;
2271cdf0e10cSrcweir pColIter = pDoc->pTab[nTab]->aCol[nIterStartCol].CreateAttrIterator( nNextRow, nEndRow );
2272cdf0e10cSrcweir }
2273cdf0e10cSrcweir }
2274cdf0e10cSrcweir
GetNext(SCCOL & rCol1,SCCOL & rCol2,SCROW & rRow1,SCROW & rRow2)2275cdf0e10cSrcweir const ScPatternAttr* ScAttrRectIterator::GetNext( SCCOL& rCol1, SCCOL& rCol2,
2276cdf0e10cSrcweir SCROW& rRow1, SCROW& rRow2 )
2277cdf0e10cSrcweir {
2278cdf0e10cSrcweir while ( pColIter )
2279cdf0e10cSrcweir {
2280cdf0e10cSrcweir const ScPatternAttr* pPattern = pColIter->Next( rRow1, rRow2 );
2281cdf0e10cSrcweir if ( pPattern )
2282cdf0e10cSrcweir {
2283cdf0e10cSrcweir rCol1 = nIterStartCol;
2284cdf0e10cSrcweir rCol2 = nIterEndCol;
2285cdf0e10cSrcweir return pPattern;
2286cdf0e10cSrcweir }
2287cdf0e10cSrcweir
2288cdf0e10cSrcweir delete pColIter;
2289cdf0e10cSrcweir nIterStartCol = nIterEndCol+1;
2290cdf0e10cSrcweir if ( nIterStartCol <= nEndCol )
2291cdf0e10cSrcweir {
2292cdf0e10cSrcweir nIterEndCol = nIterStartCol;
2293cdf0e10cSrcweir pColIter = pDoc->pTab[nTab]->aCol[nIterStartCol].CreateAttrIterator( nStartRow, nEndRow );
2294cdf0e10cSrcweir while ( nIterEndCol < nEndCol &&
2295cdf0e10cSrcweir pDoc->pTab[nTab]->aCol[nIterEndCol].IsAllAttrEqual(
2296cdf0e10cSrcweir pDoc->pTab[nTab]->aCol[nIterEndCol+1], nStartRow, nEndRow ) )
2297cdf0e10cSrcweir ++nIterEndCol;
2298cdf0e10cSrcweir }
2299cdf0e10cSrcweir else
2300cdf0e10cSrcweir pColIter = NULL;
2301cdf0e10cSrcweir }
2302cdf0e10cSrcweir return NULL; // is nix mehr
2303cdf0e10cSrcweir }
2304cdf0e10cSrcweir
2305cdf0e10cSrcweir // ============================================================================
2306cdf0e10cSrcweir
2307cdf0e10cSrcweir SCROW ScRowBreakIterator::NOT_FOUND = -1;
2308cdf0e10cSrcweir
ScRowBreakIterator(set<SCROW> & rBreaks)2309cdf0e10cSrcweir ScRowBreakIterator::ScRowBreakIterator(set<SCROW>& rBreaks) :
2310cdf0e10cSrcweir mrBreaks(rBreaks),
2311cdf0e10cSrcweir maItr(rBreaks.begin()), maEnd(rBreaks.end())
2312cdf0e10cSrcweir {
2313cdf0e10cSrcweir }
2314cdf0e10cSrcweir
first()2315cdf0e10cSrcweir SCROW ScRowBreakIterator::first()
2316cdf0e10cSrcweir {
2317cdf0e10cSrcweir maItr = mrBreaks.begin();
2318cdf0e10cSrcweir return maItr == maEnd ? NOT_FOUND : *maItr;
2319cdf0e10cSrcweir }
2320cdf0e10cSrcweir
next()2321cdf0e10cSrcweir SCROW ScRowBreakIterator::next()
2322cdf0e10cSrcweir {
2323cdf0e10cSrcweir ++maItr;
2324cdf0e10cSrcweir return maItr == maEnd ? NOT_FOUND : *maItr;
2325cdf0e10cSrcweir }
2326