PageRenderTime 58ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 1ms

/libreoffice-3.6.0.2/binfilter/bf_sc/source/core/data/sc_pivot.cxx

#
C++ | 1213 lines | 985 code | 68 blank | 160 comment | 238 complexity | 7e95a92e6a1d5dde847b35e8a329e7af MD5 | raw file
Possible License(s): MPL-2.0-no-copyleft-exception, LGPL-2.1, AGPL-1.0, BSD-3-Clause-No-Nuclear-License-2014, GPL-3.0, LGPL-3.0
  1. /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
  2. /*************************************************************************
  3. *
  4. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  5. *
  6. * Copyright 2000, 2010 Oracle and/or its affiliates.
  7. *
  8. * OpenOffice.org - a multi-platform office productivity suite
  9. *
  10. * This file is part of OpenOffice.org.
  11. *
  12. * OpenOffice.org is free software: you can redistribute it and/or modify
  13. * it under the terms of the GNU Lesser General Public License version 3
  14. * only, as published by the Free Software Foundation.
  15. *
  16. * OpenOffice.org is distributed in the hope that it will be useful,
  17. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  19. * GNU Lesser General Public License version 3 for more details
  20. * (a copy is included in the LICENSE file that accompanied this code).
  21. *
  22. * You should have received a copy of the GNU Lesser General Public License
  23. * version 3 along with OpenOffice.org. If not, see
  24. * <http://www.openoffice.org/license.html>
  25. * for a copy of the LGPLv3 License.
  26. *
  27. ************************************************************************/
  28. #ifdef _MSC_VER
  29. #pragma hdrstop
  30. #endif
  31. // -----------------------------------------------------------------------
  32. #ifdef _MSC_VER
  33. #pragma optimize("",off)
  34. #endif
  35. #ifdef _MSC_VER
  36. #pragma optimize("q",off) // p-code off
  37. #endif
  38. // INCLUDE ---------------------------------------------------------------
  39. #include <bf_svtools/bf_solar.h>
  40. #include <string.h>
  41. #include <math.h>
  42. #include "globstr.hrc"
  43. #include "subtotal.hxx"
  44. #include "docpool.hxx"
  45. #include "document.hxx"
  46. #include "userlist.hxx"
  47. #include "pivot.hxx"
  48. #include "cell.hxx"
  49. #include "rechead.hxx"
  50. namespace binfilter {
  51. // STATIC DATA -----------------------------------------------------------
  52. //! bei Gelegenheit...
  53. static short nStaticStrRefCount = 0;
  54. static String* pLabel[PIVOT_MAXFUNC+1]; // incl. "auto"
  55. static String* pLabelTotal;
  56. static String* pLabelData;
  57. static USHORT nDataMult = 1;
  58. #define nFirstLine 2
  59. static const USHORT nFuncMaskArr[PIVOT_MAXFUNC+1] =
  60. { PIVOT_FUNC_SUM,
  61. PIVOT_FUNC_COUNT,
  62. PIVOT_FUNC_AVERAGE,
  63. PIVOT_FUNC_MAX,
  64. PIVOT_FUNC_MIN,
  65. PIVOT_FUNC_PRODUCT,
  66. PIVOT_FUNC_COUNT_NUM,
  67. PIVOT_FUNC_STD_DEV,
  68. PIVOT_FUNC_STD_DEVP,
  69. PIVOT_FUNC_STD_VAR,
  70. PIVOT_FUNC_STD_VARP,
  71. PIVOT_FUNC_AUTO }; // automatisch
  72. // -----------------------------------------------------------------------
  73. // 1 Filter-Knopf
  74. // 2 Feldnamen links
  75. // 3 "Daten" links
  76. // 4 Feldnamen oben
  77. // 5 "Daten" oben
  78. // 6 einzelne "Gesamt" oben rechts
  79. // 7 "Gesamt" oben rechts
  80. // 8 einzelne "Gesamt" unten links
  81. // 9 "Gesamt" unten links
  82. // 10 innere Kategorie links
  83. // 11 Teilergebnis Label einzeln links
  84. // 12 Teilergebnis Label gesamt links
  85. // 13 letzte Kategorie links
  86. // 14 innere Kategorie oben
  87. // 15 Teilergebnis Label einzeln oben
  88. // 16 Teilergebnis Label gesamt oben
  89. // 17 letzte Kategorie oben
  90. // 18 Werte innen
  91. // 19 Werte in Teilergebnisspalte
  92. // 20 Werte in Gesamt-Spalte
  93. // 21 Werte in einzelnen Gesamt-Spalten
  94. // 22 Werte in Ergebnis-Zeile Teilergebnis oder Gesamt
  95. // 23 Kreuzung von Spalte/Zeile (Teilergebnis-Spalte)
  96. // 24 Kreuzung von Spalte/Zeile (Gesamt-Spalte)
  97. // 25 wie 24 bei einzelnen "Gesamt"
  98. /*N*/ ScPivot::ScPivot(ScDocument* pDocument) :
  99. /*N*/ pDoc (pDocument),
  100. /*N*/ aQuery (),
  101. /*N*/ bHasHeader (FALSE),
  102. /*N*/ bIgnoreEmpty (FALSE),
  103. /*N*/ bDetectCat (FALSE),
  104. /*N*/ bMakeTotalCol (TRUE),
  105. /*N*/ bMakeTotalRow (TRUE),
  106. /*N*/ nColNameCount (0),
  107. /*N*/ pColNames (NULL),
  108. /*N*/ nSrcCol1 (0),
  109. /*N*/ nSrcRow1 (0),
  110. /*N*/ nSrcCol2 (0),
  111. /*N*/ nSrcRow2 (0),
  112. /*N*/ nSrcTab (0),
  113. /*N*/ nDestCol1 (0),
  114. /*N*/ nDestRow1 (0),
  115. /*N*/ nDestCol2 (0),
  116. /*N*/ nDestRow2 (0),
  117. /*N*/ nDestTab (0),
  118. /*N*/ nDataStartCol (0),
  119. /*N*/ nDataStartRow (0),
  120. /*N*/ nColCount (0),
  121. /*N*/ nRowCount (0),
  122. /*N*/ nDataCount (0),
  123. /*N*/ bValidArea (FALSE),
  124. /*N*/ bDataAtCol (FALSE)
  125. /*N*/ {
  126. /*N*/ short i;
  127. /*N*/ for (i=0; i<PIVOT_MAXFIELD; i++)
  128. /*N*/ {
  129. /*N*/ pColList[i] = new PivotStrCollection();
  130. /*N*/ pRowList[i] = new PivotStrCollection();
  131. /*N*/ }
  132. /*N*/ pDataList = pColList[0];
  133. /*N*/ ppDataArr = NULL;
  134. /*N*/ nDataColCount = 0;
  135. /*N*/ nDataRowCount = 0;
  136. /*N*/ nRecCount = 0;
  137. /*N*/ pColRef = NULL;
  138. /*N*/
  139. /*N*/ // Initialisierung der statischen Strings, wenn noetig
  140. /*N*/ nStaticStrRefCount += 1;
  141. /*N*/ if ( nStaticStrRefCount < 2 )
  142. /*N*/ {
  143. /*N*/ pLabelTotal = new String( ScGlobal::GetRscString(STR_PIVOT_TOTAL) );
  144. /*N*/ pLabelData = new String( ScGlobal::GetRscString(STR_PIVOT_DATA) );
  145. /*N*/
  146. /*N*/ for ( i=0; i<=PIVOT_MAXFUNC; i++ ) // incl. "auto"
  147. /*N*/ pLabel[i] = new String; // kein Leerzeichen
  148. /*N*/
  149. /*N*/ *pLabel[ 0] = ScGlobal::GetRscString(STR_FUN_TEXT_SUM);
  150. /*N*/ *pLabel[ 1] = ScGlobal::GetRscString(STR_FUN_TEXT_COUNT);
  151. /*N*/ *pLabel[ 2] = ScGlobal::GetRscString(STR_FUN_TEXT_AVG);
  152. /*N*/ *pLabel[ 3] = ScGlobal::GetRscString(STR_FUN_TEXT_MAX);
  153. /*N*/ *pLabel[ 4] = ScGlobal::GetRscString(STR_FUN_TEXT_MIN);
  154. /*N*/ *pLabel[ 5] = ScGlobal::GetRscString(STR_FUN_TEXT_PRODUCT);
  155. /*N*/ *pLabel[ 6] = ScGlobal::GetRscString(STR_FUN_TEXT_COUNT); // Count2
  156. /*N*/ *pLabel[ 7] = ScGlobal::GetRscString(STR_FUN_TEXT_STDDEV);
  157. /*N*/ *pLabel[ 8] = ScGlobal::GetRscString(STR_FUN_TEXT_STDDEV); // Stddev2
  158. /*N*/ *pLabel[ 9] = ScGlobal::GetRscString(STR_FUN_TEXT_VAR);
  159. /*N*/ *pLabel[10] = ScGlobal::GetRscString(STR_FUN_TEXT_VAR); // Var2
  160. /*N*/ *pLabel[11] = ScGlobal::GetRscString(STR_TABLE_ERGEBNIS);
  161. /*N*/ }
  162. /*N*/ }
  163. /*N*/
  164. /*N*/ ScPivot::ScPivot(const ScPivot& rPivot): DataObject(rPivot),
  165. /*N*/ pDoc (rPivot.pDoc),
  166. /*N*/ aQuery (rPivot.aQuery),
  167. /*N*/ bHasHeader (rPivot.bHasHeader),
  168. /*N*/ bIgnoreEmpty (rPivot.bIgnoreEmpty),
  169. /*N*/ bDetectCat (rPivot.bDetectCat),
  170. /*N*/ bMakeTotalCol (rPivot.bMakeTotalCol),
  171. /*N*/ bMakeTotalRow (rPivot.bMakeTotalRow),
  172. /*N*/ aName (rPivot.aName),
  173. /*N*/ aTag (rPivot.aTag),
  174. /*N*/ nColNameCount (0),
  175. /*N*/ pColNames (NULL),
  176. /*N*/ nSrcCol1 (rPivot.nSrcCol1),
  177. /*N*/ nSrcRow1 (rPivot.nSrcRow1),
  178. /*N*/ nSrcCol2 (rPivot.nSrcCol2),
  179. /*N*/ nSrcRow2 (rPivot.nSrcRow2),
  180. /*N*/ nSrcTab (rPivot.nSrcTab),
  181. /*N*/ nDestCol1 (rPivot.nDestCol1),
  182. /*N*/ nDestRow1 (rPivot.nDestRow1),
  183. /*N*/ nDestCol2 (rPivot.nDestCol2),
  184. /*N*/ nDestRow2 (rPivot.nDestRow2),
  185. /*N*/ nDestTab (rPivot.nDestTab),
  186. /*N*/ nDataStartCol (0),
  187. /*N*/ nDataStartRow (0),
  188. /*N*/ nColCount (0),
  189. /*N*/ nRowCount (0),
  190. /*N*/ nDataCount (0),
  191. /*N*/ bValidArea (FALSE),
  192. /*N*/ bDataAtCol (FALSE)
  193. /*N*/ {
  194. /*N*/ if (rPivot.nColNameCount && rPivot.pColNames)
  195. /*N*/ {
  196. /*N*/ nColNameCount = rPivot.nColNameCount;
  197. /*N*/ pColNames = new String[nColNameCount];
  198. /*N*/ for (USHORT nCol=0; nCol<nColNameCount; nCol++)
  199. /*N*/ pColNames[nCol] = rPivot.pColNames[nCol];
  200. /*N*/ }
  201. /*N*/
  202. /*N*/ short i;
  203. /*N*/ for (i=0; i<PIVOT_MAXFIELD; i++)
  204. /*N*/ {
  205. /*N*/ pColList[i] = new PivotStrCollection();
  206. /*N*/ pRowList[i] = new PivotStrCollection();
  207. /*N*/ }
  208. /*N*/ pDataList = pColList[0];
  209. /*N*/ ppDataArr = NULL;
  210. /*N*/ nRecCount = 0;
  211. /*N*/ pColRef = NULL;
  212. /*N*/
  213. /*N*/ SetColFields( rPivot.aColArr, rPivot.nColCount );
  214. /*N*/ SetRowFields( rPivot.aRowArr, rPivot.nRowCount );
  215. /*N*/ SetDataFields( rPivot.aDataArr, rPivot.nDataCount );
  216. /*N*/
  217. /*N*/ nStaticStrRefCount += 1;
  218. /*N*/ }
  219. /*N*/ ScPivot::~ScPivot()
  220. /*N*/ {
  221. /*N*/ short i;
  222. /*N*/ for (i=0; i<PIVOT_MAXFIELD; i++)
  223. /*N*/ {
  224. /*N*/ delete pColList[i];
  225. /*N*/ delete pRowList[i];
  226. /*N*/ }
  227. /*N*/ if (ppDataArr)
  228. /*N*/ {
  229. /*N*/ for (i=0; i<nDataRowCount; i++)
  230. /*N*/ delete[] ppDataArr[i];
  231. /*N*/ delete[] ppDataArr;
  232. /*N*/ ppDataArr = NULL;
  233. /*N*/ }
  234. /*N*/ delete[] pColRef;
  235. /*N*/
  236. /*N*/ delete[] pColNames;
  237. /*N*/
  238. /*N*/ // statische Strings ggF. wieder abraeumen
  239. /*N*/ nStaticStrRefCount -= 1;
  240. /*N*/ if ( nStaticStrRefCount == 0 )
  241. /*N*/ {
  242. /*N*/ delete pLabelTotal;
  243. /*N*/ delete pLabelData;
  244. /*N*/
  245. /*N*/ for ( i=0; i<=PIVOT_MAXFUNC; i++ ) // incl. "auto"
  246. /*N*/ delete pLabel[i];
  247. /*N*/ }
  248. /*N*/ }
  249. /*N*/ void lcl_LoadFieldArr30( SvStream& rStream, PivotField* pField, USHORT nCount )
  250. /*N*/ {
  251. /*N*/ USHORT i;
  252. /*N*/
  253. /*N*/ for (i=0; i<nCount; i++)
  254. /*N*/ {
  255. /*N*/ rStream >> pField[i].nCol
  256. /*N*/ >> pField[i].nFuncMask
  257. /*N*/ >> pField[i].nFuncCount;
  258. /*N*/ }
  259. /*N*/ }
  260. /*N*/ void lcl_LoadFieldArr( SvStream& rStream, PivotField* pField, USHORT nCount )
  261. /*N*/ {
  262. /*N*/ USHORT i;
  263. /*N*/
  264. /*N*/ for (i=0; i<nCount; i++)
  265. /*N*/ {
  266. /*N*/ BYTE cData;
  267. /*N*/ rStream >> cData;
  268. /*N*/ if( cData & 0x0F )
  269. /*N*/ rStream.SeekRel( cData & 0x0F );
  270. /*N*/ rStream >> pField[i].nCol
  271. /*N*/ >> pField[i].nFuncMask
  272. /*N*/ >> pField[i].nFuncCount;
  273. /*N*/ }
  274. /*N*/ }
  275. // nach Load muessen Daten neu berechnet werden !
  276. /*N*/ BOOL ScPivot::Load( SvStream& rStream, ScMultipleReadHeader& rHdr )
  277. /*N*/ {
  278. /*N*/ rHdr.StartEntry();
  279. /*N*/
  280. /*N*/ rStream >> bHasHeader
  281. /*N*/
  282. /*N*/ >> nSrcCol1
  283. /*N*/ >> nSrcRow1
  284. /*N*/ >> nSrcCol2
  285. /*N*/ >> nSrcRow2
  286. /*N*/ >> nSrcTab
  287. /*N*/
  288. /*N*/ >> nDestCol1
  289. /*N*/ >> nDestRow1
  290. /*N*/ >> nDestCol2
  291. /*N*/ >> nDestRow2
  292. /*N*/ >> nDestTab;
  293. /*N*/
  294. /*N*/ // Arrays immer ueber Set...Fields initalisieren!
  295. /*N*/
  296. /*N*/ short nCount;
  297. /*N*/ PivotFieldArr aFieldArr;
  298. /*N*/
  299. /*N*/ if( pDoc->GetSrcVersion() >= SC_DATABYTES2 )
  300. /*N*/ {
  301. /*N*/ rStream >> nCount;
  302. /*N*/ lcl_LoadFieldArr( rStream, aFieldArr, nCount );
  303. /*N*/ SetColFields(aFieldArr, nCount);
  304. /*N*/
  305. /*N*/ rStream >> nCount;
  306. /*N*/ lcl_LoadFieldArr( rStream, aFieldArr, nCount );
  307. /*N*/ SetRowFields(aFieldArr, nCount);
  308. /*N*/
  309. /*N*/ rStream >> nCount;
  310. /*N*/ lcl_LoadFieldArr( rStream, aFieldArr, nCount );
  311. /*N*/ SetDataFields(aFieldArr, nCount);
  312. /*N*/ }
  313. /*N*/ else
  314. /*N*/ {
  315. /*N*/ rStream >> nCount;
  316. /*N*/ lcl_LoadFieldArr30( rStream, aFieldArr, nCount );
  317. /*N*/ SetColFields(aFieldArr, nCount);
  318. /*N*/
  319. /*N*/ rStream >> nCount;
  320. /*N*/ lcl_LoadFieldArr30( rStream, aFieldArr, nCount );
  321. /*N*/ SetRowFields(aFieldArr, nCount);
  322. /*N*/
  323. /*N*/ rStream >> nCount;
  324. /*N*/ lcl_LoadFieldArr30( rStream, aFieldArr, nCount );
  325. /*N*/ SetDataFields(aFieldArr, nCount);
  326. /*N*/ }
  327. /*N*/
  328. /*N*/ aQuery.Load( rStream );
  329. /*N*/
  330. /*N*/ rStream >> bIgnoreEmpty;
  331. /*N*/ rStream >> bDetectCat;
  332. /*N*/
  333. /*N*/ if (rHdr.BytesLeft())
  334. /*N*/ {
  335. /*N*/ rStream >> bMakeTotalCol; // ab 355i
  336. /*N*/ rStream >> bMakeTotalRow;
  337. /*N*/ }
  338. /*N*/
  339. /*N*/ if (rHdr.BytesLeft()) // ab 500a
  340. /*N*/ {
  341. /*N*/ aName = rStream.ReadUniOrByteString( rStream.GetStreamCharSet() );
  342. /*N*/ aTag = rStream.ReadUniOrByteString( rStream.GetStreamCharSet() );
  343. /*N*/
  344. /*N*/ DBG_ASSERT(!pColNames, "Spaltennamen schon gesetzt?");
  345. /*N*/ rStream >> nColNameCount;
  346. /*N*/ if (nColNameCount)
  347. /*N*/ {
  348. /*N*/ pColNames = new String[nColNameCount];
  349. /*N*/ for (USHORT nCol=0; nCol<nColNameCount; nCol++)
  350. /*N*/ pColNames[nCol] = rStream.ReadUniOrByteString( rStream.GetStreamCharSet() );
  351. /*N*/ }
  352. /*N*/ }
  353. /*N*/ // sonst wird hinterher aus ScPivotCollection::Load ein Name vergeben
  354. /*N*/
  355. /*N*/ rHdr.EndEntry();
  356. /*N*/ return TRUE;
  357. /*N*/ }
  358. /*N*/ void ScPivot::SetQuery(const ScQueryParam& rQuery)
  359. /*N*/ {
  360. /*N*/ aQuery = rQuery;
  361. /*N*/
  362. /*N*/ bValidArea = FALSE;
  363. /*N*/ }
  364. /*N*/ void ScPivot::GetQuery(ScQueryParam& rQuery) const
  365. /*N*/ {
  366. /*N*/ rQuery = aQuery;
  367. /*N*/ }
  368. /*N*/ void ScPivot::SetHeader(BOOL bHeader)
  369. /*N*/ {
  370. /*N*/ bHasHeader = bHeader;
  371. /*N*/ bValidArea = FALSE;
  372. /*N*/ }
  373. /*N*/ void ScPivot::SetIgnoreEmpty(BOOL bIgnore)
  374. /*N*/ {
  375. /*N*/ bIgnoreEmpty = bIgnore;
  376. /*N*/ bValidArea = FALSE;
  377. /*N*/ }
  378. /*N*/ BOOL ScPivot::GetIgnoreEmpty() const
  379. /*N*/ {
  380. /*N*/ return bIgnoreEmpty;
  381. /*N*/ }
  382. /*N*/ void ScPivot::SetDetectCat(BOOL bDetect)
  383. /*N*/ {
  384. /*N*/ bDetectCat = bDetect;
  385. /*N*/ bValidArea = FALSE;
  386. /*N*/ }
  387. /*N*/ BOOL ScPivot::GetDetectCat() const
  388. /*N*/ {
  389. /*N*/ return bDetectCat;
  390. /*N*/ }
  391. /*N*/ void ScPivot::SetMakeTotalCol(BOOL bSet)
  392. /*N*/ {
  393. /*N*/ bMakeTotalCol = bSet;
  394. /*N*/ bValidArea = FALSE;
  395. /*N*/ }
  396. /*N*/ BOOL ScPivot::GetMakeTotalCol() const
  397. /*N*/ {
  398. /*N*/ return bMakeTotalCol;
  399. /*N*/ }
  400. /*N*/ void ScPivot::SetMakeTotalRow(BOOL bSet)
  401. /*N*/ {
  402. /*N*/ bMakeTotalRow = bSet;
  403. /*N*/ bValidArea = FALSE;
  404. /*N*/ }
  405. /*N*/ BOOL ScPivot::GetMakeTotalRow() const
  406. /*N*/ {
  407. /*N*/ return bMakeTotalRow;
  408. /*N*/ }
  409. /*N*/ void ScPivot::SetName(const String& rNew)
  410. /*N*/ {
  411. /*N*/ aName = rNew;
  412. /*N*/ }
  413. /*N*/ const String& ScPivot::GetName() const
  414. /*N*/ {
  415. /*N*/ return aName;
  416. /*N*/ }
  417. /*N*/ void ScPivot::SetTag(const String& rNew)
  418. /*N*/ {
  419. /*N*/ aTag = rNew;
  420. /*N*/ }
  421. /*N*/ const String& ScPivot::GetTag() const
  422. /*N*/ {
  423. /*N*/ return aTag;
  424. /*N*/ }
  425. /*N*/ void ScPivot::SetSrcArea(USHORT nCol1, USHORT nRow1, USHORT nCol2, USHORT nRow2, USHORT nTab)
  426. /*N*/ {
  427. /*N*/ nSrcCol1 = Min(nCol1, (USHORT)MAXCOL);
  428. /*N*/ nSrcRow1 = Min(nRow1, (USHORT)MAXROW);
  429. /*N*/ nSrcCol2 = Min(nCol2, (USHORT)MAXCOL);
  430. /*N*/ nSrcRow2 = Min(nRow2, (USHORT)MAXROW);
  431. /*N*/ nSrcTab = nTab;
  432. /*N*/ bValidArea = FALSE;
  433. /*N*/ }
  434. /*N*/ void ScPivot::GetSrcArea(USHORT& rCol1, USHORT& rRow1, USHORT& rCol2, USHORT& rRow2, USHORT& rTab) const
  435. /*N*/ {
  436. /*N*/ rCol1 = nSrcCol1;
  437. /*N*/ rRow1 = nSrcRow1;
  438. /*N*/ rCol2 = nSrcCol2;
  439. /*N*/ rRow2 = nSrcRow2;
  440. /*N*/ rTab = nSrcTab;
  441. /*N*/ }
  442. /*N*/ ScRange ScPivot::GetSrcArea() const
  443. /*N*/ {
  444. /*N*/ return ScRange( nSrcCol1,nSrcRow1,nSrcTab, nSrcCol2,nSrcRow2,nSrcTab );
  445. /*N*/ }
  446. /*N*/ void ScPivot::SetDestPos(USHORT nCol, USHORT nRow, USHORT nTab)
  447. /*N*/ {
  448. /*N*/ nDestCol1 = nCol;
  449. /*N*/ nDestRow1 = nRow;
  450. /*N*/ nDestTab = nTab;
  451. /*N*/ bValidArea = FALSE;
  452. /*N*/ }
  453. /*N*/ void ScPivot::GetDestArea(USHORT& rCol1, USHORT& rRow1, USHORT& rCol2, USHORT& rRow2, USHORT& rTab) const
  454. /*N*/ {
  455. /*N*/ rCol1 = nDestCol1;
  456. /*N*/ rRow1 = nDestRow1;
  457. /*N*/ rTab = nDestTab;
  458. /*N*/ if (bValidArea)
  459. /*N*/ {
  460. /*N*/ rCol2 = nDestCol2;
  461. /*N*/ rRow2 = nDestRow2;
  462. /*N*/ }
  463. /*N*/ else
  464. /*N*/ {
  465. /*N*/ rCol2 = nDestCol1;
  466. /*N*/ rRow2 = nDestRow1;
  467. /*N*/ }
  468. /*N*/ }
  469. /*N*/ ScRange ScPivot::GetDestArea() const
  470. /*N*/ {
  471. /*N*/ ScAddress aStart( nDestCol1, nDestRow1, nDestTab );
  472. /*N*/ ScAddress aEnd = aStart;
  473. /*N*/ if ( bValidArea )
  474. /*N*/ aEnd = ScAddress( nDestCol2, nDestRow2, nDestTab );
  475. /*N*/ return ScRange( aStart, aEnd );
  476. /*N*/ }
  477. /*N*/ void ScPivot::MoveSrcArea( USHORT nNewCol, USHORT nNewRow, USHORT nNewTab )
  478. /*N*/ {
  479. /*N*/ if ( nNewCol != nSrcCol1 || nNewRow != nSrcRow1 || nNewTab != nSrcTab )
  480. /*N*/ {
  481. /*N*/ USHORT i;
  482. /*N*/ short nDiffX = nNewCol - (short) nSrcCol1;
  483. /*N*/ short nDiffY = nNewRow - (short) nSrcRow1;
  484. /*N*/
  485. /*N*/ nSrcTab = nNewTab;
  486. /*N*/ nSrcCol1 += nDiffX;
  487. /*N*/ nSrcCol2 += nDiffX;
  488. /*N*/ nSrcRow1 += nDiffY;
  489. /*N*/ nSrcRow2 += nDiffY;
  490. /*N*/
  491. /*N*/ aQuery.nCol1 += nDiffX;
  492. /*N*/ aQuery.nCol2 += nDiffX;
  493. /*N*/ aQuery.nRow1 += nDiffY;
  494. /*N*/ aQuery.nRow2 += nDiffY;
  495. /*N*/
  496. /*N*/ USHORT nEC = aQuery.GetEntryCount();
  497. /*N*/ for (i=0; i<nEC; i++)
  498. /*N*/ if (aQuery.GetEntry(i).bDoQuery)
  499. /*N*/ aQuery.GetEntry(i).nField += nDiffX;
  500. /*N*/
  501. /*N*/ if (bValidArea)
  502. /*N*/ {
  503. /*N*/ short nC;
  504. /*N*/ for (nC=0; nC<nColCount; nC++)
  505. /*N*/ if (aColArr[nC].nCol != PIVOT_DATA_FIELD)
  506. /*N*/ aColArr[nC].nCol += nDiffX;
  507. /*N*/ for (nC=0; nC<nRowCount; nC++)
  508. /*N*/ if (aRowArr[nC].nCol != PIVOT_DATA_FIELD)
  509. /*N*/ aRowArr[nC].nCol += nDiffX;
  510. /*N*/ for (nC=0; nC<nDataCount; nC++)
  511. /*N*/ if (aDataArr[nC].nCol != PIVOT_DATA_FIELD)
  512. /*N*/ aDataArr[nC].nCol += nDiffX;
  513. /*N*/ }
  514. /*N*/ }
  515. /*N*/ }
  516. /*N*/ void ScPivot::MoveDestArea( USHORT nNewCol, USHORT nNewRow, USHORT nNewTab )
  517. /*N*/ {
  518. /*N*/ if ( nNewCol != nDestCol1 || nNewRow != nDestRow1 || nNewTab != nDestTab )
  519. /*N*/ {
  520. /*N*/ short nDiffX = nNewCol - (short) nDestCol1;
  521. /*N*/ short nDiffY = nNewRow - (short) nDestRow1;
  522. /*N*/
  523. /*N*/ nDestTab = nNewTab;
  524. /*N*/ nDestCol1 += nDiffX;
  525. /*N*/ nDestRow1 += nDiffY;
  526. /*N*/
  527. /*N*/ if (bValidArea)
  528. /*N*/ {
  529. /*N*/ nDestCol2 += nDiffX;
  530. /*N*/ nDestRow2 += nDiffY;
  531. /*N*/
  532. /*N*/ nDataStartCol += nDiffX;
  533. /*N*/ nDataStartRow += nDiffY;
  534. /*N*/ }
  535. /*N*/ }
  536. /*N*/ }
  537. /*N*/ void ScPivot::SetColFields(const PivotField* pFieldArr, short nCount)
  538. /*N*/ {
  539. /*N*/ nColCount = Max((short)0, Min(nCount, (short)PIVOT_MAXFIELD));
  540. /*N*/ for (short i = 0; i < nColCount; i++)
  541. /*N*/ {
  542. /*N*/ aColArr[i] = pFieldArr[i];
  543. /*N*/ aColArr[i].nFuncCount = 0;
  544. /*N*/ if (aColArr[i].nCol == PIVOT_DATA_FIELD)
  545. /*N*/ {
  546. /*N*/ aColArr[i].nFuncMask = PIVOT_FUNC_NONE;
  547. /*N*/ pDataList = pColList[i];
  548. /*N*/ bDataAtCol = TRUE;
  549. /*N*/ }
  550. /*N*/ else
  551. /*N*/ {
  552. /*N*/ for (short j=0; j<=PIVOT_MAXFUNC; j++) // incl. "auto"
  553. /*N*/ if (aColArr[i].nFuncMask & nFuncMaskArr[j])
  554. /*N*/ aColArr[i].nFuncCount++;
  555. /*N*/ }
  556. /*N*/ }
  557. /*N*/ bValidArea = FALSE;
  558. /*N*/ }
  559. /*N*/ void ScPivot::GetColFields(PivotField* pFieldArr, short& rCount) const
  560. /*N*/ {
  561. /*N*/ for (short i=0; i<nColCount; i++)
  562. /*N*/ pFieldArr[i] = aColArr[i];
  563. /*N*/ rCount = nColCount;
  564. /*N*/ }
  565. /*N*/ void ScPivot::SetRowFields(const PivotField* pFieldArr, short nCount)
  566. /*N*/ {
  567. /*N*/ nRowCount = Max((short)0, Min(nCount, (short)PIVOT_MAXFIELD));
  568. /*N*/ for (short i = 0; i < nRowCount; i++)
  569. /*N*/ {
  570. /*N*/ aRowArr[i] = pFieldArr[i];
  571. /*N*/ aRowArr[i].nFuncCount = 0;
  572. /*N*/ if (aRowArr[i].nCol == PIVOT_DATA_FIELD)
  573. /*N*/ {
  574. /*N*/ aRowArr[i].nFuncMask = PIVOT_FUNC_NONE;
  575. /*N*/ pDataList = pRowList[i];
  576. /*N*/ bDataAtCol = FALSE;
  577. /*N*/ }
  578. /*N*/ else
  579. /*N*/ {
  580. /*N*/ for (short j=0; j<=PIVOT_MAXFUNC; j++) // incl. "auto"
  581. /*N*/ if (aRowArr[i].nFuncMask & nFuncMaskArr[j])
  582. /*N*/ aRowArr[i].nFuncCount++;
  583. /*N*/ }
  584. /*N*/ }
  585. /*N*/ bValidArea = FALSE;
  586. /*N*/ }
  587. /*N*/ void ScPivot::GetRowFields(PivotField* pFieldArr, short& rCount) const
  588. /*N*/ {
  589. /*N*/ for (short i=0; i<nRowCount; i++)
  590. /*N*/ pFieldArr[i] = aRowArr[i];
  591. /*N*/ rCount = nRowCount;
  592. /*N*/ }
  593. /*N*/ void ScPivot::SetDataFields(const PivotField* pFieldArr, short nCount)
  594. /*N*/ {
  595. /*N*/ USHORT nFuncNo;
  596. /*N*/ short i;
  597. /*N*/
  598. /*N*/ //
  599. /*N*/ // nDataCount vorausberechnen (wie unten)
  600. /*N*/ //
  601. /*N*/
  602. /*N*/ nDataCount = 0;
  603. /*N*/ for (i = 0; i < nCount; i++)
  604. /*N*/ for (nFuncNo=0; nFuncNo<PIVOT_MAXFUNC; nFuncNo++)
  605. /*N*/ if (pFieldArr[i].nFuncMask & nFuncMaskArr[nFuncNo])
  606. /*N*/ if (nDataCount+1 < PIVOT_MAXFIELD)
  607. /*N*/ ++nDataCount;
  608. /*N*/
  609. /*N*/ //
  610. /*N*/ // Eintraege anpassen
  611. /*N*/ //
  612. /*N*/
  613. /*N*/ if ((nRowCount == 1) && (aRowArr[0].nCol == PIVOT_DATA_FIELD) && (nDataCount == 1))
  614. /*N*/ {
  615. /*?*/ aColArr[nColCount] = aRowArr[0];
  616. /*?*/ pDataList = pColList[nColCount];
  617. /*?*/ nColCount++;
  618. /*?*/ nRowCount--;
  619. /*?*/ bDataAtCol = TRUE;
  620. /*N*/ }
  621. /*N*/ if ((nColCount == 1) && (aColArr[0].nCol == PIVOT_DATA_FIELD) && (nDataCount == 1))
  622. /*N*/ {
  623. /*?*/ aRowArr[nRowCount] = aColArr[0];
  624. /*?*/ pDataList = pRowList[nRowCount];
  625. /*?*/ nRowCount++;
  626. /*?*/ nColCount--;
  627. /*?*/ bDataAtCol = FALSE;
  628. /*N*/ }
  629. /*N*/
  630. /*N*/ if ((nDataCount == 1)
  631. /*N*/ && (aColArr[nColCount-1].nCol != PIVOT_DATA_FIELD)
  632. /*N*/ && (aColArr[nRowCount-1].nCol != PIVOT_DATA_FIELD))
  633. /*N*/ {
  634. /*?*/ if (bDataAtCol)
  635. /*?*/ {
  636. /*?*/ PivotField aField;
  637. /*?*/ short nIndex = PIVOT_MAXFIELD;
  638. /*?*/ for (i=0; i<nColCount; i++)
  639. /*?*/ {
  640. /*?*/ if (aColArr[i].nCol == PIVOT_DATA_FIELD)
  641. /*?*/ {
  642. /*?*/ aField = aColArr[i];
  643. /*?*/ nIndex = i;
  644. /*?*/ }
  645. /*?*/ }
  646. /*?*/ DBG_ASSERT(nIndex < PIVOT_MAXFIELD, "no data field (GPF in old versions!)");
  647. /*?*/ if ( nIndex < PIVOT_MAXFIELD )
  648. /*?*/ {
  649. /*?*/ memcpy(&aColArr[nIndex], &aColArr[nIndex+1], (PIVOT_MAXFIELD - nIndex - 1) * sizeof(PivotField));
  650. /*?*/ aColArr[nColCount-1] = aField;
  651. /*?*/ pDataList = pColList[nColCount-1];
  652. /*?*/ }
  653. /*?*/ }
  654. /*?*/ else
  655. /*?*/ {
  656. /*?*/ PivotField aField;
  657. /*?*/ short nIndex = PIVOT_MAXFIELD;
  658. /*?*/ for (i=0; i<nRowCount; i++)
  659. /*?*/ {
  660. /*?*/ if (aRowArr[i].nCol == PIVOT_DATA_FIELD)
  661. /*?*/ {
  662. /*?*/ aField = aRowArr[i];
  663. /*?*/ nIndex = i;
  664. /*?*/ }
  665. /*?*/ }
  666. /*?*/ DBG_ASSERT(nIndex < PIVOT_MAXFIELD, "no data field (GPF in old versions!)");
  667. /*?*/ if ( nIndex < PIVOT_MAXFIELD )
  668. /*?*/ {
  669. /*?*/ memcpy(&aRowArr[nIndex], &aRowArr[nIndex+1], (PIVOT_MAXFIELD - nIndex - 1) * sizeof(PivotField));
  670. /*?*/ aRowArr[nRowCount-1] = aField;
  671. /*?*/ pDataList = pRowList[nRowCount-1];
  672. /*?*/ }
  673. /*?*/ }
  674. /*N*/ }
  675. /*N*/
  676. /*N*/ //
  677. /*N*/ // Datenfelder in Eintraege mit nur einer Funktion aufteilen
  678. /*N*/ //
  679. /*N*/
  680. /*N*/ pDataList->FreeAll();
  681. /*N*/ nDataCount = 0;
  682. /*N*/ for (i = 0; i < nCount; i++)
  683. /*N*/ {
  684. /*N*/ for (nFuncNo=0; nFuncNo<PIVOT_MAXFUNC; nFuncNo++)
  685. /*N*/ if (pFieldArr[i].nFuncMask & nFuncMaskArr[nFuncNo])
  686. /*N*/ if (nDataCount+1 < PIVOT_MAXFIELD)
  687. /*N*/ {
  688. /*N*/ aDataArr[nDataCount] = pFieldArr[i];
  689. /*N*/ aDataArr[nDataCount].nFuncCount = 0;
  690. /*N*/ aDataArr[nDataCount].nFuncMask = nFuncMaskArr[nFuncNo];
  691. /*N*/
  692. /*N*/ String aStr;
  693. /*N*/ pDoc->GetString(aDataArr[nDataCount].nCol, nSrcRow1, nSrcTab, aStr);
  694. /*N*/ if (aStr.Len() == 0)
  695. /*?*/ aStr = ColToAlpha( aDataArr[nDataCount].nCol );
  696. /*N*/ TypedStrData* pStrData = new TypedStrData(aStr);
  697. /*N*/ if (!(pDataList->AtInsert(pDataList->GetCount(), pStrData)))
  698. /*N*/ {
  699. /*?*/ delete pStrData;
  700. /*?*/ OSL_FAIL("Fehler bei pDataList->AtInsert");
  701. /*N*/ }
  702. /*N*/
  703. /*N*/ ++nDataCount;
  704. /*N*/ }
  705. /*N*/ }
  706. /*N*/
  707. /*N*/ //
  708. /*N*/ //
  709. /*N*/ //
  710. /*N*/
  711. /*N*/ bValidArea = FALSE;
  712. /*N*/ }
  713. /*N*/ void ScPivot::GetDataFields(PivotField* pFieldArr, short& rCount) const
  714. /*N*/ {
  715. /*N*/ rCount = 0;
  716. /*N*/ for (short i=0; i<nDataCount; i++)
  717. /*N*/ {
  718. /*N*/ BOOL bFound = FALSE;
  719. /*N*/ for (short j=0; j<rCount && !bFound; j++)
  720. /*?*/ if (pFieldArr[j].nCol == aDataArr[i].nCol)
  721. /*?*/ {
  722. /*?*/ // add to previous column only if new bits aren't already set there
  723. /*?*/ if ( ( pFieldArr[j].nFuncMask & aDataArr[i].nFuncMask ) == 0 )
  724. /*?*/ {
  725. /*?*/ pFieldArr[j].nFuncMask |= aDataArr[i].nFuncMask;
  726. /*?*/ pFieldArr[j].nFuncCount++;
  727. /*?*/ bFound = TRUE;
  728. /*?*/ }
  729. /*?*/ }
  730. /*N*/ if (!bFound)
  731. /*N*/ {
  732. /*N*/ pFieldArr[rCount] = aDataArr[i];
  733. /*N*/ ++rCount;
  734. /*N*/ }
  735. /*N*/ }
  736. /*N*/ }
  737. /*N*/ BOOL ScPivot::CreateData(BOOL bKeepDest)
  738. /*N*/ {
  739. /*N*/ USHORT nOldCol2 = nDestCol2;
  740. /*N*/ USHORT nOldRow2 = nDestRow2;
  741. /*N*/
  742. /*N*/ pColRef = new PivotColRef[MAXCOL];
  743. /*N*/ aQuery.nCol1 = nSrcCol1;
  744. /*N*/ aQuery.nRow1 = nSrcRow1;
  745. /*N*/ aQuery.nCol2 = nSrcCol2;
  746. /*N*/ aQuery.nRow2 = nSrcRow2;
  747. /*N*/ aQuery.bHasHeader = bHasHeader;
  748. /*N*/ BOOL bRet = CreateFields();
  749. /*N*/ if (bRet)
  750. /*N*/ {
  751. /*N*/ short i=0; // nDataMult berechnen - nach CreateFields, vor CreateFieldData !!!
  752. /*N*/ nDataMult = 1;
  753. /*N*/ if (nDataCount > 1)
  754. /*N*/ {
  755. /*?*/ if (bDataAtCol)
  756. /*?*/ {
  757. /*?*/ while (i<nColCount && aColArr[i].nCol != PIVOT_DATA_FIELD) i++;
  758. /*?*/ i++;
  759. /*?*/ while (i<nColCount)
  760. /*?*/ nDataMult *= pColList[i++]->GetCount();
  761. /*?*/ }
  762. /*?*/ else
  763. /*?*/ {
  764. /*?*/ while (i<nRowCount && aRowArr[i].nCol != PIVOT_DATA_FIELD) i++;
  765. /*?*/ i++;
  766. /*?*/ while (i<nRowCount)
  767. /*?*/ nDataMult *= pRowList[i++]->GetCount();
  768. /*?*/ }
  769. /*N*/ }
  770. /*N*/ DBG_ASSERT(nDataMult,"nDataMult==0");
  771. /*N*/
  772. /*N*/ CalcArea();
  773. /*N*/ if ((nDestCol2 <= MAXCOL) && (nDestRow2 <= MAXROW))
  774. /*N*/ {
  775. /*N*/ CreateFieldData();
  776. /*N*/ bValidArea = TRUE;
  777. /*N*/ }
  778. /*N*/ else
  779. /*N*/ bRet = FALSE;
  780. /*N*/ }
  781. /*N*/
  782. /*N*/ if ( bKeepDest )
  783. /*N*/ {
  784. /*N*/ bValidArea = TRUE; //! ???
  785. /*N*/ nDestCol2 = nOldCol2;
  786. /*N*/ nDestRow2 = nOldRow2;
  787. /*N*/ }
  788. /*N*/
  789. /*N*/ return bRet;
  790. /*N*/ }
  791. /*N*/ void ScPivot::ReleaseData()
  792. /*N*/ {
  793. /*N*/ short i;
  794. /*N*/ for (i = 0; i < PIVOT_MAXFIELD; i++)
  795. /*N*/ {
  796. /*N*/ pColList[i]->FreeAll();
  797. /*N*/ pRowList[i]->FreeAll();
  798. /*N*/ }
  799. /*N*/ if (ppDataArr)
  800. /*N*/ {
  801. /*N*/ for (i=0; i<nDataRowCount; i++)
  802. /*N*/ delete[] ppDataArr[i];
  803. /*N*/ delete[] ppDataArr;
  804. /*N*/ ppDataArr = NULL;
  805. /*N*/ }
  806. /*N*/ nDataColCount = 0;
  807. /*N*/ nDataRowCount = 0;
  808. /*N*/ delete[] pColRef;
  809. /*N*/ pColRef = NULL;
  810. /*N*/ }
  811. //--------------------------------------------------------------------------------------------------
  812. // Private Methoden
  813. //--------------------------------------------------------------------------------------------------
  814. /*N*/ BOOL ScPivot::CreateFields()
  815. /*N*/ {
  816. /*N*/ short i;
  817. /*N*/ USHORT nRow;
  818. /*N*/ USHORT nHeader;
  819. /*N*/ String aStr;
  820. /*N*/ TypedStrData* pStrData;
  821. /*N*/ if (bHasHeader)
  822. /*N*/ nHeader = 1;
  823. /*N*/ else
  824. /*N*/ nHeader = 0;
  825. /*N*/
  826. /*N*/ // Sortieren nach Benutzerdefinierte Listen ??
  827. /*N*/ for (i = 0; i < nColCount; i++)
  828. /*N*/ {
  829. /*N*/ if (aColArr[i].nCol != PIVOT_DATA_FIELD)
  830. /*N*/ {
  831. /*N*/ pDoc->GetString(aColArr[i].nCol, nSrcRow1 + nHeader, nSrcTab, aStr);
  832. /*N*/ pColList[i]->SetUserData(ScGlobal::GetUserList()->GetData(aStr));
  833. /*N*/ }
  834. /*N*/ else
  835. /*N*/ pColList[i]->SetUserData(NULL);
  836. /*N*/ }
  837. /*N*/ for (i = 0; i < nRowCount; i++)
  838. /*N*/ {
  839. /*N*/ if (aRowArr[i].nCol != PIVOT_DATA_FIELD)
  840. /*N*/ {
  841. /*N*/ pDoc->GetString(aRowArr[i].nCol, nSrcRow1 + nHeader, nSrcTab, aStr);
  842. /*N*/ pRowList[i]->SetUserData(ScGlobal::GetUserList()->GetData(aStr));
  843. /*N*/ }
  844. /*N*/ else
  845. /*?*/ pRowList[i]->SetUserData(NULL);
  846. /*N*/ }
  847. /*N*/
  848. /*N*/ ScAddress aSrcAdr( nSrcCol1, 0, nSrcTab );
  849. /*N*/ for (nRow = nSrcRow1 + nHeader; nRow <= nSrcRow2; nRow++)
  850. /*N*/ {
  851. /*N*/ BOOL bValidLine = TRUE;
  852. /*N*/ if (bValidLine)
  853. /*N*/ bValidLine = pDoc->pTab[nSrcTab]->ValidQuery(nRow, aQuery);
  854. /*N*/ if (bValidLine)
  855. /*N*/ {
  856. /*N*/ // Sortierte Liste der Felder erzeugen
  857. /*N*/ //! statt GetCategoryString leere weglassen !
  858. /*N*/
  859. /*N*/ for (i = 0; i < nColCount; i++)
  860. /*N*/ {
  861. /*N*/ if (aColArr[i].nCol != PIVOT_DATA_FIELD)
  862. /*N*/ {
  863. /*N*/ USHORT nCatRow = bDetectCat ? GetCategoryRow( aColArr[i].nCol, nRow ) : nRow;
  864. /*N*/ pStrData = new TypedStrData( pDoc, aColArr[i].nCol, nCatRow, nSrcTab, TRUE );
  865. /*N*/ if (!(pColList[i]->Insert(pStrData)))
  866. /*N*/ delete pStrData;
  867. /*N*/ }
  868. /*N*/ }
  869. /*N*/ for (i = 0; i < nRowCount; i++)
  870. /*N*/ {
  871. /*N*/ if (aRowArr[i].nCol != PIVOT_DATA_FIELD)
  872. /*N*/ {
  873. /*N*/ USHORT nCatRow = bDetectCat ? GetCategoryRow( aRowArr[i].nCol, nRow ) : nRow;
  874. /*N*/ pStrData = new TypedStrData( pDoc, aRowArr[i].nCol, nCatRow, nSrcTab, TRUE );
  875. /*N*/ if (!(pRowList[i]->Insert(pStrData)))
  876. /*N*/ delete pStrData;
  877. /*N*/ }
  878. /*N*/ }
  879. /*N*/ }
  880. /*N*/ }
  881. /*N*/ return TRUE;
  882. /*N*/ }
  883. /*N*/ void ScPivot::CreateFieldData()
  884. /*N*/ {
  885. /*N*/ USHORT* pRowListIndex = nRowCount ? new USHORT[nRowCount] : NULL;
  886. /*N*/ USHORT* pColListIndex = nColCount ? new USHORT[nColCount] : NULL;
  887. /*N*/
  888. /*N*/ short i,j,k;
  889. /*N*/
  890. /*N*/ ppDataArr = new SubTotal*[nDataRowCount];
  891. /*N*/ for (i=0; i<nDataRowCount; i++)
  892. /*N*/ ppDataArr[i] = new SubTotal[nDataColCount];
  893. /*N*/
  894. /*N*/ if (bDataAtCol)
  895. /*N*/ for (j=0; j<nDataRowCount; j++)
  896. /*N*/ for (i=0; i<nDataColCount; i++)
  897. /*N*/ ppDataArr[j][i].nIndex = j/nDataMult%nDataCount;
  898. /*N*/ else
  899. /*?*/ for (j=0; j<nDataRowCount; j++)
  900. /*?*/ for (i=0; i<nDataColCount; i++)
  901. /*?*/ ppDataArr[j][i].nIndex = i/nDataMult%nDataCount;
  902. /*N*/
  903. /*N*/ short nHeader;
  904. /*N*/ if (bHasHeader)
  905. /*N*/ nHeader = 1;
  906. /*N*/ else
  907. /*N*/ nHeader = 0;
  908. /*N*/ ScAddress aSrcAdr( nSrcCol1, 0, nSrcTab );
  909. /*N*/ for (USHORT nRow = nSrcRow1 + nHeader; nRow <= nSrcRow2; nRow++)
  910. /*N*/ {
  911. /*N*/ BOOL bValidLine = TRUE;
  912. /*N*/ if (bValidLine)
  913. /*N*/ bValidLine = pDoc->pTab[nSrcTab]->ValidQuery(nRow, aQuery);
  914. /*N*/ if (bValidLine)
  915. /*N*/ {
  916. /*N*/ // Indizes der Kategorien nur einmal ausserhalb nDataCount
  917. /*N*/ for (j=0; j<nRowCount; j++)
  918. /*N*/ if (aRowArr[j].nCol != PIVOT_DATA_FIELD)
  919. /*N*/ {
  920. /*N*/ USHORT nCatRow = bDetectCat ? GetCategoryRow( aRowArr[j].nCol, nRow ) : nRow;
  921. /*N*/ TypedStrData aStrData( pDoc, aRowArr[j].nCol, nCatRow, nSrcTab, TRUE );
  922. /*N*/ pRowListIndex[j] = pRowList[j]->GetIndex(&aStrData);
  923. /*N*/ }
  924. /*N*/ for (j=0; j<nColCount; j++)
  925. /*N*/ if (aColArr[j].nCol != PIVOT_DATA_FIELD)
  926. /*N*/ {
  927. /*N*/ USHORT nCatRow = bDetectCat ? GetCategoryRow( aColArr[j].nCol, nRow ) : nRow;
  928. /*N*/ TypedStrData aStrData( pDoc, aColArr[j].nCol, nCatRow, nSrcTab, TRUE );
  929. /*N*/ pColListIndex[j] = pColList[j]->GetIndex(&aStrData);
  930. /*N*/ }
  931. /*N*/
  932. /*N*/ String aStr;
  933. /*N*/ short nCIndex;
  934. /*N*/ short nRIndex;
  935. /*N*/ short nIndex;
  936. /*N*/ ScAddress aAdr( 0, nRow, nSrcTab );
  937. /*N*/
  938. /*N*/ for (i=0; i<nDataCount; i++)
  939. /*N*/ {
  940. /*N*/ // ColIndex Berechnen
  941. /*N*/ nCIndex = 0;
  942. /*N*/ for (j=0; j<nRowCount; j++)
  943. /*N*/ {
  944. /*N*/ if (aRowArr[j].nCol == PIVOT_DATA_FIELD)
  945. /*N*/ nIndex = i;
  946. /*N*/ else
  947. /*N*/ nIndex = pRowListIndex[j];
  948. /*N*/ if (nIndex)
  949. /*N*/ {
  950. /*N*/ for (k=j+1; k<nRowCount; k++)
  951. /*?*/ nIndex *= pRowList[k]->GetCount();
  952. /*N*/ nCIndex += nIndex;
  953. /*N*/ }
  954. /*N*/ }
  955. /*N*/ // RowIndex Berechnen
  956. /*N*/ nRIndex = 0;
  957. /*N*/ for (j=0; j<nColCount; j++)
  958. /*N*/ {
  959. /*N*/ if (aColArr[j].nCol == PIVOT_DATA_FIELD)
  960. /*N*/ nIndex = i;
  961. /*N*/ else
  962. /*N*/ nIndex = pColListIndex[j];
  963. /*N*/ if (nIndex)
  964. /*N*/ {
  965. /*N*/ for (k=j+1; k<nColCount; k++)
  966. /*N*/ nIndex *= pColList[k]->GetCount();
  967. /*N*/ nRIndex += nIndex;
  968. /*N*/ }
  969. /*N*/ }
  970. /*N*/ // Daten eintragen
  971. /*N*/ if ((nCIndex < nDataColCount) && (nRIndex < nDataRowCount))
  972. /*N*/ {
  973. /*N*/ DBG_ASSERT((short)ppDataArr[nRIndex][nCIndex].nIndex == i, "falsch init.");
  974. /*N*/
  975. /*N*/ ppDataArr[nRIndex][nCIndex].nIndex = i;
  976. /*N*/ aAdr.SetCol( aDataArr[i].nCol );
  977. /*N*/ CellType eCellType = pDoc->GetCellType( aAdr );
  978. /*N*/ if ((eCellType != CELLTYPE_NONE) && (eCellType != CELLTYPE_NOTE))
  979. /*N*/ {
  980. /*N*/ BOOL bValue = (eCellType == CELLTYPE_VALUE);
  981. /*N*/ if (eCellType == CELLTYPE_FORMULA)
  982. /*N*/ {
  983. /*N*/ ScBaseCell* pCell = pDoc->GetCell( aAdr );
  984. /*N*/ bValue = ((ScFormulaCell*)pCell)->IsValue();
  985. /*N*/ }
  986. /*N*/
  987. /*N*/ if (bValue)
  988. /*N*/ {
  989. /*N*/ double nVal = pDoc->GetValue( aAdr );
  990. /*N*/ ppDataArr[nRIndex][nCIndex].Update(nVal);
  991. /*N*/ }
  992. /*N*/ }
  993. /*N*/ }
  994. /*N*/ }
  995. /*N*/ }
  996. /*N*/ }
  997. /*N*/
  998. /*N*/ delete pColListIndex;
  999. /*N*/ delete pRowListIndex;
  1000. /*N*/ }
  1001. /*N*/ void ScPivot::CalcArea()
  1002. /*N*/ {
  1003. /*N*/ BOOL bNoRows = (nRowCount == 0) || ( nRowCount == 1 && aRowArr[0].nCol == PIVOT_DATA_FIELD );
  1004. /*N*/ BOOL bNoCols = (nColCount == 0) || ( nColCount == 1 && aColArr[0].nCol == PIVOT_DATA_FIELD );
  1005. /*N*/ if (!bMakeTotalCol) bNoRows = TRUE;
  1006. /*N*/ if (!bMakeTotalRow) bNoCols = TRUE;
  1007. /*N*/
  1008. /*N*/ short i;
  1009. /*N*/ short nDx;
  1010. /*N*/ // StartSpalte/StartZeile des Datenbereichs berechnen
  1011. /*N*/ if (bDataAtCol)
  1012. /*N*/ {
  1013. /*N*/ if (nDataCount > 1)
  1014. /*?*/ nDataStartCol = nDestCol1 + nColCount;
  1015. /*N*/ else
  1016. /*N*/ nDataStartCol = nDestCol1 + Max(0, nColCount - 1);
  1017. /*N*/ }
  1018. /*N*/ else
  1019. /*?*/ nDataStartCol = nDestCol1 + nColCount;
  1020. /*N*/ if (!bDataAtCol)
  1021. /*N*/ {
  1022. /*?*/ if (nDataCount > 1)
  1023. /*?*/ nDataStartRow = nDestRow1 + nRowCount + nFirstLine + 1;
  1024. /*?*/ else
  1025. /*?*/ nDataStartRow = nDestRow1 + Max(0, nRowCount - 1) + nFirstLine + 1;
  1026. /*N*/ }
  1027. /*N*/ else
  1028. /*N*/ nDataStartRow = nDestRow1 + nRowCount + nFirstLine + 1;
  1029. /*N*/
  1030. /*N*/ //
  1031. /*N*/ // Groesse der PivotTabelle berechnen
  1032. /*N*/ //
  1033. /*N*/
  1034. /*N*/ if (nRowCount == 0 || (nRowCount==1 && aRowArr[0].nCol==PIVOT_DATA_FIELD && nDataCount==1))
  1035. /*N*/ {
  1036. /*?*/ nDataColCount = 1;
  1037. /*?*/ if (nDataCount == 1)
  1038. /*?*/ nDestCol2 = nDestCol1 + nColCount - 1;
  1039. /*?*/ else
  1040. /*?*/ nDestCol2 = nDestCol1 + nColCount;
  1041. /*N*/ }
  1042. /*N*/ else
  1043. /*N*/ {
  1044. /*N*/ // Anzahl Spalten
  1045. /*N*/ if ((aRowArr[nRowCount-1].nCol == PIVOT_DATA_FIELD) && (nDataCount == 1))
  1046. /*N*/ nDx = 2;
  1047. /*N*/ else
  1048. /*N*/ nDx = 1;
  1049. /*N*/ long nColLines = pRowList[nRowCount-nDx]->GetCount(); // long um Ueberlauf zu erkennen
  1050. /*N*/ nDataColCount = pRowList[nRowCount-nDx]->GetCount();
  1051. /*N*/ for (i=nRowCount-nDx-1; i >= 0; i--)
  1052. /*N*/ {
  1053. /*?*/ nColLines *= pRowList[i]->GetCount();
  1054. /*?*/ nDataColCount *= pRowList[i]->GetCount();
  1055. /*?*/ if (!bDataAtCol)
  1056. /*?*/ nColLines += (pRowList[i]->GetCount() * aRowArr[i].nFuncCount * nDataCount);
  1057. /*?*/ else
  1058. /*?*/ nColLines += (pRowList[i]->GetCount() * aRowArr[i].nFuncCount);
  1059. /*N*/ }
  1060. /*N*/ if (nColLines > MAXCOL)
  1061. /*?*/ nDestCol2 = MAXCOL+2; // ungueltig, 1 wird unten abgezogen
  1062. /*N*/ else if (bDataAtCol)
  1063. /*N*/ {
  1064. /*N*/ if (nDataCount > 1)
  1065. /*?*/ nDestCol2 = nDestCol1 + nColCount + nColLines;
  1066. /*N*/ else
  1067. /*N*/ nDestCol2 = nDestCol1 + (nColCount - 1) + nColLines;
  1068. /*N*/ if (!bMakeTotalCol)
  1069. /*?*/ --nDestCol2;
  1070. /*N*/ }
  1071. /*N*/ else
  1072. /*?*/ nDestCol2 = nDestCol1 + nColCount + nColLines;
  1073. /*N*/ }
  1074. /*N*/
  1075. /*N*/ if (nColCount == 0 || (nColCount==1 && aColArr[0].nCol==PIVOT_DATA_FIELD && nDataCount==1))
  1076. /*N*/ {
  1077. /*?*/ nDataRowCount = 1;
  1078. /*?*/ if (nDataCount == 1)
  1079. /*?*/ nDestRow2 = nDestRow1 + (nRowCount - 1) + nFirstLine + 1;
  1080. /*?*/ else
  1081. /*?*/ nDestRow2 = nDestRow1 + nRowCount + nFirstLine + 1;
  1082. /*N*/ }
  1083. /*N*/ else
  1084. /*N*/ {
  1085. /*N*/ // Anzahl Zeilen
  1086. /*N*/ if ((aColArr[nColCount-1].nCol == PIVOT_DATA_FIELD) && (nDataCount == 1))
  1087. /*N*/ nDx = 2;
  1088. /*N*/ else
  1089. /*N*/ nDx = 1;
  1090. /*N*/ long nRowLines = pColList[nColCount-nDx]->GetCount(); // long um Ueberlauf zu erkennen
  1091. /*N*/ nDataRowCount = pColList[nColCount-nDx]->GetCount();
  1092. /*N*/ for (i=nColCount-nDx-1; i >= 0; i--)
  1093. /*N*/ {
  1094. /*?*/ nRowLines *= pColList[i]->GetCount();
  1095. /*?*/ nDataRowCount *= pColList[i]->GetCount();
  1096. /*?*/ if (bDataAtCol)
  1097. /*?*/ nRowLines += (pColList[i]->GetCount() * aColArr[i].nFuncCount * nDataCount);
  1098. /*?*/ else
  1099. /*?*/ nRowLines += (pColList[i]->GetCount() * aColArr[i].nFuncCount);
  1100. /*N*/ }
  1101. /*N*/ if (nRowLines > MAXROW)
  1102. /*?*/ nDestRow2 = MAXROW+2; // ungueltig, 1 wird unten abgezogen
  1103. /*N*/ else if (!bDataAtCol)
  1104. /*N*/ {
  1105. /*?*/ if (nDataCount > 1)
  1106. /*?*/ nDestRow2 = nDestRow1 + nRowCount + nRowLines + nFirstLine + 1;
  1107. /*?*/ else
  1108. /*?*/ nDestRow2 = nDestRow1 + (nRowCount - 1) + nRowLines + nFirstLine + 1;
  1109. /*?*/ if (!bMakeTotalRow)
  1110. /*?*/ --nDestRow2;
  1111. /*N*/ }
  1112. /*N*/ else
  1113. /*N*/ nDestRow2 = nDestRow1 + nRowCount + nRowLines + nFirstLine + 1;
  1114. /*N*/ }
  1115. /*N*/
  1116. /*N*/ if (bDataAtCol)
  1117. /*N*/ {
  1118. /*N*/ if (!bNoCols)
  1119. /*N*/ nDestRow2 += nDataCount;
  1120. /*N*/ nDestRow2 --;
  1121. /*N*/ }
  1122. /*N*/ else
  1123. /*N*/ {
  1124. /*?*/ if (!bNoRows)
  1125. /*?*/ nDestCol2 += nDataCount;
  1126. /*?*/ nDestCol2 --;
  1127. /*N*/ }
  1128. /*N*/ }
  1129. /*N*/ USHORT ScPivot::GetCategoryRow( USHORT nCol, USHORT nRow )
  1130. /*N*/ {
  1131. /*N*/ USHORT nMinRow = nSrcRow1;
  1132. /*N*/ if (bHasHeader) ++nMinRow;
  1133. /*N*/ BOOL bFound = FALSE;
  1134. /*N*/ do
  1135. /*N*/ {
  1136. /*N*/ if ( !pDoc->HasData( nCol, nRow, nSrcTab ) && nRow>nMinRow )
  1137. /*N*/ --nRow;
  1138. /*N*/ else
  1139. /*N*/ bFound = TRUE;
  1140. /*N*/ }
  1141. /*N*/ while (!bFound);
  1142. /*N*/ return nRow;
  1143. /*N*/ }
  1144. }
  1145. /* vim:set shiftwidth=4 softtabstop=4 expandtab: */