update ooo310-m15
[ooovba.git] / sc / source / core / data / pivot.cxx
blob80571d47d7c430fa8bcef087da4c439a2e8ee48d
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: pivot.cxx,v $
10 * $Revision: 1.13 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sc.hxx"
36 // -----------------------------------------------------------------------
37 #if OLD_PIVOT_IMPLEMENTATION
38 #ifdef _MSC_VER
39 #pragma optimize("",off)
40 #endif
42 // INCLUDE ---------------------------------------------------------------
44 #include <svtools/zforlist.hxx>
45 #include <tools/solar.h>
47 #include "globstr.hrc"
48 #include "global.hxx"
49 #include "subtotal.hxx"
50 #include "scitems.hxx"
51 #include "attrib.hxx"
52 #include "patattr.hxx"
53 #include "docpool.hxx"
54 #include "document.hxx"
55 #include "userlist.hxx"
56 #include "pivot.hxx"
57 #include "cell.hxx"
58 #include "rechead.hxx"
59 #include "compiler.hxx" // fuer errNoValue
60 #include "progress.hxx"
62 #include <string.h>
63 #include <math.h>
65 // STATIC DATA -----------------------------------------------------------
67 //! bei Gelegenheit...
69 static short nStaticStrRefCount = 0;
70 static String* pLabel[PIVOT_MAXFUNC+1]; // incl. "auto"
71 static String* pLabelTotal;
72 static String* pLabelData;
74 static SCSIZE nDataMult = 1;
76 #define nFirstLine 2
78 static const USHORT nFuncMaskArr[PIVOT_MAXFUNC+1] =
79 { PIVOT_FUNC_SUM,
80 PIVOT_FUNC_COUNT,
81 PIVOT_FUNC_AVERAGE,
82 PIVOT_FUNC_MAX,
83 PIVOT_FUNC_MIN,
84 PIVOT_FUNC_PRODUCT,
85 PIVOT_FUNC_COUNT_NUM,
86 PIVOT_FUNC_STD_DEV,
87 PIVOT_FUNC_STD_DEVP,
88 PIVOT_FUNC_STD_VAR,
89 PIVOT_FUNC_STD_VARP,
90 PIVOT_FUNC_AUTO }; // automatisch
92 // -----------------------------------------------------------------------
94 // 1 Filter-Knopf
95 // 2 Feldnamen links
96 // 3 "Daten" links
97 // 4 Feldnamen oben
98 // 5 "Daten" oben
99 // 6 einzelne "Gesamt" oben rechts
100 // 7 "Gesamt" oben rechts
101 // 8 einzelne "Gesamt" unten links
102 // 9 "Gesamt" unten links
103 // 10 innere Kategorie links
104 // 11 Teilergebnis Label einzeln links
105 // 12 Teilergebnis Label gesamt links
106 // 13 letzte Kategorie links
107 // 14 innere Kategorie oben
108 // 15 Teilergebnis Label einzeln oben
109 // 16 Teilergebnis Label gesamt oben
110 // 17 letzte Kategorie oben
111 // 18 Werte innen
112 // 19 Werte in Teilergebnisspalte
113 // 20 Werte in Gesamt-Spalte
114 // 21 Werte in einzelnen Gesamt-Spalten
115 // 22 Werte in Ergebnis-Zeile Teilergebnis oder Gesamt
116 // 23 Kreuzung von Spalte/Zeile (Teilergebnis-Spalte)
117 // 24 Kreuzung von Spalte/Zeile (Gesamt-Spalte)
118 // 25 wie 24 bei einzelnen "Gesamt"
120 SCSIZE lcl_MaskToIndex( USHORT nFuncMask )
122 SCSIZE i;
123 for (i=0; i<=PIVOT_MAXFUNC; i++)
124 if (nFuncMask == nFuncMaskArr[i])
125 return i;
127 DBG_ERROR("Falsche Maske in MaskToIndex");
128 return 0;
131 BOOL lcl_IsEmptyLine( ScDocument* pDoc, const ScAddress& rPos, SCCOL nCol2 )
133 //! ans Document verschieben !!!
135 ScAddress aAdr( rPos );
136 for (SCCOL nCol=aAdr.Col(); nCol<=nCol2; nCol++)
138 aAdr.SetCol( nCol );
139 if ( pDoc->GetCell( aAdr ) )
140 return FALSE;
142 return TRUE;
145 ScPivot::ScPivot(ScDocument* pDocument) :
146 pDoc (pDocument),
147 aQuery (),
148 bHasHeader (FALSE),
149 bIgnoreEmpty (FALSE),
150 bDetectCat (FALSE),
151 bMakeTotalCol (TRUE),
152 bMakeTotalRow (TRUE),
153 nColNameCount (0),
154 pColNames (NULL),
155 nSrcCol1 (0),
156 nSrcRow1 (0),
157 nSrcCol2 (0),
158 nSrcRow2 (0),
159 nSrcTab (0),
160 nDestCol1 (0),
161 nDestRow1 (0),
162 nDestCol2 (0),
163 nDestRow2 (0),
164 nDestTab (0),
165 nDataStartCol (0),
166 nDataStartRow (0),
167 nColCount (0),
168 nRowCount (0),
169 nDataCount (0),
170 bValidArea (FALSE),
171 bDataAtCol (FALSE)
173 for (SCSIZE i=0; i<PIVOT_MAXFIELD; i++)
175 pColList[i] = new PivotScStrCollection();
176 pRowList[i] = new PivotScStrCollection();
178 pDataList = pColList[0];
179 ppDataArr = NULL;
180 nDataColCount = 0;
181 nDataRowCount = 0;
182 nRecCount = 0;
183 pColRef = NULL;
185 // Initialisierung der statischen Strings, wenn noetig
186 nStaticStrRefCount += 1;
187 if ( nStaticStrRefCount < 2 )
189 pLabelTotal = new String( ScGlobal::GetRscString(STR_PIVOT_TOTAL) );
190 pLabelData = new String( ScGlobal::GetRscString(STR_PIVOT_DATA) );
192 for (SCSIZE i=0; i<=PIVOT_MAXFUNC; i++ ) // incl. "auto"
193 pLabel[i] = new String; // kein Leerzeichen
195 *pLabel[ 0] = ScGlobal::GetRscString(STR_FUN_TEXT_SUM);
196 *pLabel[ 1] = ScGlobal::GetRscString(STR_FUN_TEXT_COUNT);
197 *pLabel[ 2] = ScGlobal::GetRscString(STR_FUN_TEXT_AVG);
198 *pLabel[ 3] = ScGlobal::GetRscString(STR_FUN_TEXT_MAX);
199 *pLabel[ 4] = ScGlobal::GetRscString(STR_FUN_TEXT_MIN);
200 *pLabel[ 5] = ScGlobal::GetRscString(STR_FUN_TEXT_PRODUCT);
201 *pLabel[ 6] = ScGlobal::GetRscString(STR_FUN_TEXT_COUNT); // Count2
202 *pLabel[ 7] = ScGlobal::GetRscString(STR_FUN_TEXT_STDDEV);
203 *pLabel[ 8] = ScGlobal::GetRscString(STR_FUN_TEXT_STDDEV); // Stddev2
204 *pLabel[ 9] = ScGlobal::GetRscString(STR_FUN_TEXT_VAR);
205 *pLabel[10] = ScGlobal::GetRscString(STR_FUN_TEXT_VAR); // Var2
206 *pLabel[11] = ScGlobal::GetRscString(STR_TABLE_ERGEBNIS);
210 ScPivot::ScPivot(const ScPivot& rPivot):
211 ScDataObject(),
212 pDoc (rPivot.pDoc),
213 aQuery (rPivot.aQuery),
214 bHasHeader (rPivot.bHasHeader),
215 bIgnoreEmpty (rPivot.bIgnoreEmpty),
216 bDetectCat (rPivot.bDetectCat),
217 bMakeTotalCol (rPivot.bMakeTotalCol),
218 bMakeTotalRow (rPivot.bMakeTotalRow),
219 aName (rPivot.aName),
220 aTag (rPivot.aTag),
221 nColNameCount (0),
222 pColNames (NULL),
223 nSrcCol1 (rPivot.nSrcCol1),
224 nSrcRow1 (rPivot.nSrcRow1),
225 nSrcCol2 (rPivot.nSrcCol2),
226 nSrcRow2 (rPivot.nSrcRow2),
227 nSrcTab (rPivot.nSrcTab),
228 nDestCol1 (rPivot.nDestCol1),
229 nDestRow1 (rPivot.nDestRow1),
230 nDestCol2 (rPivot.nDestCol2),
231 nDestRow2 (rPivot.nDestRow2),
232 nDestTab (rPivot.nDestTab),
233 nDataStartCol (0),
234 nDataStartRow (0),
235 nColCount (0),
236 nRowCount (0),
237 nDataCount (0),
238 bValidArea (FALSE),
239 bDataAtCol (FALSE)
241 if (rPivot.nColNameCount>0 && rPivot.pColNames)
243 nColNameCount = rPivot.nColNameCount;
244 pColNames = new String[nColNameCount];
245 for (SCSIZE nCol=0; nCol<nColNameCount; nCol++)
246 pColNames[nCol] = rPivot.pColNames[nCol];
249 for (SCSIZE i=0; i<PIVOT_MAXFIELD; i++)
251 pColList[i] = new PivotScStrCollection();
252 pRowList[i] = new PivotScStrCollection();
254 pDataList = pColList[0];
255 ppDataArr = NULL;
256 nRecCount = 0;
257 pColRef = NULL;
259 SetColFields( rPivot.aColArr, rPivot.nColCount );
260 SetRowFields( rPivot.aRowArr, rPivot.nRowCount );
261 SetDataFields( rPivot.aDataArr, rPivot.nDataCount );
263 nStaticStrRefCount += 1;
266 ScPivot::~ScPivot()
268 for (SCSIZE i=0; i<PIVOT_MAXFIELD; i++)
270 delete pColList[i];
271 delete pRowList[i];
273 if (ppDataArr)
275 for (SCSIZE j=0; j<nDataRowCount; j++)
276 delete[] ppDataArr[j];
277 delete[] ppDataArr;
278 ppDataArr = NULL;
280 delete[] pColRef;
282 delete[] pColNames;
284 // statische Strings ggF. wieder abraeumen
285 nStaticStrRefCount -= 1;
286 if ( nStaticStrRefCount == 0 )
288 delete pLabelTotal;
289 delete pLabelData;
291 for ( SCSIZE k=0; k<=PIVOT_MAXFUNC; k++ ) // incl. "auto"
292 delete pLabel[k];
296 ScPivot* ScPivot::CreateNew() const
298 ScPivot* pNewPivot = new ScPivot( pDoc );
300 pNewPivot->SetQuery(aQuery);
301 pNewPivot->SetHeader(bHasHeader);
302 pNewPivot->SetIgnoreEmpty(bIgnoreEmpty);
303 pNewPivot->SetDetectCat(bDetectCat);
304 pNewPivot->SetMakeTotalCol(bMakeTotalCol);
305 pNewPivot->SetMakeTotalRow(bMakeTotalRow);
307 pNewPivot->SetSrcArea( nSrcCol1, nSrcRow1, nSrcCol2, nSrcRow2, nSrcTab );
308 pNewPivot->SetDestPos( nDestCol1, nDestRow1, nDestTab );
310 return pNewPivot;
313 void lcl_LoadFieldArr30( SvStream& /* rStream */, PivotField* /* pField */, USHORT /* nCount */ )
315 #if SC_ROWLIMIT_STREAM_ACCESS
316 #error address types changed!
317 USHORT i;
319 for (i=0; i<nCount; i++)
321 rStream >> pField[i].nCol
322 >> pField[i].nFuncMask
323 >> pField[i].nFuncCount;
325 #endif
328 void lcl_LoadFieldArr( SvStream& /* rStream */, PivotField* /* pField */, USHORT /* nCount */ )
330 #if SC_ROWLIMIT_STREAM_ACCESS
331 #error address types changed!
332 USHORT i;
334 for (i=0; i<nCount; i++)
336 BYTE cData;
337 rStream >> cData;
338 if( cData & 0x0F )
339 rStream.SeekRel( cData & 0x0F );
340 rStream >> pField[i].nCol
341 >> pField[i].nFuncMask
342 >> pField[i].nFuncCount;
344 #endif
347 void lcl_SaveFieldArr( SvStream& /* rStream */, const PivotField* /* pField */, USHORT /* nCount */ )
349 #if SC_ROWLIMIT_STREAM_ACCESS
350 #error address types changed!
351 USHORT i;
353 for (i=0; i<nCount; i++)
355 rStream << (BYTE) 0x00
356 << pField[i].nCol
357 << pField[i].nFuncMask
358 << pField[i].nFuncCount;
360 #endif
363 // nach Load muessen Daten neu berechnet werden !
365 BOOL ScPivot::Load( SvStream& /* rStream */, ScMultipleReadHeader& rHdr )
367 rHdr.StartEntry();
368 #if SC_ROWLIMIT_STREAM_ACCESS
369 #error address types changed!
371 rStream >> bHasHeader
373 >> nSrcCol1
374 >> nSrcRow1
375 >> nSrcCol2
376 >> nSrcRow2
377 >> nSrcTab
379 >> nDestCol1
380 >> nDestRow1
381 >> nDestCol2
382 >> nDestRow2
383 >> nDestTab;
385 // Arrays immer ueber Set...Fields initalisieren!
387 short nCount;
388 PivotFieldArr aFieldArr;
390 if( pDoc->GetSrcVersion() >= SC_DATABYTES2 )
392 rStream >> nCount;
393 lcl_LoadFieldArr( rStream, aFieldArr, nCount );
394 SetColFields(aFieldArr, nCount);
396 rStream >> nCount;
397 lcl_LoadFieldArr( rStream, aFieldArr, nCount );
398 SetRowFields(aFieldArr, nCount);
400 rStream >> nCount;
401 lcl_LoadFieldArr( rStream, aFieldArr, nCount );
402 SetDataFields(aFieldArr, nCount);
404 else
406 rStream >> nCount;
407 lcl_LoadFieldArr30( rStream, aFieldArr, nCount );
408 SetColFields(aFieldArr, nCount);
410 rStream >> nCount;
411 lcl_LoadFieldArr30( rStream, aFieldArr, nCount );
412 SetRowFields(aFieldArr, nCount);
414 rStream >> nCount;
415 lcl_LoadFieldArr30( rStream, aFieldArr, nCount );
416 SetDataFields(aFieldArr, nCount);
419 aQuery.Load( rStream );
421 rStream >> bIgnoreEmpty;
422 rStream >> bDetectCat;
424 if (rHdr.BytesLeft())
426 rStream >> bMakeTotalCol; // ab 355i
427 rStream >> bMakeTotalRow;
430 if (rHdr.BytesLeft()) // ab 500a
432 rStream.ReadByteString( aName, rStream.GetStreamCharSet() );
433 rStream.ReadByteString( aTag, rStream.GetStreamCharSet() );
435 DBG_ASSERT(!pColNames, "Spaltennamen schon gesetzt?");
436 rStream >> nColNameCount;
437 if (nColNameCount)
439 pColNames = new String[nColNameCount];
440 for (SCCOL nCol=0; nCol<nColNameCount; nCol++)
441 rStream.ReadByteString( pColNames[nCol], rStream.GetStreamCharSet() );
444 // sonst wird hinterher aus ScPivotCollection::Load ein Name vergeben
446 rHdr.EndEntry();
447 #endif
448 return TRUE;
451 BOOL ScPivot::Store( SvStream& /* rStream */, ScMultipleWriteHeader& rHdr ) const
453 rHdr.StartEntry();
454 #if SC_ROWLIMIT_STREAM_ACCESS
455 #error address types changed!
457 rStream << bHasHeader
459 << nSrcCol1
460 << nSrcRow1
461 << nSrcCol2
462 << nSrcRow2
463 << nSrcTab
465 << nDestCol1
466 << nDestRow1
467 << nDestCol2
468 << nDestRow2
469 << nDestTab
471 << nColCount;
472 lcl_SaveFieldArr( rStream, aColArr, nColCount );
473 rStream << nRowCount;
474 lcl_SaveFieldArr( rStream, aRowArr, nRowCount );
475 rStream << nDataCount;
476 lcl_SaveFieldArr( rStream, aDataArr, nDataCount );
478 aQuery.Store( rStream );
480 rStream << bIgnoreEmpty;
481 rStream << bDetectCat;
483 rStream << bMakeTotalCol; // ab 355i
484 rStream << bMakeTotalRow;
486 if( rStream.GetVersion() > SOFFICE_FILEFORMAT_40 ) // Name/Tag/Spalten ab 5.0
488 rStream.WriteByteString( aName, rStream.GetStreamCharSet() );
489 rStream.WriteByteString( aTag, rStream.GetStreamCharSet() );
491 if (!pColNames) ((ScPivot*)this)->nColNameCount = 0; // soll nicht sein
492 rStream << nColNameCount;
493 for (SCCOL nCol=0; nCol<nColNameCount; nCol++)
494 rStream.WriteByteString( pColNames[nCol], rStream.GetStreamCharSet() );
497 rHdr.EndEntry();
498 #endif
499 return TRUE;
502 void ScPivot::SetQuery(const ScQueryParam& rQuery)
504 aQuery = rQuery;
506 bValidArea = FALSE;
509 void ScPivot::GetQuery(ScQueryParam& rQuery) const
511 rQuery = aQuery;
514 void ScPivot::SetHeader(BOOL bHeader)
516 bHasHeader = bHeader;
517 bValidArea = FALSE;
520 BOOL ScPivot::GetHeader() const
522 return bHasHeader;
525 void ScPivot::SetIgnoreEmpty(BOOL bIgnore)
527 bIgnoreEmpty = bIgnore;
528 bValidArea = FALSE;
531 BOOL ScPivot::GetIgnoreEmpty() const
533 return bIgnoreEmpty;
536 void ScPivot::SetDetectCat(BOOL bDetect)
538 bDetectCat = bDetect;
539 bValidArea = FALSE;
542 BOOL ScPivot::GetDetectCat() const
544 return bDetectCat;
547 void ScPivot::SetMakeTotalCol(BOOL bSet)
549 bMakeTotalCol = bSet;
550 bValidArea = FALSE;
553 BOOL ScPivot::GetMakeTotalCol() const
555 return bMakeTotalCol;
558 void ScPivot::SetMakeTotalRow(BOOL bSet)
560 bMakeTotalRow = bSet;
561 bValidArea = FALSE;
564 BOOL ScPivot::GetMakeTotalRow() const
566 return bMakeTotalRow;
569 void ScPivot::SetName(const String& rNew)
571 aName = rNew;
574 const String& ScPivot::GetName() const
576 return aName;
579 void ScPivot::SetTag(const String& rNew)
581 aTag = rNew;
584 const String& ScPivot::GetTag() const
586 return aTag;
589 void ScPivot::SetSrcArea(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, SCTAB nTab)
591 nSrcCol1 = Min(nCol1, (SCCOL)MAXCOL);
592 nSrcRow1 = Min(nRow1, (SCROW)MAXROW);
593 nSrcCol2 = Min(nCol2, (SCCOL)MAXCOL);
594 nSrcRow2 = Min(nRow2, (SCROW)MAXROW);
595 nSrcTab = nTab;
596 bValidArea = FALSE;
599 void ScPivot::GetSrcArea(SCCOL& rCol1, SCROW& rRow1, SCCOL& rCol2, SCROW& rRow2, SCTAB& rTab) const
601 rCol1 = nSrcCol1;
602 rRow1 = nSrcRow1;
603 rCol2 = nSrcCol2;
604 rRow2 = nSrcRow2;
605 rTab = nSrcTab;
608 ScRange ScPivot::GetSrcArea() const
610 return ScRange( nSrcCol1,nSrcRow1,nSrcTab, nSrcCol2,nSrcRow2,nSrcTab );
613 void ScPivot::SetDestPos(SCCOL nCol, SCROW nRow, SCTAB nTab)
615 nDestCol1 = nCol;
616 nDestRow1 = nRow;
617 nDestTab = nTab;
618 bValidArea = FALSE;
621 void ScPivot::GetDestArea(SCCOL& rCol1, SCROW& rRow1, SCCOL& rCol2, SCROW& rRow2, SCTAB& rTab) const
623 rCol1 = nDestCol1;
624 rRow1 = nDestRow1;
625 rTab = nDestTab;
626 if (bValidArea)
628 rCol2 = nDestCol2;
629 rRow2 = nDestRow2;
631 else
633 rCol2 = nDestCol1;
634 rRow2 = nDestRow1;
638 ScRange ScPivot::GetDestArea() const
640 ScAddress aStart( nDestCol1, nDestRow1, nDestTab );
641 ScAddress aEnd = aStart;
642 if ( bValidArea )
643 aEnd = ScAddress( nDestCol2, nDestRow2, nDestTab );
644 return ScRange( aStart, aEnd );
647 void ScPivot::MoveSrcArea( SCCOL nNewCol, SCROW nNewRow, SCTAB nNewTab )
649 if ( nNewCol != nSrcCol1 || nNewRow != nSrcRow1 || nNewTab != nSrcTab )
651 SCsCOL nDiffX = nNewCol - (SCsCOL) nSrcCol1;
652 SCsROW nDiffY = nNewRow - (SCsROW) nSrcRow1;
654 nSrcTab = nNewTab;
655 nSrcCol1 = sal::static_int_cast<SCCOL>( nSrcCol1 + nDiffX );
656 nSrcCol2 = sal::static_int_cast<SCCOL>( nSrcCol2 + nDiffX );
657 nSrcRow1 = sal::static_int_cast<SCROW>( nSrcRow1 + nDiffY );
658 nSrcRow2 = sal::static_int_cast<SCROW>( nSrcRow2 + nDiffY );
660 aQuery.nCol1 = sal::static_int_cast<SCCOL>( aQuery.nCol1 + nDiffX );
661 aQuery.nCol2 = sal::static_int_cast<SCCOL>( aQuery.nCol2 + nDiffX );
662 aQuery.nRow1 = sal::static_int_cast<SCROW>( aQuery.nRow1 + nDiffY );
663 aQuery.nRow2 = sal::static_int_cast<SCROW>( aQuery.nRow2 + nDiffY );
665 SCSIZE nEC = aQuery.GetEntryCount();
666 for (SCSIZE i=0; i<nEC; i++)
667 if (aQuery.GetEntry(i).bDoQuery)
668 aQuery.GetEntry(i).nField += nDiffX;
670 if (bValidArea)
672 SCSIZE nC;
673 SCSIZE nR;
674 for (nC=0; nC<nColCount; nC++)
675 if (aColArr[nC].nCol != PIVOT_DATA_FIELD)
676 aColArr[nC].nCol = sal::static_int_cast<SCsCOL>( aColArr[nC].nCol + nDiffX );
677 for (nR=0; nR<nRowCount; nR++)
678 if (aRowArr[nR].nCol != PIVOT_DATA_FIELD)
679 aRowArr[nR].nCol = sal::static_int_cast<SCsCOL>( aRowArr[nR].nCol + nDiffX );
680 for (nC=0; nC<nDataCount; nC++)
681 if (aDataArr[nC].nCol != PIVOT_DATA_FIELD)
682 aDataArr[nC].nCol = sal::static_int_cast<SCsCOL>( aDataArr[nC].nCol + nDiffX );
687 void ScPivot::ExtendSrcArea( SCCOL nNewEndCol, SCROW nNewEndRow )
689 DBG_ASSERT( nNewEndCol >= nSrcCol2 && nNewEndRow >= nSrcRow2, "ExtendSrcArea: zu klein" );
691 nSrcCol2 = nNewEndCol;
692 nSrcRow2 = nNewEndRow;
694 // alles andere bleibt erhalten
697 void ScPivot::MoveDestArea( SCCOL nNewCol, SCROW nNewRow, SCTAB nNewTab )
699 if ( nNewCol != nDestCol1 || nNewRow != nDestRow1 || nNewTab != nDestTab )
701 SCsCOL nDiffX = nNewCol - (SCsCOL) nDestCol1;
702 SCsROW nDiffY = nNewRow - (SCsROW) nDestRow1;
704 nDestTab = nNewTab;
705 nDestCol1 = sal::static_int_cast<SCCOL>( nDestCol1 + nDiffX );
706 nDestRow1 = sal::static_int_cast<SCROW>( nDestRow1 + nDiffY );
708 if (bValidArea)
710 nDestCol2 = sal::static_int_cast<SCCOL>( nDestCol2 + nDiffX );
711 nDestRow2 = sal::static_int_cast<SCROW>( nDestRow2 + nDiffY );
713 nDataStartCol = sal::static_int_cast<SCCOL>( nDataStartCol + nDiffX );
714 nDataStartRow = sal::static_int_cast<SCROW>( nDataStartRow + nDiffY );
719 void ScPivot::SetColFields(const PivotField* pFieldArr, SCSIZE nCount)
721 nColCount = Max(static_cast<SCSIZE>(0), Min(nCount, PIVOT_MAXFIELD));
722 for (SCSIZE i = 0; i < nColCount; i++)
724 aColArr[i] = pFieldArr[i];
725 aColArr[i].nFuncCount = 0;
726 if (aColArr[i].nCol == PIVOT_DATA_FIELD)
728 aColArr[i].nFuncMask = PIVOT_FUNC_NONE;
729 pDataList = pColList[i];
730 bDataAtCol = TRUE;
732 else
734 for (SCsCOL j=0; j<=PIVOT_MAXFUNC; j++) // incl. "auto"
735 if (aColArr[i].nFuncMask & nFuncMaskArr[j])
736 aColArr[i].nFuncCount++;
739 bValidArea = FALSE;
742 void ScPivot::GetColFields(PivotField* pFieldArr, SCSIZE& rCount) const
744 for (SCSIZE i=0; i<nColCount; i++)
745 pFieldArr[i] = aColArr[i];
746 rCount = nColCount;
749 void ScPivot::SetRowFields(const PivotField* pFieldArr, SCSIZE nCount)
751 nRowCount = Max(static_cast<SCSIZE>(0), Min(nCount, PIVOT_MAXFIELD));
752 for (SCSIZE i = 0; i < nRowCount; i++)
754 aRowArr[i] = pFieldArr[i];
755 aRowArr[i].nFuncCount = 0;
756 if (aRowArr[i].nCol == PIVOT_DATA_FIELD)
758 aRowArr[i].nFuncMask = PIVOT_FUNC_NONE;
759 pDataList = pRowList[i];
760 bDataAtCol = FALSE;
762 else
764 for (SCSIZE j=0; j<=PIVOT_MAXFUNC; j++) // incl. "auto"
765 if (aRowArr[i].nFuncMask & nFuncMaskArr[j])
766 aRowArr[i].nFuncCount++;
769 bValidArea = FALSE;
772 void ScPivot::GetRowFields(PivotField* pFieldArr, SCSIZE& rCount) const
774 for (SCSIZE i=0; i<nRowCount; i++)
775 pFieldArr[i] = aRowArr[i];
776 rCount = nRowCount;
779 void ScPivot::SetDataFields(const PivotField* pFieldArr, SCSIZE nCount)
781 USHORT nFuncNo;
782 SCSIZE i;
785 // nDataCount vorausberechnen (wie unten)
788 nDataCount = 0;
789 for (i = 0; i < nCount; i++)
790 for (nFuncNo=0; nFuncNo<PIVOT_MAXFUNC; nFuncNo++)
791 if (pFieldArr[i].nFuncMask & nFuncMaskArr[nFuncNo])
792 if (nDataCount+1 < PIVOT_MAXFIELD)
793 ++nDataCount;
796 // Eintraege anpassen
799 if ((nRowCount == 1) && (aRowArr[0].nCol == PIVOT_DATA_FIELD) && (nDataCount == 1))
801 aColArr[nColCount] = aRowArr[0];
802 pDataList = pColList[nColCount];
803 nColCount++;
804 nRowCount--;
805 bDataAtCol = TRUE;
807 if ((nColCount == 1) && (aColArr[0].nCol == PIVOT_DATA_FIELD) && (nDataCount == 1))
809 aRowArr[nRowCount] = aColArr[0];
810 pDataList = pRowList[nRowCount];
811 nRowCount++;
812 nColCount--;
813 bDataAtCol = FALSE;
816 if ((nDataCount == 1)
817 && (aColArr[nColCount-1].nCol != PIVOT_DATA_FIELD)
818 && (aColArr[nRowCount-1].nCol != PIVOT_DATA_FIELD))
820 if (bDataAtCol)
822 PivotField aField;
823 SCSIZE nIndex = PIVOT_MAXFIELD;
824 for (i=0; i<nColCount; i++)
826 if (aColArr[i].nCol == PIVOT_DATA_FIELD)
828 aField = aColArr[i];
829 nIndex = i;
832 DBG_ASSERT(nIndex < PIVOT_MAXFIELD, "no data field (GPF in old versions!)");
833 if ( nIndex < PIVOT_MAXFIELD )
835 memcpy(&aColArr[nIndex], &aColArr[nIndex+1], (PIVOT_MAXFIELD - nIndex - 1) * sizeof(PivotField));
836 aColArr[nColCount-1] = aField;
837 pDataList = pColList[nColCount-1];
840 else
842 PivotField aField;
843 SCSIZE nIndex = PIVOT_MAXFIELD;
844 for (i=0; i<nRowCount; i++)
846 if (aRowArr[i].nCol == PIVOT_DATA_FIELD)
848 aField = aRowArr[i];
849 nIndex = i;
852 DBG_ASSERT(nIndex < PIVOT_MAXFIELD, "no data field (GPF in old versions!)");
853 if ( nIndex < PIVOT_MAXFIELD )
855 memcpy(&aRowArr[nIndex], &aRowArr[nIndex+1], (PIVOT_MAXFIELD - nIndex - 1) * sizeof(PivotField));
856 aRowArr[nRowCount-1] = aField;
857 pDataList = pRowList[nRowCount-1];
863 // Datenfelder in Eintraege mit nur einer Funktion aufteilen
866 pDataList->FreeAll();
867 nDataCount = 0;
868 for (i = 0; i < nCount; i++)
870 for (nFuncNo=0; nFuncNo<PIVOT_MAXFUNC; nFuncNo++)
871 if (pFieldArr[i].nFuncMask & nFuncMaskArr[nFuncNo])
872 if (nDataCount+1 < PIVOT_MAXFIELD)
874 aDataArr[nDataCount] = pFieldArr[i];
875 aDataArr[nDataCount].nFuncCount = 0;
876 aDataArr[nDataCount].nFuncMask = nFuncMaskArr[nFuncNo];
878 String aStr;
879 pDoc->GetString(aDataArr[nDataCount].nCol, nSrcRow1, nSrcTab, aStr);
880 if (aStr.Len() == 0)
881 aStr = ScColToAlpha( aDataArr[nDataCount].nCol );
882 TypedStrData* pStrData = new TypedStrData(aStr);
883 if (!(pDataList->AtInsert(pDataList->GetCount(), pStrData)))
885 delete pStrData;
886 DBG_ERROR("Fehler bei pDataList->AtInsert");
889 ++nDataCount;
897 bValidArea = FALSE;
900 void ScPivot::GetDataFields(PivotField* pFieldArr, SCSIZE& rCount) const
902 /* for (SCSIZE i=0; i<nDataCount; i++)
903 pFieldArr[i] = aDataArr[i];
904 rCount = nDataCount;
907 rCount = 0;
908 for (SCSIZE i=0; i<nDataCount; i++)
910 BOOL bFound = FALSE;
911 for (SCSIZE j=0; j<rCount && !bFound; j++)
912 if (pFieldArr[j].nCol == aDataArr[i].nCol)
914 // add to previous column only if new bits aren't already set there
915 if ( ( pFieldArr[j].nFuncMask & aDataArr[i].nFuncMask ) == 0 )
917 pFieldArr[j].nFuncMask |= aDataArr[i].nFuncMask;
918 pFieldArr[j].nFuncCount++;
919 bFound = TRUE;
922 if (!bFound)
924 pFieldArr[rCount] = aDataArr[i];
925 ++rCount;
930 BOOL ScPivot::CreateData(BOOL bKeepDest)
936 SCCOL nOldCol2 = nDestCol2;
937 SCROW nOldRow2 = nDestRow2;
939 pColRef = new PivotColRef[MAXCOL];
940 aQuery.nCol1 = nSrcCol1;
941 aQuery.nRow1 = nSrcRow1;
942 aQuery.nCol2 = nSrcCol2;
943 aQuery.nRow2 = nSrcRow2;
944 aQuery.bHasHeader = bHasHeader;
945 BOOL bRet = CreateFields();
946 if (bRet)
948 SCSIZE i=0; // nDataMult berechnen - nach CreateFields, vor CreateFieldData !!!
949 nDataMult = 1;
950 if (nDataCount > 1)
952 if (bDataAtCol)
954 while (i<nColCount && aColArr[i].nCol != PIVOT_DATA_FIELD) i++;
955 i++;
956 while (i<nColCount)
957 nDataMult *= pColList[i++]->GetCount();
959 else
961 while (i<nRowCount && aRowArr[i].nCol != PIVOT_DATA_FIELD) i++;
962 i++;
963 while (i<nRowCount)
964 nDataMult *= pRowList[i++]->GetCount();
967 DBG_ASSERT(nDataMult,"nDataMult==0");
969 CalcArea();
970 if ((ValidCol(nDestCol2)) && (ValidRow(nDestRow2)))
972 CreateFieldData();
973 bValidArea = TRUE;
975 else
976 bRet = FALSE;
979 if ( bKeepDest )
981 bValidArea = TRUE; //! ???
982 nDestCol2 = nOldCol2;
983 nDestRow2 = nOldRow2;
986 return bRet;
989 void ScPivot::DrawData()
991 ScProgress aProgress( pDoc->GetDocumentShell(), ScGlobal::GetRscString(STR_PIVOT_PROGRESS), nDestRow2-nDestRow1 );
993 SCSIZE i;
995 SCCOL nCol;
996 SCROW nRow;
997 String aStr;
998 pDoc->pTab[nDestTab]->DeleteArea(nDestCol1, nDestRow1, nDestCol2, nDestRow2, IDF_ALL);
1000 if ( nDataStartRow > nDestRow1+nFirstLine )
1001 SetStyle(nDestCol1, nDestRow1+nFirstLine, nDestCol2, nDataStartRow-1, PIVOT_STYLE_TOP);
1002 SetStyle(nDataStartCol, nDataStartRow, nDestCol2, nDestRow2, PIVOT_STYLE_INNER);
1004 pDoc->SetString(nDestCol1, nDestRow1, nDestTab, ScGlobal::GetRscString(STR_CELL_FILTER));
1005 // Kategorie 1
1006 SetButton(nDestCol1, nDestRow1, nDestCol1, nDestRow1);
1008 if (bHasHeader) // Spalten / Zeilennamen ausgeben
1010 if (nColCount != 0)
1012 nCol = nDestCol1;
1013 nRow = nDataStartRow - 1;
1014 for (i=0; i<nColCount; i++)
1016 if (aColArr[i].nCol != PIVOT_DATA_FIELD)
1018 pDoc->GetString(aColArr[i].nCol, nSrcRow1, nSrcTab, aStr);
1019 if ( !aStr.Len() )
1020 aStr = ScColToAlpha( aColArr[i].nCol );
1021 pDoc->SetString(nCol, nRow, nDestTab, aStr);
1022 // Kategorie 2
1023 nCol++;
1025 else if (nDataCount > 1)
1027 pDoc->SetString(nCol, nRow, nDestTab, *pLabelData);
1028 // Kategorie 3
1029 nCol++;
1032 SetButton(nDestCol1, nRow, nCol-1, nRow);
1033 SetStyle(nDestCol1, nRow, nCol-1, nRow, PIVOT_STYLE_FIELDNAME);
1035 if (nRowCount != 0)
1037 nCol = nDataStartCol;
1038 nRow = nDestRow1 + nFirstLine;
1039 for (i=0; i<nRowCount; i++)
1041 if (aRowArr[i].nCol != PIVOT_DATA_FIELD)
1043 pDoc->GetString(aRowArr[i].nCol, nSrcRow1, nSrcTab, aStr);
1044 if ( !aStr.Len() )
1045 aStr = ScColToAlpha( aRowArr[i].nCol );
1046 pDoc->SetString(nCol, nRow, nDestTab, aStr);
1047 // Kategorie 4
1048 nCol++;
1050 else if (nDataCount > 1)
1052 pDoc->SetString(nCol, nRow, nDestTab, *pLabelData);
1053 // Kategorie 5
1054 nCol++;
1057 SetButton(nDataStartCol, nRow, nCol-1, nRow);
1058 SetStyle(nDataStartCol, nRow, nCol-1, nRow, PIVOT_STYLE_FIELDNAME);
1062 BOOL bNoRows = (nRowCount == 0) || ( nRowCount == 1 && aRowArr[0].nCol == PIVOT_DATA_FIELD );
1063 BOOL bNoCols = (nColCount == 0) || ( nColCount == 1 && aColArr[0].nCol == PIVOT_DATA_FIELD );
1064 if (!bMakeTotalCol) bNoRows = TRUE;
1065 if (!bMakeTotalRow) bNoCols = TRUE;
1067 SCCOL nTotalCol = nDestCol2;
1068 SCROW nTotalRow = nDestRow2;
1069 if (bDataAtCol)
1070 nTotalRow = sal::static_int_cast<SCROW>( nTotalRow - ( nDataCount - 1 ) );
1071 else
1072 nTotalCol = sal::static_int_cast<SCCOL>( nTotalCol - ( nDataCount - 1 ) );
1074 // Spaltenkoepfe ausgeben und ColRef initialisieren
1075 // (String-Collections sind initialisiert)
1076 nDataIndex = 0;
1077 nColIndex = 0;
1078 nCol = nDataStartCol;
1079 nRecCount = 0;
1080 RowToTable(0, nCol);
1082 // Zeilenkoepfe und Daten ausgeben
1083 // (ruft SetDataLine/SetFuncLine auf)
1084 nRowIndex = 0;
1085 nRow = nDataStartRow;
1086 ColToTable(0, nRow, aProgress);
1088 // Gesamtergebnis-Zeilen
1090 if (!bNoCols)
1092 if (bDataAtCol)
1093 for (SCSIZE nTotCnt = 0; nTotCnt<nDataCount; nTotCnt++)
1094 SetFuncLine(nDataStartCol, nRow+nTotCnt, nDestTab,
1095 aDataArr[nTotCnt].nFuncMask, nTotCnt, 0, nDataRowCount);
1096 else
1097 SetFuncLine(nDataStartCol, nRow, nDestTab, PIVOT_FUNC_AUTO, SCSIZE_MAX, 0, nDataRowCount);
1101 // Rahmen Spaltenergebnis
1103 if (!bNoRows)
1105 if (!bDataAtCol)
1107 for (i=0; i<nDataCount; i++)
1109 String aLab = *pLabelTotal;
1110 aLab += ' ';
1111 aLab += *pLabel[lcl_MaskToIndex( aDataArr[i].nFuncMask )];
1112 aLab += ' ';
1113 aLab += pDataList->GetString(sal::static_int_cast<USHORT>(i));
1114 pDoc->SetString(sal::static_int_cast<SCCOL>(nTotalCol+i),
1115 sal::static_int_cast<SCROW>(nDestRow1 + nFirstLine), nDestTab, aLab);
1116 // Kategorie 6
1119 else
1121 pDoc->SetString(nTotalCol, nDestRow1 + nFirstLine, nDestTab, *pLabelTotal);
1122 // Kategorie 7
1125 if ( nDataStartRow > 0 )
1126 SetStyle(nTotalCol, nDestRow1+nFirstLine, nDestCol2, nDataStartRow-1, PIVOT_STYLE_TITLE);
1127 SetStyle(nTotalCol, nDataStartRow, nDestCol2, nDestRow2, PIVOT_STYLE_RESULT);
1128 SetFrame(nTotalCol, nDestRow1 + nFirstLine, nDestCol2, nDestRow2);
1131 // Rahmen Zeilenergebnis
1133 if (!bNoCols)
1135 if (bDataAtCol)
1137 for (i=0; i<nDataCount; i++)
1139 String aLab = *pLabelTotal;
1140 aLab += ' ';
1141 aLab += *pLabel[lcl_MaskToIndex( aDataArr[i].nFuncMask )];
1142 aLab += ' ';
1143 aLab += pDataList->GetString(sal::static_int_cast<USHORT>(i));
1144 pDoc->SetString(nDestCol1, nTotalRow+i, nDestTab, aLab);
1145 // Kategorie 8
1148 else
1150 pDoc->SetString(nDestCol1, nTotalRow, nDestTab, *pLabelTotal);
1151 // Kategorie 9
1154 if ( nDataStartCol > 0 )
1155 SetStyle(nDestCol1, nTotalRow, nDataStartCol-1, nDestRow2, PIVOT_STYLE_TITLE);
1156 SetStyle(nDataStartCol, nTotalRow, nDestCol2, nDestRow2, PIVOT_STYLE_RESULT);
1157 SetFrame(nDestCol1, nTotalRow, nDestCol2, nDestRow2);
1160 // Rahmen gesamt
1161 SetFrame(nDestCol1, nDestRow1 + nFirstLine, nDestCol2, nDestRow2, 40);
1164 void ScPivot::ReleaseData()
1166 for (SCSIZE i = 0; i < PIVOT_MAXFIELD; i++)
1168 pColList[i]->FreeAll();
1169 pRowList[i]->FreeAll();
1171 if (ppDataArr)
1173 for (SCSIZE i=0; i<nDataRowCount; i++)
1174 delete[] ppDataArr[i];
1175 delete[] ppDataArr;
1176 ppDataArr = NULL;
1178 nDataColCount = 0;
1179 nDataRowCount = 0;
1180 delete[] pColRef;
1181 pColRef = NULL;
1184 BOOL ScPivot::IsPivotAtCursor(SCCOL nCol, SCROW nRow, SCTAB nTab) const
1186 if (bValidArea)
1187 return ( nTab == nDestTab
1188 && nCol >= nDestCol1 && nCol <= nDestCol2
1189 && nRow >= nDestRow1 && nRow <= nDestRow2 );
1190 else
1191 return FALSE;
1194 BOOL ScPivot::IsFilterAtCursor(SCCOL nCol, SCROW nRow, SCTAB nTab) const
1196 if (bValidArea)
1197 return (nCol == nDestCol1 && nRow == nDestRow1 && nTab == nDestTab);
1198 else
1199 return FALSE;
1202 BOOL ScPivot::GetColFieldAtCursor(SCCOL nCol, SCROW nRow, SCTAB nTab, SCCOL& rField) const
1204 rField = 0;
1205 BOOL bRet = FALSE;
1206 if (bValidArea)
1208 bRet = ( nCol >= nDestCol1 && nCol < nDataStartCol
1209 && nRow == nDataStartRow - 1
1210 && nTab == nDestTab );
1211 if (bRet)
1213 rField = aColArr[nCol - nDestCol1].nCol;
1214 if (rField == PIVOT_DATA_FIELD)
1215 bRet = (nDataCount > 1);
1218 return bRet;
1221 BOOL ScPivot::GetRowFieldAtCursor(SCCOL nCol, SCROW nRow, SCTAB nTab, SCCOL& rField) const
1223 rField = 0;
1224 BOOL bRet = FALSE;
1225 if (bValidArea)
1227 bRet = ( nCol >= nDataStartCol && nCol < sal::static_int_cast<SCCOL>(nDataStartCol + nRowCount)
1228 && nRow == nDestRow1 + nFirstLine
1229 && nTab == nDestTab );
1230 if (bRet)
1232 rField = aRowArr[nCol - nDataStartCol].nCol;
1233 if (rField == PIVOT_DATA_FIELD)
1234 bRet = (nDataCount > 1);
1237 return bRet;
1241 //--------------------------------------------------------------------------------------------------
1242 // Private Methoden
1243 //--------------------------------------------------------------------------------------------------
1245 BOOL ScPivot::CreateFields()
1247 SCSIZE i;
1248 SCROW nRow;
1249 SCROW nHeader;
1250 String aStr;
1251 TypedStrData* pStrData;
1252 if (bHasHeader)
1253 nHeader = 1;
1254 else
1255 nHeader = 0;
1257 // Sortieren nach Benutzerdefinierte Listen ??
1258 for (i = 0; i < nColCount; i++)
1260 if (aColArr[i].nCol != PIVOT_DATA_FIELD)
1262 pDoc->GetString(aColArr[i].nCol, nSrcRow1 + nHeader, nSrcTab, aStr);
1263 pColList[i]->SetUserData(ScGlobal::GetUserList()->GetData(aStr));
1265 else
1266 pColList[i]->SetUserData(NULL);
1268 for (i = 0; i < nRowCount; i++)
1270 if (aRowArr[i].nCol != PIVOT_DATA_FIELD)
1272 pDoc->GetString(aRowArr[i].nCol, nSrcRow1 + nHeader, nSrcTab, aStr);
1273 pRowList[i]->SetUserData(ScGlobal::GetUserList()->GetData(aStr));
1275 else
1276 pRowList[i]->SetUserData(NULL);
1279 ScAddress aSrcAdr( nSrcCol1, 0, nSrcTab );
1280 for (nRow = nSrcRow1 + nHeader; nRow <= nSrcRow2; nRow++)
1282 BOOL bValidLine = TRUE;
1283 if (bIgnoreEmpty)
1285 aSrcAdr.SetRow( nRow );
1286 bValidLine = !lcl_IsEmptyLine( pDoc, aSrcAdr, nSrcCol2 );
1288 if (bValidLine)
1289 bValidLine = pDoc->pTab[nSrcTab]->ValidQuery(nRow, aQuery);
1290 if (bValidLine)
1292 // Sortierte Liste der Felder erzeugen
1293 //! statt GetCategoryString leere weglassen !
1295 for (i = 0; i < nColCount; i++)
1297 if (aColArr[i].nCol != PIVOT_DATA_FIELD)
1299 SCROW nCatRow = bDetectCat ? GetCategoryRow( aColArr[i].nCol, nRow ) : nRow;
1300 pStrData = new TypedStrData( pDoc, aColArr[i].nCol, nCatRow, nSrcTab, TRUE );
1301 if (!(pColList[i]->Insert(pStrData)))
1302 delete pStrData;
1305 for (i = 0; i < nRowCount; i++)
1307 if (aRowArr[i].nCol != PIVOT_DATA_FIELD)
1309 SCROW nCatRow = bDetectCat ? GetCategoryRow( aRowArr[i].nCol, nRow ) : nRow;
1310 pStrData = new TypedStrData( pDoc, aRowArr[i].nCol, nCatRow, nSrcTab, TRUE );
1311 if (!(pRowList[i]->Insert(pStrData)))
1312 delete pStrData;
1317 return TRUE;
1320 void ScPivot::CreateFieldData()
1322 SCSIZE* pRowListIndex = nRowCount ? new SCSIZE[nRowCount] : NULL;
1323 SCSIZE* pColListIndex = nColCount ? new SCSIZE[nColCount] : NULL;
1325 SCSIZE i,j,k;
1327 ppDataArr = new SubTotal*[nDataRowCount];
1328 for (i=0; i<nDataRowCount; i++)
1329 ppDataArr[i] = new SubTotal[nDataColCount];
1331 if (bDataAtCol)
1332 for (j=0; j<nDataRowCount; j++)
1333 for (i=0; i<nDataColCount; i++)
1334 ppDataArr[j][i].nIndex = j/nDataMult%nDataCount;
1335 else
1336 for (j=0; j<nDataRowCount; j++)
1337 for (i=0; i<nDataColCount; i++)
1338 ppDataArr[j][i].nIndex = i/nDataMult%nDataCount;
1340 SCROW nHeader;
1341 if (bHasHeader)
1342 nHeader = 1;
1343 else
1344 nHeader = 0;
1345 ScAddress aSrcAdr( nSrcCol1, 0, nSrcTab );
1346 for (SCROW nRow = nSrcRow1 + nHeader; nRow <= nSrcRow2; nRow++)
1348 BOOL bValidLine = TRUE;
1349 if (bIgnoreEmpty)
1351 aSrcAdr.SetRow( nRow );
1352 bValidLine = !lcl_IsEmptyLine( pDoc, aSrcAdr, nSrcCol2 );
1354 if (bValidLine)
1355 bValidLine = pDoc->pTab[nSrcTab]->ValidQuery(nRow, aQuery);
1356 if (bValidLine)
1358 // Indizes der Kategorien nur einmal ausserhalb nDataCount
1359 for (j=0; j<nRowCount; j++)
1360 if (aRowArr[j].nCol != PIVOT_DATA_FIELD)
1362 SCROW nCatRow = bDetectCat ? GetCategoryRow( aRowArr[j].nCol, nRow ) : nRow;
1363 TypedStrData aStrData( pDoc, aRowArr[j].nCol, nCatRow, nSrcTab, TRUE );
1364 pRowListIndex[j] = pRowList[j]->GetIndex(&aStrData);
1366 for (j=0; j<nColCount; j++)
1367 if (aColArr[j].nCol != PIVOT_DATA_FIELD)
1369 SCROW nCatRow = bDetectCat ? GetCategoryRow( aColArr[j].nCol, nRow ) : nRow;
1370 TypedStrData aStrData( pDoc, aColArr[j].nCol, nCatRow, nSrcTab, TRUE );
1371 pColListIndex[j] = pColList[j]->GetIndex(&aStrData);
1374 String aStr;
1375 SCSIZE nCIndex;
1376 SCSIZE nRIndex;
1377 SCSIZE nIndex;
1378 ScAddress aAdr( 0, nRow, nSrcTab );
1380 for (i=0; i<nDataCount; i++)
1382 // ColIndex Berechnen
1383 nCIndex = 0;
1384 for (j=0; j<nRowCount; j++)
1386 if (aRowArr[j].nCol == PIVOT_DATA_FIELD)
1387 nIndex = i;
1388 else
1389 nIndex = pRowListIndex[j];
1390 if (nIndex)
1392 for (k=j+1; k<nRowCount; k++)
1393 nIndex *= pRowList[k]->GetCount();
1394 nCIndex += nIndex;
1397 // RowIndex Berechnen
1398 nRIndex = 0;
1399 for (j=0; j<nColCount; j++)
1401 if (aColArr[j].nCol == PIVOT_DATA_FIELD)
1402 nIndex = i;
1403 else
1404 nIndex = pColListIndex[j];
1405 if (nIndex)
1407 for (k=j+1; k<nColCount; k++)
1408 nIndex *= pColList[k]->GetCount();
1409 nRIndex += nIndex;
1412 // Daten eintragen
1413 if ((nCIndex < nDataColCount) && (nRIndex < nDataRowCount))
1415 DBG_ASSERT(ppDataArr[nRIndex][nCIndex].nIndex == i, "falsch init.");
1417 ppDataArr[nRIndex][nCIndex].nIndex = i;
1418 aAdr.SetCol( aDataArr[i].nCol );
1419 CellType eCellType = pDoc->GetCellType( aAdr );
1420 if ((eCellType != CELLTYPE_NONE) && (eCellType != CELLTYPE_NOTE))
1422 BOOL bValue = (eCellType == CELLTYPE_VALUE);
1423 if (eCellType == CELLTYPE_FORMULA)
1425 ScBaseCell* pCell = pDoc->GetCell( aAdr );
1426 bValue = ((ScFormulaCell*)pCell)->IsValue();
1429 if (bValue)
1431 double nVal = pDoc->GetValue( aAdr );
1432 ppDataArr[nRIndex][nCIndex].Update(nVal);
1434 else
1435 ppDataArr[nRIndex][nCIndex].UpdateNoVal(); // nur nCount
1442 delete pColListIndex;
1443 delete pRowListIndex;
1446 void ScPivot::CalcArea()
1448 BOOL bNoRows = (nRowCount == 0) || ( nRowCount == 1 && aRowArr[0].nCol == PIVOT_DATA_FIELD );
1449 BOOL bNoCols = (nColCount == 0) || ( nColCount == 1 && aColArr[0].nCol == PIVOT_DATA_FIELD );
1450 if (!bMakeTotalCol) bNoRows = TRUE;
1451 if (!bMakeTotalRow) bNoCols = TRUE;
1453 // StartSpalte/StartZeile des Datenbereichs berechnen
1454 if (bDataAtCol)
1456 if (nDataCount > 1)
1457 nDataStartCol = sal::static_int_cast<SCCOL>(nDestCol1 + nColCount);
1458 else
1459 nDataStartCol = sal::static_int_cast<SCCOL>(nDestCol1 + Max(static_cast<SCSIZE>(0), nColCount - 1));
1461 else
1462 nDataStartCol = sal::static_int_cast<SCCOL>(nDestCol1 + nColCount);
1463 if (!bDataAtCol)
1465 if (nDataCount > 1)
1466 nDataStartRow = nDestRow1 + nRowCount + nFirstLine + 1;
1467 else
1468 nDataStartRow = nDestRow1 + Max(static_cast<SCSIZE>(0), nRowCount - 1) + nFirstLine + 1;
1470 else
1471 nDataStartRow = nDestRow1 + nRowCount + nFirstLine + 1;
1474 // Groesse der PivotTabelle berechnen
1477 if (nRowCount == 0 || (nRowCount==1 && aRowArr[0].nCol==PIVOT_DATA_FIELD && nDataCount==1))
1479 nDataColCount = 1;
1480 if (nDataCount == 1)
1481 nDestCol2 = sal::static_int_cast<SCCOL>(nDestCol1 + nColCount - 1);
1482 else
1483 nDestCol2 = sal::static_int_cast<SCCOL>(nDestCol1 + nColCount);
1485 else
1487 SCSIZE nDx;
1488 // Anzahl Spalten
1489 if ((aRowArr[nRowCount-1].nCol == PIVOT_DATA_FIELD) && (nDataCount == 1))
1490 nDx = 2;
1491 else
1492 nDx = 1;
1493 SCSIZE nColLines = pRowList[nRowCount-nDx]->GetCount(); // SCSIZE to recognize overflow
1494 nDataColCount = pRowList[nRowCount-nDx]->GetCount();
1495 for (SCSIZE i=nRowCount-nDx; i-- > 0; )
1497 nColLines *= pRowList[i]->GetCount();
1498 nDataColCount *= pRowList[i]->GetCount();
1499 if (!bDataAtCol)
1500 nColLines += (pRowList[i]->GetCount() * aRowArr[i].nFuncCount * nDataCount);
1501 else
1502 nColLines += (pRowList[i]->GetCount() * aRowArr[i].nFuncCount);
1505 // Ergebnisspalten des letzten Elements
1506 if (aRowArr[nRowCount-1].nCol != PIVOT_DATA_FIELD)
1507 nColLines += (pRowList[nRowCount-1]->GetCount() * aRowArr[nRowCount-1].nFuncCount);
1509 if (nColLines > static_cast<SCSIZE>(MAXCOL))
1510 nDestCol2 = MAXCOL+2; // ungueltig, 1 wird unten abgezogen
1511 else if (bDataAtCol)
1513 if (nDataCount > 1)
1514 nDestCol2 = sal::static_int_cast<SCCOL>(nDestCol1 + nColCount + nColLines);
1515 else
1516 nDestCol2 = sal::static_int_cast<SCCOL>(nDestCol1 + (nColCount - 1) + nColLines);
1517 if (!bMakeTotalCol)
1518 --nDestCol2;
1520 else
1521 nDestCol2 = sal::static_int_cast<SCCOL>(nDestCol1 + nColCount + nColLines);
1524 if (nColCount == 0 || (nColCount==1 && aColArr[0].nCol==PIVOT_DATA_FIELD && nDataCount==1))
1526 nDataRowCount = 1;
1527 if (nDataCount == 1)
1528 nDestRow2 = nDestRow1 + (nRowCount - 1) + nFirstLine + 1;
1529 else
1530 nDestRow2 = nDestRow1 + nRowCount + nFirstLine + 1;
1532 else
1534 SCSIZE nDx;
1535 // Anzahl Zeilen
1536 if ((aColArr[nColCount-1].nCol == PIVOT_DATA_FIELD) && (nDataCount == 1))
1537 nDx = 2;
1538 else
1539 nDx = 1;
1540 SCSIZE nRowLines = pColList[nColCount-nDx]->GetCount(); // SCSIZE to recognize overflow
1541 nDataRowCount = pColList[nColCount-nDx]->GetCount();
1542 for (SCSIZE i=nColCount-nDx; i-- > 0; )
1544 nRowLines *= pColList[i]->GetCount();
1545 nDataRowCount *= pColList[i]->GetCount();
1546 if (bDataAtCol)
1547 nRowLines += (pColList[i]->GetCount() * aColArr[i].nFuncCount * nDataCount);
1548 else
1549 nRowLines += (pColList[i]->GetCount() * aColArr[i].nFuncCount);
1552 // Ergebniszeilen des letzten Elements
1553 if (aColArr[nColCount-1].nCol != PIVOT_DATA_FIELD)
1554 nRowLines += (pColList[nColCount-1]->GetCount() * aColArr[nColCount-1].nFuncCount);
1556 if (nRowLines > static_cast<SCSIZE>(MAXROW))
1557 nDestRow2 = MAXROW+2; // ungueltig, 1 wird unten abgezogen
1558 else if (!bDataAtCol)
1560 if (nDataCount > 1)
1561 nDestRow2 = nDestRow1 + nRowCount + nRowLines + nFirstLine + 1;
1562 else
1563 nDestRow2 = nDestRow1 + (nRowCount - 1) + nRowLines + nFirstLine + 1;
1564 if (!bMakeTotalRow)
1565 --nDestRow2;
1567 else
1568 nDestRow2 = nDestRow1 + nRowCount + nRowLines + nFirstLine + 1;
1571 if (bDataAtCol)
1573 if (!bNoCols)
1574 nDestRow2 += nDataCount;
1575 nDestRow2 --;
1577 else
1579 if (!bNoRows)
1580 nDestCol2 = sal::static_int_cast<SCCOL>(nDestCol2 + nDataCount);
1581 nDestCol2 --;
1585 void ScPivot::SetDataLine(SCCOL nCol, SCROW nRow, SCTAB /* nTab */, SCSIZE nRIndex)
1587 SCSIZE nCIndex2;
1589 SubTotal aGrandTotal[PIVOT_MAXFIELD]; // pro Daten-Feld
1591 for (SCSIZE i=0; i < nColIndex; i++)
1593 SCSIZE nCIndex = pColRef[i].nDataIndex;
1594 if (nCIndex != sal::static_int_cast<SCSIZE>(PIVOT_FUNC_REF))
1596 // if ( ppDataArr[nRIndex][nCIndex].GetCount() )
1598 SCSIZE nDIndex = ppDataArr[nRIndex][nCIndex].nIndex;
1599 SetValue( sal::static_int_cast<SCCOL>(nCol+i), nRow, ppDataArr[nRIndex][nCIndex], aDataArr[nDIndex].nFuncMask );
1600 // Kategorie 18
1602 if (bDataAtCol)
1603 aGrandTotal[0].Update(ppDataArr[nRIndex][nCIndex]);
1604 else
1605 aGrandTotal[nDIndex].Update(ppDataArr[nRIndex][nCIndex]);
1608 else
1610 SubTotal aTotal;
1611 SCSIZE k = i-1;
1612 while ((pColRef[k].nDataIndex == sal::static_int_cast<SCSIZE>(PIVOT_FUNC_REF)) && (k > 0))
1613 k--;
1614 for (SCSIZE j=k+1; (j-- > 0) && (pColRef[j].nRecCount > pColRef[i].nRecCount); )
1616 nCIndex2 = pColRef[j].nDataIndex;
1617 if (nCIndex2 != sal::static_int_cast<SCSIZE>(PIVOT_FUNC_REF))
1619 if ((pColRef[i].nIndex == ppDataArr[nRIndex][nCIndex2].nIndex) ||
1620 (pColRef[i].nIndex == SCSIZE_MAX))
1622 aTotal.Update( ppDataArr[nRIndex][nCIndex2] );
1627 USHORT nFunc = pColRef[i].nFuncMask;
1628 if (nFunc == PIVOT_FUNC_AUTO)
1629 nFunc = aDataArr[nRIndex/nDataMult%nDataCount].nFuncMask;
1630 SetValue( sal::static_int_cast<SCCOL>(nCol+i), nRow, aTotal, nFunc );
1631 // Kategorie 19
1635 BOOL bNoRows = (nRowCount == 0) || ( nRowCount == 1 && aRowArr[0].nCol == PIVOT_DATA_FIELD );
1636 if (!bMakeTotalCol) bNoRows = TRUE;
1638 if (!bNoRows)
1640 if (bDataAtCol)
1642 SetValue( nDestCol2, nRow, aGrandTotal[0], aDataArr[nRIndex/nDataMult%nDataCount].nFuncMask );
1643 // Kategorie 20
1645 else
1647 SCCOL nTotalCol = sal::static_int_cast<SCCOL>(nDestCol2 - nDataCount + 1);
1648 for (SCSIZE nTotCnt = 0; nTotCnt<nDataCount; nTotCnt++)
1650 SetValue( sal::static_int_cast<SCCOL>(nTotalCol+nTotCnt), nRow, aGrandTotal[nTotCnt], aDataArr[nTotCnt].nFuncMask );
1651 // Kategorie 21
1657 void ScPivot::SetFuncLine(SCCOL nCol, SCROW nRow, SCTAB /* nTab */, USHORT nFunc, SCSIZE nIndex, SCSIZE nStartRIndex, SCSIZE nEndRIndex)
1659 SCSIZE nSubtCount = 0;
1660 SubTotal aGrandTotal[PIVOT_MAXFIELD];
1661 USHORT nThisFunc = nFunc;
1663 for (SCSIZE i=0; i<nColIndex; i++)
1665 SCSIZE nCIndex = pColRef[i].nDataIndex;
1666 if (nCIndex != sal::static_int_cast<SCSIZE>(PIVOT_FUNC_REF))
1668 SubTotal aTotal;
1669 for (SCSIZE j = nStartRIndex; j < nEndRIndex; j++)
1671 SCSIZE nDIndex = ppDataArr[j][nCIndex].nIndex;
1672 if ((nIndex == nDIndex) || (nIndex == SCSIZE_MAX))
1674 aTotal.Update( ppDataArr[j][nCIndex] );
1678 if (bDataAtCol)
1679 aGrandTotal[0].Update( aTotal );
1680 else
1681 aGrandTotal[nCIndex/nDataMult%nDataCount].Update( aTotal ); //! immer ?
1683 if (nFunc == PIVOT_FUNC_AUTO)
1685 if (bDataAtCol)
1687 if (nIndex<nDataCount)
1688 nThisFunc = aDataArr[nIndex].nFuncMask;
1689 else
1691 DBG_ERROR("wat fuer'n Index ???");
1694 else
1695 nThisFunc = aDataArr[nCIndex/nDataMult%nDataCount].nFuncMask;
1697 SetValue( sal::static_int_cast<SCCOL>(nCol+i), nRow, aTotal, nThisFunc );
1698 // Kategorie 22
1700 else
1701 { // Kreuzungspunkte kompatibel ?
1703 if ( nFunc == pColRef[i].nFuncMask )
1705 SCSIZE nEffIndex = nIndex;
1706 if (nEffIndex == SCSIZE_MAX)
1708 nEffIndex = nSubtCount % nDataCount;
1709 ++nSubtCount;
1711 SubTotal aTotal;
1713 SCSIZE k = i-1;
1714 while ((pColRef[k].nDataIndex == sal::static_int_cast<SCSIZE>(PIVOT_FUNC_REF)) && (k > 0))
1715 k--;
1716 for (SCSIZE j=k+1; (j-- > 0) && (pColRef[j].nRecCount > pColRef[i].nRecCount); )
1718 nCIndex = pColRef[j].nDataIndex;
1719 if (nCIndex != sal::static_int_cast<SCSIZE>(PIVOT_FUNC_REF))
1721 for (SCSIZE nRIndex = nStartRIndex; nRIndex < nEndRIndex; nRIndex++)
1723 SCSIZE nDIndex = ppDataArr[nRIndex][nCIndex].nIndex;
1724 if (nEffIndex == nDIndex)
1726 aTotal.Update( ppDataArr[nRIndex][nCIndex] );
1732 if (nFunc == PIVOT_FUNC_AUTO)
1734 if (nEffIndex<nDataCount)
1735 nThisFunc = aDataArr[nEffIndex].nFuncMask;
1736 else
1738 DBG_ERROR("wat fuer'n Index ???");
1741 SetValue( sal::static_int_cast<SCCOL>(nCol+i), nRow, aTotal, nThisFunc );
1742 // Kategorie 23
1747 BOOL bNoRows = (nRowCount == 0) || ( nRowCount == 1 && aRowArr[0].nCol == PIVOT_DATA_FIELD );
1748 if (!bMakeTotalCol) bNoRows = TRUE;
1750 if (!bNoRows)
1752 if (bDataAtCol)
1754 if (nFunc == PIVOT_FUNC_AUTO)
1756 if (nIndex<nDataCount)
1757 nThisFunc = aDataArr[nIndex].nFuncMask;
1758 else
1760 DBG_ERROR("wat fuer'n Index ???");
1763 SetValue( nDestCol2, nRow, aGrandTotal[0], nThisFunc );
1764 // Kategorie 24
1766 else
1768 SCCOL nTotalCol = sal::static_int_cast<SCCOL>(nDestCol2 - nDataCount + 1);
1769 for (SCSIZE nTotCnt = 0; nTotCnt<nDataCount; nTotCnt++)
1771 if (nFunc == PIVOT_FUNC_AUTO)
1772 nThisFunc = aDataArr[nTotCnt%nDataCount].nFuncMask;
1773 SetValue( sal::static_int_cast<SCCOL>(nTotalCol+nTotCnt), nRow, aGrandTotal[nTotCnt], nThisFunc );
1774 // Kategorie 25
1780 void ScPivot::ColToTable(SCSIZE nField, SCROW& nRow, ScProgress& rProgress)
1782 SCCOL nCol = sal::static_int_cast<SCCOL>(nDestCol1 + nField);
1783 if (nColCount == 0)
1785 // SetDataLine(nCol + 1, nRow, nDestTab, nRowIndex);
1786 SetDataLine(nCol, nRow, nDestTab, nRowIndex);
1787 nRowIndex++;
1788 return;
1791 SCSIZE nDx;
1792 if ((aColArr[nColCount -1].nCol == PIVOT_DATA_FIELD) && (nDataCount == 1))
1793 nDx = 2;
1794 else
1795 nDx = 1;
1796 if (nField < nColCount - nDx)
1798 for (USHORT i = 0; i < pColList[nField]->GetCount(); i++)
1800 SCSIZE nSaveIndex = nRowIndex;
1801 String aStr = pColList[nField]->GetString(i);
1802 if (!aStr.Len()) aStr = ScGlobal::GetRscString(STR_EMPTYDATA);
1803 pDoc->SetString(nCol, nRow, nDestTab, aStr);
1804 // Kategorie 10
1805 SCROW nSaveRow = nRow;
1806 ColToTable(nField + 1, nRow, rProgress);
1807 SetStyle(nCol, nSaveRow, nCol, nRow - 1, PIVOT_STYLE_CATEGORY);
1808 SetFrame(nCol, nSaveRow, nCol, nRow - 1);
1809 if (aColArr[nField].nFuncCount > 0) // Zwischenergebnisse eingestellt?
1811 nSaveRow = nRow;
1812 for (SCSIZE j=0; j<=PIVOT_MAXFUNC; j++) // incl. "auto"
1814 if (aColArr[nField].nFuncMask & nFuncMaskArr[j])
1816 String aLab;
1817 if (bDataAtCol)
1819 for (SCSIZE k=0; k < nDataCount; k++)
1821 String aDataStr = pDataList->GetString(sal::static_int_cast<USHORT>(k)); // always String
1822 aLab = aStr;
1823 SCSIZE nFuncType;
1824 if ( j==PIVOT_MAXFUNC )
1825 nFuncType = lcl_MaskToIndex( aDataArr[k].nFuncMask );
1826 else
1827 nFuncType = j;
1828 aLab += ' ';
1829 aLab += *pLabel[nFuncType];
1830 aLab += ' ';
1831 aLab += aDataStr;
1832 pDoc->SetString(nCol, nRow, nDestTab, aLab);
1833 // Kategorie 11
1834 SetFuncLine(nDataStartCol, nRow, nDestTab, nFuncMaskArr[j], k, nSaveIndex, nRowIndex);
1835 nRow++;
1838 else
1840 aLab = aStr;
1841 aLab += ' ';
1842 aLab += *pLabel[j];
1843 pDoc->SetString(nCol, nRow, nDestTab, aLab);
1844 // Kategorie 12
1845 SetFuncLine(nDataStartCol, nRow, nDestTab, nFuncMaskArr[j], SCSIZE_MAX, nSaveIndex, nRowIndex);
1846 nRow++;
1850 if ( nDataStartCol > 0 )
1851 SetStyle(nCol, nSaveRow, nDataStartCol-1, nRow-1, PIVOT_STYLE_TITLE);
1852 SetStyle(nDataStartCol, nSaveRow, nDestCol2, nRow-1, PIVOT_STYLE_RESULT);
1853 SetFrameHor(nCol, nSaveRow, nDestCol2, nRow-1);
1855 nSaveIndex = nRowIndex;
1858 else if (nField < nColCount)
1860 SCSIZE nCatCount = pColList[nField]->GetCount();
1861 SetStyle(nCol, nRow, nCol, nRow+nCatCount-1, PIVOT_STYLE_CATEGORY);
1862 SetFrame(nCol, nRow, nDestCol2, nRow+nCatCount-1);
1863 for (SCSIZE i = 0; i < nCatCount; i++)
1865 String aTmpStr = pColList[nField]->GetString(sal::static_int_cast<USHORT>(i));
1866 if (!aTmpStr.Len()) aTmpStr = ScGlobal::GetRscString(STR_EMPTYDATA);
1868 String aPutStr;
1869 if (pColList[nField] == pDataList)
1871 SCSIZE nFuncType = lcl_MaskToIndex( aDataArr[i].nFuncMask );
1872 aPutStr = *pLabel[nFuncType];
1873 aPutStr += ' ';
1874 aPutStr += aTmpStr;
1876 else
1877 aPutStr += aTmpStr;
1879 pDoc->SetString(nCol, nRow, nDestTab, aPutStr);
1880 // Kategorie 13
1881 SetDataLine(nCol + 1, nRow, nDestTab, nRowIndex);
1882 nRowIndex++;
1883 nRow++;
1885 rProgress.SetState( nRow - nDestRow1 );
1890 void ScPivot::RowToTable(SCSIZE nField, SCCOL& nCol)
1892 nRecCount++;
1893 SCROW nRow = nDestRow1 + nFirstLine + nField + 1;
1894 if (nRowCount == 0)
1896 pColRef[nColIndex].nDataIndex = nDataIndex;
1897 nColIndex++;
1898 nDataIndex++;
1899 return;
1902 SCSIZE nDx;
1903 if ((aRowArr[nRowCount -1].nCol == PIVOT_DATA_FIELD) && (nDataCount == 1))
1904 nDx = 2;
1905 else
1906 nDx = 1;
1908 if (nField < nRowCount - nDx)
1910 for (USHORT i = 0; i < pRowList[nField]->GetCount(); i++)
1912 String aStr = pRowList[nField]->GetString(i);
1913 if (!aStr.Len()) aStr = ScGlobal::GetRscString(STR_EMPTYDATA);
1914 pDoc->SetString(nCol, nRow, nDestTab, aStr);
1915 // Kategorie 14
1916 SCCOL nSaveCol = nCol;
1917 RowToTable(nField + 1, nCol);
1918 SetStyle(nSaveCol, nRow, nCol - 1, nRow, PIVOT_STYLE_CATEGORY);
1919 SetFrame(nSaveCol, nRow, nCol - 1, nRow);
1920 if (aRowArr[nField].nFuncCount > 0)
1922 nSaveCol = nCol;
1923 for (SCSIZE j=0; j<=PIVOT_MAXFUNC; j++) // incl. "auto"
1925 if (aRowArr[nField].nFuncMask & nFuncMaskArr[j])
1927 String aLab;
1928 if (!bDataAtCol)
1930 for (SCSIZE k=0; k < nDataCount; k++)
1932 aLab = aStr;
1933 SCSIZE nFuncType;
1934 if ( j==PIVOT_MAXFUNC )
1935 nFuncType = lcl_MaskToIndex( aDataArr[k].nFuncMask );
1936 else
1937 nFuncType = j;
1938 aLab += ' ';
1939 aLab += *pLabel[nFuncType];
1940 aLab += ' ';
1941 aLab += pDataList->GetString(sal::static_int_cast<USHORT>(k));
1942 pDoc->SetString(nCol, nRow, nDestTab, aLab);
1943 // Kategorie 15
1944 pColRef[nColIndex].nDataIndex = PIVOT_FUNC_REF;
1945 pColRef[nColIndex].nRecCount = nRecCount;
1946 pColRef[nColIndex].nIndex = k;
1947 pColRef[nColIndex].nFuncMask = nFuncMaskArr[j];
1948 nColIndex++;
1949 nCol++;
1952 else
1954 aLab = aStr;
1955 aLab += ' ';
1956 aLab += *pLabel[j];
1957 pDoc->SetString(nCol, nRow, nDestTab, aLab);
1958 // Kategorie 16
1959 pColRef[nColIndex].nDataIndex = PIVOT_FUNC_REF;
1960 pColRef[nColIndex].nRecCount = nRecCount;
1961 pColRef[nColIndex].nIndex = SCSIZE_MAX;
1962 pColRef[nColIndex].nFuncMask = nFuncMaskArr[j];
1963 nColIndex++;
1964 nCol++;
1968 if ( nDataStartRow > 0 )
1969 SetStyle(nSaveCol, nRow,
1970 nCol-1, nDataStartRow-1, PIVOT_STYLE_TITLE);
1971 SetStyle(nSaveCol, nDataStartRow, nCol-1, nDestRow2, PIVOT_STYLE_RESULT);
1972 SetFrameVer(nSaveCol, nRow, nCol-1, nDestRow2);
1976 else if (nField < nRowCount)
1978 SCSIZE nCatCount = pRowList[nField]->GetCount();
1979 SetStyle(nCol, nRow, sal::static_int_cast<SCCOL>(nCol+nCatCount-1), nRow, PIVOT_STYLE_CATEGORY);
1980 SetFrame(nCol, nRow, sal::static_int_cast<SCCOL>(nCol+nCatCount-1), nDestRow2);
1981 for (SCSIZE i = 0; i < nCatCount; i++)
1983 String aTmpStr = pRowList[nField]->GetString(sal::static_int_cast<USHORT>(i));
1984 if (!aTmpStr.Len()) aTmpStr = ScGlobal::GetRscString(STR_EMPTYDATA);
1986 String aPutStr;
1987 if (pRowList[nField] == pDataList)
1989 SCSIZE nFuncType = lcl_MaskToIndex( aDataArr[i].nFuncMask );
1990 aPutStr = *pLabel[nFuncType];
1991 aPutStr += ' ';
1992 aPutStr += aTmpStr;
1994 else
1995 aPutStr = aTmpStr;
1997 pDoc->SetString(nCol, nRow, nDestTab, aPutStr);
1998 // Kategorie 17
1999 pColRef[nColIndex].nDataIndex = nDataIndex;
2000 pColRef[nColIndex].nRecCount = nRecCount;
2001 pColRef[nColIndex].nIndex = SCSIZE_MAX;
2002 pColRef[nColIndex].nFuncMask = PIVOT_FUNC_NONE;
2003 nColIndex++;
2004 nDataIndex++;
2005 nCol++;
2008 nRecCount--;
2011 SCROW ScPivot::GetCategoryRow( SCCOL nCol, SCROW nRow )
2013 SCROW nMinRow = nSrcRow1;
2014 if (bHasHeader) ++nMinRow;
2015 BOOL bFound = FALSE;
2018 if ( !pDoc->HasData( nCol, nRow, nSrcTab ) && nRow>nMinRow )
2019 --nRow;
2020 else
2021 bFound = TRUE;
2023 while (!bFound);
2024 return nRow;
2027 #endif