xref: /aoo41x/main/sc/source/core/tool/consoli.cxx (revision b3f79822)
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