1*b3f79822SAndrew Rist /**************************************************************
2cdf0e10cSrcweir *
3*b3f79822SAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one
4*b3f79822SAndrew Rist * or more contributor license agreements. See the NOTICE file
5*b3f79822SAndrew Rist * distributed with this work for additional information
6*b3f79822SAndrew Rist * regarding copyright ownership. The ASF licenses this file
7*b3f79822SAndrew Rist * to you under the Apache License, Version 2.0 (the
8*b3f79822SAndrew Rist * "License"); you may not use this file except in compliance
9*b3f79822SAndrew Rist * with the License. You may obtain a copy of the License at
10*b3f79822SAndrew Rist *
11*b3f79822SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0
12*b3f79822SAndrew Rist *
13*b3f79822SAndrew Rist * Unless required by applicable law or agreed to in writing,
14*b3f79822SAndrew Rist * software distributed under the License is distributed on an
15*b3f79822SAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*b3f79822SAndrew Rist * KIND, either express or implied. See the License for the
17*b3f79822SAndrew Rist * specific language governing permissions and limitations
18*b3f79822SAndrew Rist * under the License.
19*b3f79822SAndrew Rist *
20*b3f79822SAndrew Rist *************************************************************/
21*b3f79822SAndrew Rist
22*b3f79822SAndrew Rist
23cdf0e10cSrcweir
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_sc.hxx"
26cdf0e10cSrcweir
27cdf0e10cSrcweir
28cdf0e10cSrcweir
29cdf0e10cSrcweir // INCLUDE ---------------------------------------------------------------
30cdf0e10cSrcweir
31cdf0e10cSrcweir #include <tools/debug.hxx>
32cdf0e10cSrcweir
33cdf0e10cSrcweir #include "consoli.hxx"
34cdf0e10cSrcweir #include "document.hxx"
35cdf0e10cSrcweir #include "olinetab.hxx"
36cdf0e10cSrcweir #include "globstr.hrc"
37cdf0e10cSrcweir #include "subtotal.hxx"
38cdf0e10cSrcweir #include "formula/errorcodes.hxx"
39cdf0e10cSrcweir #include "cell.hxx"
40cdf0e10cSrcweir
41cdf0e10cSrcweir #include <math.h>
42cdf0e10cSrcweir #include <string.h>
43cdf0e10cSrcweir
44cdf0e10cSrcweir #define SC_CONS_NOTFOUND -1
45cdf0e10cSrcweir
46cdf0e10cSrcweir // STATIC DATA -----------------------------------------------------------
47cdf0e10cSrcweir
48cdf0e10cSrcweir /* Strings bei Gelegenheit ganz raus...
49cdf0e10cSrcweir static sal_uInt16 nFuncRes[] = { // Reihenfolge wie bei enum ScSubTotalFunc
50cdf0e10cSrcweir 0, // none
51cdf0e10cSrcweir STR_PIVOTFUNC_AVG,
52cdf0e10cSrcweir STR_PIVOTFUNC_COUNT,
53cdf0e10cSrcweir STR_PIVOTFUNC_COUNT2,
54cdf0e10cSrcweir STR_PIVOTFUNC_MAX,
55cdf0e10cSrcweir STR_PIVOTFUNC_MIN,
56cdf0e10cSrcweir STR_PIVOTFUNC_PROD,
57cdf0e10cSrcweir STR_PIVOTFUNC_STDDEV,
58cdf0e10cSrcweir STR_PIVOTFUNC_STDDEV2,
59cdf0e10cSrcweir STR_PIVOTFUNC_SUM,
60cdf0e10cSrcweir STR_PIVOTFUNC_VAR,
61cdf0e10cSrcweir STR_PIVOTFUNC_VAR2 };
62cdf0e10cSrcweir */
63cdf0e10cSrcweir
64cdf0e10cSrcweir static OpCode eOpCodeTable[] = { // Reihenfolge wie bei enum ScSubTotalFunc
65cdf0e10cSrcweir ocBad, // none
66cdf0e10cSrcweir ocAverage,
67cdf0e10cSrcweir ocCount,
68cdf0e10cSrcweir ocCount2,
69cdf0e10cSrcweir ocMax,
70cdf0e10cSrcweir ocMin,
71cdf0e10cSrcweir ocProduct,
72cdf0e10cSrcweir ocStDev,
73cdf0e10cSrcweir ocStDevP,
74cdf0e10cSrcweir ocSum,
75cdf0e10cSrcweir ocVar,
76cdf0e10cSrcweir ocVarP };
77cdf0e10cSrcweir
78cdf0e10cSrcweir // -----------------------------------------------------------------------
79cdf0e10cSrcweir
AddEntry(SCCOL nCol,SCROW nRow,SCTAB nTab)80cdf0e10cSrcweir void ScReferenceList::AddEntry( SCCOL nCol, SCROW nRow, SCTAB nTab )
81cdf0e10cSrcweir {
82cdf0e10cSrcweir ScReferenceEntry* pOldData = pData;
83cdf0e10cSrcweir pData = new ScReferenceEntry[ nFullSize+1 ];
84cdf0e10cSrcweir if (pOldData)
85cdf0e10cSrcweir {
86cdf0e10cSrcweir memmove( pData, pOldData, nCount * sizeof(ScReferenceEntry) );
87cdf0e10cSrcweir delete[] pOldData;
88cdf0e10cSrcweir }
89cdf0e10cSrcweir while (nCount < nFullSize)
90cdf0e10cSrcweir {
91cdf0e10cSrcweir pData[nCount].nCol = SC_CONS_NOTFOUND;
92cdf0e10cSrcweir pData[nCount].nRow = SC_CONS_NOTFOUND;
93cdf0e10cSrcweir pData[nCount].nTab = SC_CONS_NOTFOUND;
94cdf0e10cSrcweir ++nCount;
95cdf0e10cSrcweir }
96cdf0e10cSrcweir pData[nCount].nCol = nCol;
97cdf0e10cSrcweir pData[nCount].nRow = nRow;
98cdf0e10cSrcweir pData[nCount].nTab = nTab;
99cdf0e10cSrcweir ++nCount;
100cdf0e10cSrcweir nFullSize = nCount;
101cdf0e10cSrcweir }
102cdf0e10cSrcweir
103cdf0e10cSrcweir template< typename T >
lcl_AddString(String ** & pData,T & nCount,const String & rInsert)104cdf0e10cSrcweir void lcl_AddString( String**& pData, T& nCount, const String& rInsert )
105cdf0e10cSrcweir {
106cdf0e10cSrcweir String** pOldData = pData;
107cdf0e10cSrcweir pData = new String*[ nCount+1 ];
108cdf0e10cSrcweir if (pOldData)
109cdf0e10cSrcweir {
110cdf0e10cSrcweir memmove( pData, pOldData, nCount * sizeof(String*) );
111cdf0e10cSrcweir delete[] pOldData;
112cdf0e10cSrcweir }
113cdf0e10cSrcweir pData[nCount] = new String(rInsert);
114cdf0e10cSrcweir ++nCount;
115cdf0e10cSrcweir }
116cdf0e10cSrcweir
117cdf0e10cSrcweir // -----------------------------------------------------------------------
118cdf0e10cSrcweir
ScConsData()119cdf0e10cSrcweir ScConsData::ScConsData() :
120cdf0e10cSrcweir eFunction(SUBTOTAL_FUNC_SUM),
121cdf0e10cSrcweir bReference(sal_False),
122cdf0e10cSrcweir bColByName(sal_False),
123cdf0e10cSrcweir bRowByName(sal_False),
124cdf0e10cSrcweir bSubTitles(sal_False),
125cdf0e10cSrcweir nColCount(0),
126cdf0e10cSrcweir nRowCount(0),
127cdf0e10cSrcweir ppUsed(NULL),
128cdf0e10cSrcweir ppSum(NULL),
129cdf0e10cSrcweir ppCount(NULL),
130cdf0e10cSrcweir ppSumSqr(NULL),
131cdf0e10cSrcweir ppRefs(NULL),
132cdf0e10cSrcweir ppColHeaders(NULL),
133cdf0e10cSrcweir ppRowHeaders(NULL),
134cdf0e10cSrcweir nDataCount(0),
135cdf0e10cSrcweir nTitleCount(0),
136cdf0e10cSrcweir ppTitles(NULL),
137cdf0e10cSrcweir ppTitlePos(NULL),
138cdf0e10cSrcweir bCornerUsed(sal_False)
139cdf0e10cSrcweir {
140cdf0e10cSrcweir }
141cdf0e10cSrcweir
~ScConsData()142cdf0e10cSrcweir ScConsData::~ScConsData()
143cdf0e10cSrcweir {
144cdf0e10cSrcweir DeleteData();
145cdf0e10cSrcweir }
146cdf0e10cSrcweir
147cdf0e10cSrcweir
148cdf0e10cSrcweir #define DELETEARR(ppArray,nCount) \
149cdf0e10cSrcweir { \
150cdf0e10cSrcweir sal_uLong i; \
151cdf0e10cSrcweir if (ppArray) \
152cdf0e10cSrcweir for(i=0; i<nCount; i++) \
153cdf0e10cSrcweir delete[] ppArray[i]; \
154cdf0e10cSrcweir delete[] ppArray; \
155cdf0e10cSrcweir ppArray = NULL; \
156cdf0e10cSrcweir }
157cdf0e10cSrcweir
158cdf0e10cSrcweir #define DELETESTR(ppArray,nCount) \
159cdf0e10cSrcweir { \
160cdf0e10cSrcweir sal_uLong i; \
161cdf0e10cSrcweir if (ppArray) \
162cdf0e10cSrcweir for(i=0; i<nCount; i++) \
163cdf0e10cSrcweir delete ppArray[i]; \
164cdf0e10cSrcweir delete[] ppArray; \
165cdf0e10cSrcweir ppArray = NULL; \
166cdf0e10cSrcweir }
167cdf0e10cSrcweir
DeleteData()168cdf0e10cSrcweir void ScConsData::DeleteData()
169cdf0e10cSrcweir {
170cdf0e10cSrcweir if (ppRefs)
171cdf0e10cSrcweir {
172cdf0e10cSrcweir for (SCSIZE i=0; i<nColCount; i++)
173cdf0e10cSrcweir {
174cdf0e10cSrcweir for (SCSIZE j=0; j<nRowCount; j++)
175cdf0e10cSrcweir if (ppUsed[i][j])
176cdf0e10cSrcweir ppRefs[i][j].Clear();
177cdf0e10cSrcweir delete[] ppRefs[i];
178cdf0e10cSrcweir }
179cdf0e10cSrcweir delete[] ppRefs;
180cdf0e10cSrcweir ppRefs = NULL;
181cdf0e10cSrcweir }
182cdf0e10cSrcweir
183cdf0e10cSrcweir // DELETEARR( ppData1, nColCount );
184cdf0e10cSrcweir // DELETEARR( ppData2, nColCount );
185cdf0e10cSrcweir DELETEARR( ppCount, nColCount );
186cdf0e10cSrcweir DELETEARR( ppSum, nColCount );
187cdf0e10cSrcweir DELETEARR( ppSumSqr,nColCount );
188cdf0e10cSrcweir DELETEARR( ppUsed, nColCount ); // erst nach ppRefs !!!
189cdf0e10cSrcweir DELETEARR( ppTitlePos, nRowCount );
190cdf0e10cSrcweir DELETESTR( ppColHeaders, nColCount );
191cdf0e10cSrcweir DELETESTR( ppRowHeaders, nRowCount );
192cdf0e10cSrcweir DELETESTR( ppTitles, nTitleCount );
193cdf0e10cSrcweir nTitleCount = 0;
194cdf0e10cSrcweir nDataCount = 0;
195cdf0e10cSrcweir
196cdf0e10cSrcweir if (bColByName) nColCount = 0; // sonst stimmt ppColHeaders nicht
197cdf0e10cSrcweir if (bRowByName) nRowCount = 0;
198cdf0e10cSrcweir
199cdf0e10cSrcweir bCornerUsed = sal_False;
200cdf0e10cSrcweir aCornerText.Erase();
201cdf0e10cSrcweir }
202cdf0e10cSrcweir
203cdf0e10cSrcweir #undef DELETEARR
204cdf0e10cSrcweir #undef DELETESTR
205cdf0e10cSrcweir
InitData(sal_Bool bDelete)206cdf0e10cSrcweir void ScConsData::InitData( sal_Bool bDelete )
207cdf0e10cSrcweir {
208cdf0e10cSrcweir if (bDelete)
209cdf0e10cSrcweir DeleteData();
210cdf0e10cSrcweir
211cdf0e10cSrcweir if (bReference && nColCount && !ppRefs)
212cdf0e10cSrcweir {
213cdf0e10cSrcweir ppRefs = new ScReferenceList*[nColCount];
214cdf0e10cSrcweir for (SCSIZE i=0; i<nColCount; i++)
215cdf0e10cSrcweir ppRefs[i] = new ScReferenceList[nRowCount];
216cdf0e10cSrcweir }
217cdf0e10cSrcweir else if (nColCount && !ppCount)
218cdf0e10cSrcweir {
219cdf0e10cSrcweir ppCount = new double*[nColCount];
220cdf0e10cSrcweir ppSum = new double*[nColCount];
221cdf0e10cSrcweir ppSumSqr = new double*[nColCount];
222cdf0e10cSrcweir for (SCSIZE i=0; i<nColCount; i++)
223cdf0e10cSrcweir {
224cdf0e10cSrcweir ppCount[i] = new double[nRowCount];
225cdf0e10cSrcweir ppSum[i] = new double[nRowCount];
226cdf0e10cSrcweir ppSumSqr[i] = new double[nRowCount];
227cdf0e10cSrcweir }
228cdf0e10cSrcweir }
229cdf0e10cSrcweir
230cdf0e10cSrcweir if (nColCount && !ppUsed)
231cdf0e10cSrcweir {
232cdf0e10cSrcweir ppUsed = new sal_Bool*[nColCount];
233cdf0e10cSrcweir for (SCSIZE i=0; i<nColCount; i++)
234cdf0e10cSrcweir {
235cdf0e10cSrcweir ppUsed[i] = new sal_Bool[nRowCount];
236cdf0e10cSrcweir memset( ppUsed[i], 0, nRowCount * sizeof(sal_Bool) );
237cdf0e10cSrcweir }
238cdf0e10cSrcweir }
239cdf0e10cSrcweir
240cdf0e10cSrcweir if (nRowCount && nDataCount && !ppTitlePos)
241cdf0e10cSrcweir {
242cdf0e10cSrcweir ppTitlePos = new SCSIZE*[nRowCount];
243cdf0e10cSrcweir for (SCSIZE i=0; i<nRowCount; i++)
244cdf0e10cSrcweir {
245cdf0e10cSrcweir ppTitlePos[i] = new SCSIZE[nDataCount];
246cdf0e10cSrcweir memset( ppTitlePos[i], 0, nDataCount * sizeof(SCSIZE) ); //! unnoetig ?
247cdf0e10cSrcweir }
248cdf0e10cSrcweir }
249cdf0e10cSrcweir
250cdf0e10cSrcweir // CornerText: einzelner String
251cdf0e10cSrcweir }
252cdf0e10cSrcweir
DoneFields()253cdf0e10cSrcweir void ScConsData::DoneFields()
254cdf0e10cSrcweir {
255cdf0e10cSrcweir InitData(sal_False);
256cdf0e10cSrcweir }
257cdf0e10cSrcweir
SetSize(SCCOL nCols,SCROW nRows)258cdf0e10cSrcweir void ScConsData::SetSize( SCCOL nCols, SCROW nRows )
259cdf0e10cSrcweir {
260cdf0e10cSrcweir DeleteData();
261cdf0e10cSrcweir nColCount = static_cast<SCSIZE>(nCols);
262cdf0e10cSrcweir nRowCount = static_cast<SCSIZE>(nRows);
263cdf0e10cSrcweir }
264cdf0e10cSrcweir
GetSize(SCCOL & rCols,SCROW & rRows) const265cdf0e10cSrcweir void ScConsData::GetSize( SCCOL& rCols, SCROW& rRows ) const
266cdf0e10cSrcweir {
267cdf0e10cSrcweir rCols = static_cast<SCCOL>(nColCount);
268cdf0e10cSrcweir rRows = static_cast<SCROW>(nRowCount);
269cdf0e10cSrcweir }
270cdf0e10cSrcweir
SetFlags(ScSubTotalFunc eFunc,sal_Bool bColName,sal_Bool bRowName,sal_Bool bRef)271cdf0e10cSrcweir void ScConsData::SetFlags( ScSubTotalFunc eFunc, sal_Bool bColName, sal_Bool bRowName, sal_Bool bRef )
272cdf0e10cSrcweir {
273cdf0e10cSrcweir DeleteData();
274cdf0e10cSrcweir bReference = bRef;
275cdf0e10cSrcweir bColByName = bColName;
276cdf0e10cSrcweir if (bColName) nColCount = 0;
277cdf0e10cSrcweir bRowByName = bRowName;
278cdf0e10cSrcweir if (bRowName) nRowCount = 0;
279cdf0e10cSrcweir eFunction = eFunc;
280cdf0e10cSrcweir }
281cdf0e10cSrcweir
AddFields(ScDocument * pSrcDoc,SCTAB nTab,SCCOL nCol1,SCROW nRow1,SCCOL nCol2,SCROW nRow2)282cdf0e10cSrcweir void ScConsData::AddFields( ScDocument* pSrcDoc, SCTAB nTab,
283cdf0e10cSrcweir SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 )
284cdf0e10cSrcweir {
285cdf0e10cSrcweir ++nDataCount;
286cdf0e10cSrcweir
287cdf0e10cSrcweir String aTitle;
288cdf0e10cSrcweir
289cdf0e10cSrcweir SCCOL nStartCol = nCol1;
290cdf0e10cSrcweir SCROW nStartRow = nRow1;
291cdf0e10cSrcweir if (bColByName) ++nStartRow;
292cdf0e10cSrcweir if (bRowByName) ++nStartCol;
293cdf0e10cSrcweir
294cdf0e10cSrcweir if (bColByName)
295cdf0e10cSrcweir {
296cdf0e10cSrcweir for (SCCOL nCol=nStartCol; nCol<=nCol2; nCol++)
297cdf0e10cSrcweir {
298cdf0e10cSrcweir pSrcDoc->GetString( nCol, nRow1, nTab, aTitle );
299cdf0e10cSrcweir if (aTitle.Len())
300cdf0e10cSrcweir {
301cdf0e10cSrcweir sal_Bool bFound = sal_False;
302cdf0e10cSrcweir for (SCSIZE i=0; i<nColCount && !bFound; i++)
303cdf0e10cSrcweir if ( *ppColHeaders[i] == aTitle )
304cdf0e10cSrcweir bFound = sal_True;
305cdf0e10cSrcweir if (!bFound)
306cdf0e10cSrcweir lcl_AddString( ppColHeaders, nColCount, aTitle );
307cdf0e10cSrcweir }
308cdf0e10cSrcweir }
309cdf0e10cSrcweir }
310cdf0e10cSrcweir
311cdf0e10cSrcweir if (bRowByName)
312cdf0e10cSrcweir {
313cdf0e10cSrcweir for (SCROW nRow=nStartRow; nRow<=nRow2; nRow++)
314cdf0e10cSrcweir {
315cdf0e10cSrcweir pSrcDoc->GetString( nCol1, nRow, nTab, aTitle );
316cdf0e10cSrcweir if (aTitle.Len())
317cdf0e10cSrcweir {
318cdf0e10cSrcweir sal_Bool bFound = sal_False;
319cdf0e10cSrcweir for (SCSIZE i=0; i<nRowCount && !bFound; i++)
320cdf0e10cSrcweir if ( *ppRowHeaders[i] == aTitle )
321cdf0e10cSrcweir bFound = sal_True;
322cdf0e10cSrcweir if (!bFound)
323cdf0e10cSrcweir lcl_AddString( ppRowHeaders, nRowCount, aTitle );
324cdf0e10cSrcweir }
325cdf0e10cSrcweir }
326cdf0e10cSrcweir }
327cdf0e10cSrcweir }
328cdf0e10cSrcweir
AddName(const String & rName)329cdf0e10cSrcweir void ScConsData::AddName( const String& rName )
330cdf0e10cSrcweir {
331cdf0e10cSrcweir SCSIZE nArrX;
332cdf0e10cSrcweir SCSIZE nArrY;
333cdf0e10cSrcweir
334cdf0e10cSrcweir if (bReference)
335cdf0e10cSrcweir {
336cdf0e10cSrcweir lcl_AddString( ppTitles, nTitleCount, rName );
337cdf0e10cSrcweir
338cdf0e10cSrcweir for (nArrY=0; nArrY<nRowCount; nArrY++)
339cdf0e10cSrcweir {
340cdf0e10cSrcweir // Daten auf gleiche Laenge bringen
341cdf0e10cSrcweir
342cdf0e10cSrcweir SCSIZE nMax = 0;
343cdf0e10cSrcweir for (nArrX=0; nArrX<nColCount; nArrX++)
344cdf0e10cSrcweir if (ppUsed[nArrX][nArrY])
345cdf0e10cSrcweir nMax = Max( nMax, ppRefs[nArrX][nArrY].GetCount() );
346cdf0e10cSrcweir
347cdf0e10cSrcweir for (nArrX=0; nArrX<nColCount; nArrX++)
348cdf0e10cSrcweir {
349cdf0e10cSrcweir if (!ppUsed[nArrX][nArrY])
350cdf0e10cSrcweir {
351cdf0e10cSrcweir ppUsed[nArrX][nArrY] = sal_True;
352cdf0e10cSrcweir ppRefs[nArrX][nArrY].Init();
353cdf0e10cSrcweir }
354cdf0e10cSrcweir ppRefs[nArrX][nArrY].SetFullSize(nMax);
355cdf0e10cSrcweir }
356cdf0e10cSrcweir
357cdf0e10cSrcweir // Positionen eintragen
358cdf0e10cSrcweir
359cdf0e10cSrcweir if (ppTitlePos)
360cdf0e10cSrcweir if (nTitleCount < nDataCount)
361cdf0e10cSrcweir ppTitlePos[nArrY][nTitleCount] = nMax;
362cdf0e10cSrcweir }
363cdf0e10cSrcweir }
364cdf0e10cSrcweir }
365cdf0e10cSrcweir
366cdf0e10cSrcweir // rCount < 0 <=> Fehler aufgetreten
367cdf0e10cSrcweir
lcl_UpdateArray(ScSubTotalFunc eFunc,double & rCount,double & rSum,double & rSumSqr,double nVal)368cdf0e10cSrcweir void lcl_UpdateArray( ScSubTotalFunc eFunc,
369cdf0e10cSrcweir double& rCount, double& rSum, double& rSumSqr, double nVal )
370cdf0e10cSrcweir {
371cdf0e10cSrcweir if (rCount < 0.0)
372cdf0e10cSrcweir return;
373cdf0e10cSrcweir switch (eFunc)
374cdf0e10cSrcweir {
375cdf0e10cSrcweir case SUBTOTAL_FUNC_SUM:
376cdf0e10cSrcweir if (!SubTotal::SafePlus(rSum, nVal))
377cdf0e10cSrcweir rCount = -MAXDOUBLE;
378cdf0e10cSrcweir break;
379cdf0e10cSrcweir case SUBTOTAL_FUNC_PROD:
380cdf0e10cSrcweir if (!SubTotal::SafeMult(rSum, nVal))
381cdf0e10cSrcweir rCount = -MAXDOUBLE;
382cdf0e10cSrcweir break;
383cdf0e10cSrcweir case SUBTOTAL_FUNC_CNT:
384cdf0e10cSrcweir case SUBTOTAL_FUNC_CNT2:
385cdf0e10cSrcweir rCount += 1.0;
386cdf0e10cSrcweir break;
387cdf0e10cSrcweir case SUBTOTAL_FUNC_AVE:
388cdf0e10cSrcweir if (!SubTotal::SafePlus(rSum, nVal))
389cdf0e10cSrcweir rCount = -MAXDOUBLE;
390cdf0e10cSrcweir else
391cdf0e10cSrcweir rCount += 1.0;
392cdf0e10cSrcweir break;
393cdf0e10cSrcweir case SUBTOTAL_FUNC_MAX:
394cdf0e10cSrcweir if (nVal > rSum)
395cdf0e10cSrcweir rSum = nVal;
396cdf0e10cSrcweir break;
397cdf0e10cSrcweir case SUBTOTAL_FUNC_MIN:
398cdf0e10cSrcweir if (nVal < rSum)
399cdf0e10cSrcweir rSum = nVal;
400cdf0e10cSrcweir break;
401cdf0e10cSrcweir case SUBTOTAL_FUNC_STD:
402cdf0e10cSrcweir case SUBTOTAL_FUNC_STDP:
403cdf0e10cSrcweir case SUBTOTAL_FUNC_VAR:
404cdf0e10cSrcweir case SUBTOTAL_FUNC_VARP:
405cdf0e10cSrcweir {
406cdf0e10cSrcweir sal_Bool bOk = SubTotal::SafePlus(rSum, nVal);
407cdf0e10cSrcweir bOk = bOk && SubTotal::SafeMult(nVal, nVal);
408cdf0e10cSrcweir bOk = bOk && SubTotal::SafePlus(rSumSqr, nVal);
409cdf0e10cSrcweir if (!bOk)
410cdf0e10cSrcweir rCount = -MAXDOUBLE;
411cdf0e10cSrcweir else
412cdf0e10cSrcweir rCount += 1.0;
413cdf0e10cSrcweir break;
414cdf0e10cSrcweir }
415cdf0e10cSrcweir default:
416cdf0e10cSrcweir {
417cdf0e10cSrcweir // added to avoid warnings
418cdf0e10cSrcweir }
419cdf0e10cSrcweir }
420cdf0e10cSrcweir }
421cdf0e10cSrcweir
lcl_InitArray(ScSubTotalFunc eFunc,double & rCount,double & rSum,double & rSumSqr,double nVal)422cdf0e10cSrcweir void lcl_InitArray( ScSubTotalFunc eFunc,
423cdf0e10cSrcweir double& rCount, double& rSum, double& rSumSqr, double nVal )
424cdf0e10cSrcweir {
425cdf0e10cSrcweir rCount = 1.0;
426cdf0e10cSrcweir switch (eFunc)
427cdf0e10cSrcweir {
428cdf0e10cSrcweir case SUBTOTAL_FUNC_SUM:
429cdf0e10cSrcweir case SUBTOTAL_FUNC_MAX:
430cdf0e10cSrcweir case SUBTOTAL_FUNC_MIN:
431cdf0e10cSrcweir case SUBTOTAL_FUNC_PROD:
432cdf0e10cSrcweir case SUBTOTAL_FUNC_AVE:
433cdf0e10cSrcweir rSum = nVal;
434cdf0e10cSrcweir break;
435cdf0e10cSrcweir case SUBTOTAL_FUNC_STD:
436cdf0e10cSrcweir case SUBTOTAL_FUNC_STDP:
437cdf0e10cSrcweir case SUBTOTAL_FUNC_VAR:
438cdf0e10cSrcweir case SUBTOTAL_FUNC_VARP:
439cdf0e10cSrcweir {
440cdf0e10cSrcweir rSum = nVal;
441cdf0e10cSrcweir sal_Bool bOk = SubTotal::SafeMult(nVal, nVal);
442cdf0e10cSrcweir if (bOk)
443cdf0e10cSrcweir rSumSqr = nVal;
444cdf0e10cSrcweir else
445cdf0e10cSrcweir rCount = -MAXDOUBLE;
446cdf0e10cSrcweir }
447cdf0e10cSrcweir break;
448cdf0e10cSrcweir default:
449cdf0e10cSrcweir break;
450cdf0e10cSrcweir }
451cdf0e10cSrcweir }
452cdf0e10cSrcweir
lcl_CalcData(ScSubTotalFunc eFunc,double fCount,double fSum,double fSumSqr)453cdf0e10cSrcweir double lcl_CalcData( ScSubTotalFunc eFunc,
454cdf0e10cSrcweir double fCount, double fSum, double fSumSqr)
455cdf0e10cSrcweir {
456cdf0e10cSrcweir if (fCount < 0.0)
457cdf0e10cSrcweir return 0.0;
458cdf0e10cSrcweir double fVal = 0.0;
459cdf0e10cSrcweir switch (eFunc)
460cdf0e10cSrcweir {
461cdf0e10cSrcweir case SUBTOTAL_FUNC_CNT:
462cdf0e10cSrcweir case SUBTOTAL_FUNC_CNT2:
463cdf0e10cSrcweir fVal = fCount;
464cdf0e10cSrcweir break;
465cdf0e10cSrcweir case SUBTOTAL_FUNC_SUM:
466cdf0e10cSrcweir case SUBTOTAL_FUNC_MAX:
467cdf0e10cSrcweir case SUBTOTAL_FUNC_MIN:
468cdf0e10cSrcweir case SUBTOTAL_FUNC_PROD:
469cdf0e10cSrcweir fVal = fSum;
470cdf0e10cSrcweir break;
471cdf0e10cSrcweir case SUBTOTAL_FUNC_AVE:
472cdf0e10cSrcweir if (fCount > 0.0)
473cdf0e10cSrcweir fVal = fSum / fCount;
474cdf0e10cSrcweir else
475cdf0e10cSrcweir fCount = -MAXDOUBLE;
476cdf0e10cSrcweir break;
477cdf0e10cSrcweir case SUBTOTAL_FUNC_STD:
478cdf0e10cSrcweir {
479cdf0e10cSrcweir if (fCount > 1 && SubTotal::SafeMult(fSum, fSum))
480cdf0e10cSrcweir fVal = sqrt((fSumSqr - fSum/fCount)/(fCount-1.0));
481cdf0e10cSrcweir else
482cdf0e10cSrcweir fCount = -MAXDOUBLE;
483cdf0e10cSrcweir }
484cdf0e10cSrcweir break;
485cdf0e10cSrcweir case SUBTOTAL_FUNC_STDP:
486cdf0e10cSrcweir {
487cdf0e10cSrcweir if (fCount > 0 && SubTotal::SafeMult(fSum, fSum))
488cdf0e10cSrcweir fVal = sqrt((fSumSqr - fSum/fCount)/fCount);
489cdf0e10cSrcweir else
490cdf0e10cSrcweir fCount = -MAXDOUBLE;
491cdf0e10cSrcweir }
492cdf0e10cSrcweir break;
493cdf0e10cSrcweir case SUBTOTAL_FUNC_VAR:
494cdf0e10cSrcweir {
495cdf0e10cSrcweir if (fCount > 1 && SubTotal::SafeMult(fSum, fSum))
496cdf0e10cSrcweir fVal = (fSumSqr - fSum/fCount)/(fCount-1.0);
497cdf0e10cSrcweir else
498cdf0e10cSrcweir fCount = -MAXDOUBLE;
499cdf0e10cSrcweir }
500cdf0e10cSrcweir break;
501cdf0e10cSrcweir case SUBTOTAL_FUNC_VARP:
502cdf0e10cSrcweir {
503cdf0e10cSrcweir if (fCount > 0 && SubTotal::SafeMult(fSum, fSum))
504cdf0e10cSrcweir fVal = (fSumSqr - fSum/fCount)/fCount;
505cdf0e10cSrcweir else
506cdf0e10cSrcweir fCount = -MAXDOUBLE;
507cdf0e10cSrcweir }
508cdf0e10cSrcweir break;
509cdf0e10cSrcweir default:
510cdf0e10cSrcweir {
511cdf0e10cSrcweir DBG_ERROR("unbekannte Funktion bei Consoli::CalcData");
512cdf0e10cSrcweir fCount = -MAXDOUBLE;
513cdf0e10cSrcweir }
514cdf0e10cSrcweir break;
515cdf0e10cSrcweir }
516cdf0e10cSrcweir return fVal;
517cdf0e10cSrcweir }
518cdf0e10cSrcweir
AddData(ScDocument * pSrcDoc,SCTAB nTab,SCCOL nCol1,SCROW nRow1,SCCOL nCol2,SCROW nRow2)519cdf0e10cSrcweir void ScConsData::AddData( ScDocument* pSrcDoc, SCTAB nTab,
520cdf0e10cSrcweir SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 )
521cdf0e10cSrcweir {
522cdf0e10cSrcweir PutInOrder(nCol1,nCol2);
523cdf0e10cSrcweir PutInOrder(nRow1,nRow2);
524cdf0e10cSrcweir if ( nCol2 >= sal::static_int_cast<SCCOL>(nCol1 + nColCount) && !bColByName )
525cdf0e10cSrcweir {
526cdf0e10cSrcweir DBG_ASSERT(0,"Bereich zu gross");
527cdf0e10cSrcweir nCol2 = sal::static_int_cast<SCCOL>( nCol1 + nColCount - 1 );
528cdf0e10cSrcweir }
529cdf0e10cSrcweir if ( nRow2 >= sal::static_int_cast<SCROW>(nRow1 + nRowCount) && !bRowByName )
530cdf0e10cSrcweir {
531cdf0e10cSrcweir DBG_ASSERT(0,"Bereich zu gross");
532cdf0e10cSrcweir nRow2 = sal::static_int_cast<SCROW>( nRow1 + nRowCount - 1 );
533cdf0e10cSrcweir }
534cdf0e10cSrcweir
535cdf0e10cSrcweir SCCOL nCol;
536cdf0e10cSrcweir SCROW nRow;
537cdf0e10cSrcweir
538cdf0e10cSrcweir // Ecke links oben
539cdf0e10cSrcweir
540cdf0e10cSrcweir if ( bColByName && bRowByName )
541cdf0e10cSrcweir {
542cdf0e10cSrcweir String aThisCorner;
543cdf0e10cSrcweir pSrcDoc->GetString(nCol1,nRow1,nTab,aThisCorner);
544cdf0e10cSrcweir if (bCornerUsed)
545cdf0e10cSrcweir {
546cdf0e10cSrcweir if (aCornerText != aThisCorner)
547cdf0e10cSrcweir aCornerText.Erase();
548cdf0e10cSrcweir }
549cdf0e10cSrcweir else
550cdf0e10cSrcweir {
551cdf0e10cSrcweir aCornerText = aThisCorner;
552cdf0e10cSrcweir bCornerUsed = sal_True;
553cdf0e10cSrcweir }
554cdf0e10cSrcweir }
555cdf0e10cSrcweir
556cdf0e10cSrcweir // Titel suchen
557cdf0e10cSrcweir
558cdf0e10cSrcweir SCCOL nStartCol = nCol1;
559cdf0e10cSrcweir SCROW nStartRow = nRow1;
560cdf0e10cSrcweir if (bColByName) ++nStartRow;
561cdf0e10cSrcweir if (bRowByName) ++nStartCol;
562cdf0e10cSrcweir String aTitle;
563cdf0e10cSrcweir SCCOL* pDestCols = NULL;
564cdf0e10cSrcweir SCROW* pDestRows = NULL;
565cdf0e10cSrcweir if (bColByName)
566cdf0e10cSrcweir {
567cdf0e10cSrcweir pDestCols = new SCCOL[nCol2-nStartCol+1];
568cdf0e10cSrcweir for (nCol=nStartCol; nCol<=nCol2; nCol++)
569cdf0e10cSrcweir {
570cdf0e10cSrcweir pSrcDoc->GetString(nCol,nRow1,nTab,aTitle);
571cdf0e10cSrcweir SCCOL nPos = SC_CONS_NOTFOUND;
572cdf0e10cSrcweir if (aTitle.Len())
573cdf0e10cSrcweir {
574cdf0e10cSrcweir sal_Bool bFound = sal_False;
575cdf0e10cSrcweir for (SCSIZE i=0; i<nColCount && !bFound; i++)
576cdf0e10cSrcweir if ( *ppColHeaders[i] == aTitle )
577cdf0e10cSrcweir {
578cdf0e10cSrcweir nPos = static_cast<SCCOL>(i);
579cdf0e10cSrcweir bFound = sal_True;
580cdf0e10cSrcweir }
581cdf0e10cSrcweir DBG_ASSERT(bFound, "Spalte nicht gefunden");
582cdf0e10cSrcweir }
583cdf0e10cSrcweir pDestCols[nCol-nStartCol] = nPos;
584cdf0e10cSrcweir }
585cdf0e10cSrcweir }
586cdf0e10cSrcweir if (bRowByName)
587cdf0e10cSrcweir {
588cdf0e10cSrcweir pDestRows = new SCROW[nRow2-nStartRow+1];
589cdf0e10cSrcweir for (nRow=nStartRow; nRow<=nRow2; nRow++)
590cdf0e10cSrcweir {
591cdf0e10cSrcweir pSrcDoc->GetString(nCol1,nRow,nTab,aTitle);
592cdf0e10cSrcweir SCROW nPos = SC_CONS_NOTFOUND;
593cdf0e10cSrcweir if (aTitle.Len())
594cdf0e10cSrcweir {
595cdf0e10cSrcweir sal_Bool bFound = sal_False;
596cdf0e10cSrcweir for (SCSIZE i=0; i<nRowCount && !bFound; i++)
597cdf0e10cSrcweir if ( *ppRowHeaders[i] == aTitle )
598cdf0e10cSrcweir {
599cdf0e10cSrcweir nPos = static_cast<SCROW>(i);
600cdf0e10cSrcweir bFound = sal_True;
601cdf0e10cSrcweir }
602cdf0e10cSrcweir DBG_ASSERT(bFound, "Zeile nicht gefunden");
603cdf0e10cSrcweir }
604cdf0e10cSrcweir pDestRows[nRow-nStartRow] = nPos;
605cdf0e10cSrcweir }
606cdf0e10cSrcweir }
607cdf0e10cSrcweir nCol1 = nStartCol;
608cdf0e10cSrcweir nRow1 = nStartRow;
609cdf0e10cSrcweir
610cdf0e10cSrcweir // Daten
611cdf0e10cSrcweir
612cdf0e10cSrcweir sal_Bool bAnyCell = ( eFunction == SUBTOTAL_FUNC_CNT2 );
613cdf0e10cSrcweir for (nCol=nCol1; nCol<=nCol2; nCol++)
614cdf0e10cSrcweir {
615cdf0e10cSrcweir SCCOL nArrX = nCol-nCol1;
616cdf0e10cSrcweir if (bColByName) nArrX = pDestCols[nArrX];
617cdf0e10cSrcweir if (nArrX != SC_CONS_NOTFOUND)
618cdf0e10cSrcweir {
619cdf0e10cSrcweir for (nRow=nRow1; nRow<=nRow2; nRow++)
620cdf0e10cSrcweir {
621cdf0e10cSrcweir SCROW nArrY = nRow-nRow1;
622cdf0e10cSrcweir if (bRowByName) nArrY = pDestRows[nArrY];
623cdf0e10cSrcweir if ( nArrY != SC_CONS_NOTFOUND && (
624cdf0e10cSrcweir bAnyCell ? pSrcDoc->HasData( nCol, nRow, nTab )
625cdf0e10cSrcweir : pSrcDoc->HasValueData( nCol, nRow, nTab ) ) )
626cdf0e10cSrcweir {
627cdf0e10cSrcweir if (bReference)
628cdf0e10cSrcweir {
629cdf0e10cSrcweir if (ppUsed[nArrX][nArrY])
630cdf0e10cSrcweir ppRefs[nArrX][nArrY].AddEntry( nCol, nRow, nTab );
631cdf0e10cSrcweir else
632cdf0e10cSrcweir {
633cdf0e10cSrcweir ppUsed[nArrX][nArrY] = sal_True;
634cdf0e10cSrcweir ppRefs[nArrX][nArrY].Init();
635cdf0e10cSrcweir ppRefs[nArrX][nArrY].AddEntry( nCol, nRow, nTab );
636cdf0e10cSrcweir }
637cdf0e10cSrcweir }
638cdf0e10cSrcweir else
639cdf0e10cSrcweir {
640cdf0e10cSrcweir double nVal;
641cdf0e10cSrcweir pSrcDoc->GetValue( nCol, nRow, nTab, nVal );
642cdf0e10cSrcweir if (ppUsed[nArrX][nArrY])
643cdf0e10cSrcweir lcl_UpdateArray( eFunction, ppCount[nArrX][nArrY],
644cdf0e10cSrcweir ppSum[nArrX][nArrY], ppSumSqr[nArrX][nArrY],
645cdf0e10cSrcweir nVal);
646cdf0e10cSrcweir else
647cdf0e10cSrcweir {
648cdf0e10cSrcweir ppUsed[nArrX][nArrY] = sal_True;
649cdf0e10cSrcweir lcl_InitArray( eFunction, ppCount[nArrX][nArrY],
650cdf0e10cSrcweir ppSum[nArrX][nArrY],
651cdf0e10cSrcweir ppSumSqr[nArrX][nArrY], nVal );
652cdf0e10cSrcweir }
653cdf0e10cSrcweir }
654cdf0e10cSrcweir }
655cdf0e10cSrcweir }
656cdf0e10cSrcweir }
657cdf0e10cSrcweir }
658cdf0e10cSrcweir
659cdf0e10cSrcweir delete[] pDestCols;
660cdf0e10cSrcweir delete[] pDestRows;
661cdf0e10cSrcweir }
662cdf0e10cSrcweir
663cdf0e10cSrcweir // vorher testen, wieviele Zeilen eingefuegt werden (fuer Undo)
664cdf0e10cSrcweir
GetInsertCount() const665cdf0e10cSrcweir SCROW ScConsData::GetInsertCount() const
666cdf0e10cSrcweir {
667cdf0e10cSrcweir SCROW nInsert = 0;
668cdf0e10cSrcweir SCSIZE nArrX;
669cdf0e10cSrcweir SCSIZE nArrY;
670cdf0e10cSrcweir if ( ppRefs && ppUsed )
671cdf0e10cSrcweir {
672cdf0e10cSrcweir for (nArrY=0; nArrY<nRowCount; nArrY++)
673cdf0e10cSrcweir {
674cdf0e10cSrcweir SCSIZE nNeeded = 0;
675cdf0e10cSrcweir for (nArrX=0; nArrX<nColCount; nArrX++)
676cdf0e10cSrcweir if (ppUsed[nArrX][nArrY])
677cdf0e10cSrcweir nNeeded = Max( nNeeded, ppRefs[nArrX][nArrY].GetCount() );
678cdf0e10cSrcweir
679cdf0e10cSrcweir nInsert += nNeeded;
680cdf0e10cSrcweir }
681cdf0e10cSrcweir }
682cdf0e10cSrcweir return nInsert;
683cdf0e10cSrcweir }
684cdf0e10cSrcweir
685cdf0e10cSrcweir // fertige Daten ins Dokument schreiben
686cdf0e10cSrcweir //! optimieren nach Spalten?
687cdf0e10cSrcweir
OutputToDocument(ScDocument * pDestDoc,SCCOL nCol,SCROW nRow,SCTAB nTab)688cdf0e10cSrcweir void ScConsData::OutputToDocument( ScDocument* pDestDoc, SCCOL nCol, SCROW nRow, SCTAB nTab )
689cdf0e10cSrcweir {
690cdf0e10cSrcweir OpCode eOpCode = eOpCodeTable[eFunction];
691cdf0e10cSrcweir
692cdf0e10cSrcweir SCSIZE nArrX;
693cdf0e10cSrcweir SCSIZE nArrY;
694cdf0e10cSrcweir
695cdf0e10cSrcweir // Ecke links oben
696cdf0e10cSrcweir
697cdf0e10cSrcweir if ( bColByName && bRowByName && aCornerText.Len() )
698cdf0e10cSrcweir pDestDoc->SetString( nCol, nRow, nTab, aCornerText );
699cdf0e10cSrcweir
700cdf0e10cSrcweir // Titel
701cdf0e10cSrcweir
702cdf0e10cSrcweir SCCOL nStartCol = nCol;
703cdf0e10cSrcweir SCROW nStartRow = nRow;
704cdf0e10cSrcweir if (bColByName) ++nStartRow;
705cdf0e10cSrcweir if (bRowByName) ++nStartCol;
706cdf0e10cSrcweir
707cdf0e10cSrcweir if (bColByName)
708cdf0e10cSrcweir for (SCSIZE i=0; i<nColCount; i++)
709cdf0e10cSrcweir pDestDoc->SetString( sal::static_int_cast<SCCOL>(nStartCol+i), nRow, nTab, *ppColHeaders[i] );
710cdf0e10cSrcweir if (bRowByName)
711cdf0e10cSrcweir for (SCSIZE j=0; j<nRowCount; j++)
712cdf0e10cSrcweir pDestDoc->SetString( nCol, sal::static_int_cast<SCROW>(nStartRow+j), nTab, *ppRowHeaders[j] );
713cdf0e10cSrcweir
714cdf0e10cSrcweir nCol = nStartCol;
715cdf0e10cSrcweir nRow = nStartRow;
716cdf0e10cSrcweir
717cdf0e10cSrcweir // Daten
718cdf0e10cSrcweir
719cdf0e10cSrcweir if ( ppCount && ppUsed ) // Werte direkt einfuegen
720cdf0e10cSrcweir {
721cdf0e10cSrcweir for (nArrX=0; nArrX<nColCount; nArrX++)
722cdf0e10cSrcweir for (nArrY=0; nArrY<nRowCount; nArrY++)
723cdf0e10cSrcweir if (ppUsed[nArrX][nArrY])
724cdf0e10cSrcweir {
725cdf0e10cSrcweir double fVal = lcl_CalcData( eFunction, ppCount[nArrX][nArrY],
726cdf0e10cSrcweir ppSum[nArrX][nArrY],
727cdf0e10cSrcweir ppSumSqr[nArrX][nArrY]);
728cdf0e10cSrcweir if (ppCount[nArrX][nArrY] < 0.0)
729cdf0e10cSrcweir pDestDoc->SetError( sal::static_int_cast<SCCOL>(nCol+nArrX),
730cdf0e10cSrcweir sal::static_int_cast<SCROW>(nRow+nArrY), nTab, errNoValue );
731cdf0e10cSrcweir else
732cdf0e10cSrcweir pDestDoc->SetValue( sal::static_int_cast<SCCOL>(nCol+nArrX),
733cdf0e10cSrcweir sal::static_int_cast<SCROW>(nRow+nArrY), nTab, fVal );
734cdf0e10cSrcweir }
735cdf0e10cSrcweir }
736cdf0e10cSrcweir
737cdf0e10cSrcweir if ( ppRefs && ppUsed ) // Referenzen einfuegen
738cdf0e10cSrcweir {
739cdf0e10cSrcweir //! unterscheiden, ob nach Kategorien aufgeteilt
740cdf0e10cSrcweir String aString;
741cdf0e10cSrcweir
742cdf0e10cSrcweir ScSingleRefData aSRef; // Daten fuer Referenz-Formelzellen
743cdf0e10cSrcweir aSRef.InitFlags();
744cdf0e10cSrcweir aSRef.SetFlag3D(sal_True);
745cdf0e10cSrcweir
746cdf0e10cSrcweir ScComplexRefData aCRef; // Daten fuer Summen-Zellen
747cdf0e10cSrcweir aCRef.InitFlags();
748cdf0e10cSrcweir aCRef.Ref1.SetColRel(sal_True); aCRef.Ref1.SetRowRel(sal_True); aCRef.Ref1.SetTabRel(sal_True);
749cdf0e10cSrcweir aCRef.Ref2.SetColRel(sal_True); aCRef.Ref2.SetRowRel(sal_True); aCRef.Ref2.SetTabRel(sal_True);
750cdf0e10cSrcweir
751cdf0e10cSrcweir for (nArrY=0; nArrY<nRowCount; nArrY++)
752cdf0e10cSrcweir {
753cdf0e10cSrcweir SCSIZE nNeeded = 0;
754cdf0e10cSrcweir for (nArrX=0; nArrX<nColCount; nArrX++)
755cdf0e10cSrcweir if (ppUsed[nArrX][nArrY])
756cdf0e10cSrcweir nNeeded = Max( nNeeded, ppRefs[nArrX][nArrY].GetCount() );
757cdf0e10cSrcweir
758cdf0e10cSrcweir if (nNeeded)
759cdf0e10cSrcweir {
760cdf0e10cSrcweir pDestDoc->InsertRow( 0,nTab, MAXCOL,nTab, nRow+nArrY, nNeeded );
761cdf0e10cSrcweir
762cdf0e10cSrcweir for (nArrX=0; nArrX<nColCount; nArrX++)
763cdf0e10cSrcweir if (ppUsed[nArrX][nArrY])
764cdf0e10cSrcweir {
765cdf0e10cSrcweir ScReferenceList& rList = ppRefs[nArrX][nArrY];
766cdf0e10cSrcweir SCSIZE nCount = rList.GetCount();
767cdf0e10cSrcweir if (nCount)
768cdf0e10cSrcweir {
769cdf0e10cSrcweir for (SCSIZE nPos=0; nPos<nCount; nPos++)
770cdf0e10cSrcweir {
771cdf0e10cSrcweir ScReferenceEntry aRef = rList.GetEntry(nPos);
772cdf0e10cSrcweir if (aRef.nTab != SC_CONS_NOTFOUND)
773cdf0e10cSrcweir {
774cdf0e10cSrcweir // Referenz einfuegen (absolut, 3d)
775cdf0e10cSrcweir
776cdf0e10cSrcweir aSRef.nCol = aRef.nCol;
777cdf0e10cSrcweir aSRef.nRow = aRef.nRow;
778cdf0e10cSrcweir aSRef.nTab = aRef.nTab;
779cdf0e10cSrcweir
780cdf0e10cSrcweir ScTokenArray aRefArr;
781cdf0e10cSrcweir aRefArr.AddSingleReference(aSRef);
782cdf0e10cSrcweir aRefArr.AddOpCode(ocStop);
783cdf0e10cSrcweir ScAddress aDest( sal::static_int_cast<SCCOL>(nCol+nArrX),
784cdf0e10cSrcweir sal::static_int_cast<SCROW>(nRow+nArrY+nPos), nTab );
785cdf0e10cSrcweir ScBaseCell* pCell = new ScFormulaCell( pDestDoc, aDest, &aRefArr );
786cdf0e10cSrcweir pDestDoc->PutCell( aDest.Col(), aDest.Row(), aDest.Tab(), pCell );
787cdf0e10cSrcweir }
788cdf0e10cSrcweir }
789cdf0e10cSrcweir
790cdf0e10cSrcweir // Summe einfuegen (relativ, nicht 3d)
791cdf0e10cSrcweir
792cdf0e10cSrcweir ScAddress aDest( sal::static_int_cast<SCCOL>(nCol+nArrX),
793cdf0e10cSrcweir sal::static_int_cast<SCROW>(nRow+nArrY+nNeeded), nTab );
794cdf0e10cSrcweir
795cdf0e10cSrcweir aCRef.Ref1.nTab = aCRef.Ref2.nTab = nTab;
796cdf0e10cSrcweir aCRef.Ref1.nCol = aCRef.Ref2.nCol = sal::static_int_cast<SCsCOL>( nCol+nArrX );
797cdf0e10cSrcweir aCRef.Ref1.nRow = nRow+nArrY;
798cdf0e10cSrcweir aCRef.Ref2.nRow = nRow+nArrY+nNeeded-1;
799cdf0e10cSrcweir aCRef.CalcRelFromAbs( aDest );
800cdf0e10cSrcweir
801cdf0e10cSrcweir ScTokenArray aArr;
802cdf0e10cSrcweir aArr.AddOpCode(eOpCode); // ausgewaehlte Funktion
803cdf0e10cSrcweir aArr.AddOpCode(ocOpen);
804cdf0e10cSrcweir aArr.AddDoubleReference(aCRef);
805cdf0e10cSrcweir aArr.AddOpCode(ocClose);
806cdf0e10cSrcweir aArr.AddOpCode(ocStop);
807cdf0e10cSrcweir ScBaseCell* pCell = new ScFormulaCell( pDestDoc, aDest, &aArr );
808cdf0e10cSrcweir pDestDoc->PutCell( aDest.Col(), aDest.Row(), aDest.Tab(), pCell );
809cdf0e10cSrcweir }
810cdf0e10cSrcweir }
811cdf0e10cSrcweir
812cdf0e10cSrcweir // Gliederung einfuegen
813cdf0e10cSrcweir
814cdf0e10cSrcweir ScOutlineArray* pOutArr = pDestDoc->GetOutlineTable( nTab, sal_True )->GetRowArray();
815cdf0e10cSrcweir SCROW nOutStart = nRow+nArrY;
816cdf0e10cSrcweir SCROW nOutEnd = nRow+nArrY+nNeeded-1;
817cdf0e10cSrcweir sal_Bool bSize = sal_False;
818cdf0e10cSrcweir pOutArr->Insert( nOutStart, nOutEnd, bSize );
819cdf0e10cSrcweir for (SCROW nOutRow=nOutStart; nOutRow<=nOutEnd; nOutRow++)
820cdf0e10cSrcweir pDestDoc->ShowRow( nOutRow, nTab, sal_False );
821cdf0e10cSrcweir pDestDoc->UpdateOutlineRow( nOutStart, nOutEnd, nTab, sal_False );
822cdf0e10cSrcweir
823cdf0e10cSrcweir // Zwischentitel
824cdf0e10cSrcweir
825cdf0e10cSrcweir if (ppTitlePos && ppTitles && ppRowHeaders)
826cdf0e10cSrcweir {
827cdf0e10cSrcweir String aDelim( RTL_CONSTASCII_USTRINGPARAM(" / ") );
828cdf0e10cSrcweir for (SCSIZE nPos=0; nPos<nDataCount; nPos++)
829cdf0e10cSrcweir {
830cdf0e10cSrcweir SCSIZE nTPos = ppTitlePos[nArrY][nPos];
831cdf0e10cSrcweir sal_Bool bDo = sal_True;
832cdf0e10cSrcweir if (nPos+1<nDataCount)
833cdf0e10cSrcweir if (ppTitlePos[nArrY][nPos+1] == nTPos)
834cdf0e10cSrcweir bDo = sal_False; // leer
835cdf0e10cSrcweir if ( bDo && nTPos < nNeeded )
836cdf0e10cSrcweir {
837cdf0e10cSrcweir aString = *ppRowHeaders[nArrY];
838cdf0e10cSrcweir aString += aDelim;
839cdf0e10cSrcweir aString += *ppTitles[nPos];
840cdf0e10cSrcweir pDestDoc->SetString( nCol-1, nRow+nArrY+nTPos, nTab, aString );
841cdf0e10cSrcweir }
842cdf0e10cSrcweir }
843cdf0e10cSrcweir }
844cdf0e10cSrcweir
845cdf0e10cSrcweir nRow += nNeeded;
846cdf0e10cSrcweir }
847cdf0e10cSrcweir }
848cdf0e10cSrcweir }
849cdf0e10cSrcweir }
850cdf0e10cSrcweir
851cdf0e10cSrcweir
852cdf0e10cSrcweir
853cdf0e10cSrcweir
854cdf0e10cSrcweir
855