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