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