1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 // MARKER(update_precomp.py): autogen include statement, do not remove 25 #include "precompiled_sc.hxx" 26 27 // System - Includes --------------------------------------------------------- 28 29 30 31 #include <sfx2/dispatch.hxx> 32 33 // INCLUDE ------------------------------------------------------------------- 34 35 #include "tabvwsh.hxx" 36 #include "uiitems.hxx" 37 #include "dbcolect.hxx" 38 #include "rangenam.hxx" 39 #include "rangeutl.hxx" 40 #include "reffact.hxx" 41 #include "document.hxx" 42 #include "scresid.hxx" 43 44 #include "globstr.hrc" 45 #include "consdlg.hrc" 46 47 #define _CONSDLG_CXX 48 #include "consdlg.hxx" 49 #undef _CONSDLG_CXX 50 #include <vcl/msgbox.hxx> 51 52 #define INFOBOX(id) InfoBox(this, ScGlobal::GetRscString(id)).Execute() 53 54 //============================================================================ 55 // class ScAreaData 56 57 class ScAreaData 58 { 59 public: 60 ScAreaData() {} 61 ~ScAreaData() {} 62 63 void Set( const String& rName, const String& rArea, sal_Bool bDb ) 64 { 65 aStrName = rName; 66 aStrArea = rArea; 67 bIsDbArea = bDb; 68 } 69 70 String aStrName; 71 String aStrArea; 72 sal_Bool bIsDbArea; 73 }; 74 75 76 //============================================================================ 77 // class ScConsolidateDialog 78 79 80 ScConsolidateDlg::ScConsolidateDlg( SfxBindings* pB, SfxChildWindow* pCW, Window* pParent, 81 const SfxItemSet& rArgSet ) 82 83 : ScAnyRefDlg ( pB, pCW, pParent, RID_SCDLG_CONSOLIDATE ), 84 // 85 aFtFunc ( this, ScResId( FT_FUNC ) ), 86 aLbFunc ( this, ScResId( LB_FUNC ) ), 87 88 aFtConsAreas ( this, ScResId( FT_CONSAREAS ) ), 89 aLbConsAreas ( this, ScResId( LB_CONSAREAS ) ), 90 91 aLbDataArea ( this, ScResId( LB_DATA_AREA ) ), 92 aFtDataArea ( this, ScResId( FT_DATA_AREA ) ), 93 aEdDataArea ( this, this, ScResId( ED_DATA_AREA ) ), 94 aRbDataArea ( this, ScResId( RB_DATA_AREA ), &aEdDataArea, this ), 95 96 aLbDestArea ( this, ScResId( LB_DEST_AREA ) ), 97 aFtDestArea ( this, ScResId( FT_DEST_AREA ) ), 98 aEdDestArea ( this, this, ScResId( ED_DEST_AREA ) ), 99 aRbDestArea ( this, ScResId( RB_DEST_AREA ), &aEdDestArea, this), 100 101 aFlConsBy ( this, ScResId( FL_CONSBY ) ), 102 aBtnByRow ( this, ScResId( BTN_BYROW ) ), 103 aBtnByCol ( this, ScResId( BTN_BYCOL) ), 104 105 aFlSep ( this, ScResId( FL_SEP ) ), 106 aFlOptions ( this, ScResId( FL_OPTIONS ) ), 107 aBtnRefs ( this, ScResId( BTN_REFS ) ), 108 109 aBtnOk ( this, ScResId( BTN_OK ) ), 110 aBtnCancel ( this, ScResId( BTN_CANCEL ) ), 111 aBtnHelp ( this, ScResId( BTN_HELP ) ), 112 aBtnAdd ( this, ScResId( BTN_ADD ) ), 113 aBtnRemove ( this, ScResId( BTN_REMOVE ) ), 114 aBtnMore ( this, ScResId( BTN_MORE ) ), 115 116 aStrUndefined ( ScResId( SCSTR_UNDEFINED ) ), 117 // 118 theConsData ( ((const ScConsolidateItem&) 119 rArgSet.Get( rArgSet.GetPool()-> 120 GetWhich( SID_CONSOLIDATE ) ) 121 ).GetData() ), 122 pViewData ( ((ScTabViewShell*)SfxViewShell::Current())-> 123 GetViewData() ), 124 pDoc ( ((ScTabViewShell*)SfxViewShell::Current())-> 125 GetViewData()->GetDocument() ), 126 pRangeUtil ( new ScRangeUtil ), 127 pAreaData ( NULL ), 128 nAreaDataCount ( 0 ), 129 nWhichCons ( rArgSet.GetPool()->GetWhich( SID_CONSOLIDATE ) ), 130 131 pRefInputEdit ( &aEdDataArea ) 132 { 133 Init(); 134 FreeResource(); 135 } 136 137 138 //---------------------------------------------------------------------------- 139 140 __EXPORT ScConsolidateDlg::~ScConsolidateDlg() 141 { 142 delete [] pAreaData; 143 delete pRangeUtil; 144 } 145 146 147 //---------------------------------------------------------------------------- 148 149 void ScConsolidateDlg::Init() 150 { 151 DBG_ASSERT( pViewData && pDoc && pRangeUtil, "Error in Ctor" ); 152 153 String aStr; 154 sal_uInt16 i=0; 155 156 aEdDataArea .SetGetFocusHdl( LINK( this, ScConsolidateDlg, GetFocusHdl ) ); 157 aEdDestArea .SetGetFocusHdl( LINK( this, ScConsolidateDlg, GetFocusHdl ) ); 158 aLbDataArea .SetGetFocusHdl( LINK( this, ScConsolidateDlg, GetFocusHdl ) ); 159 aLbDestArea .SetGetFocusHdl( LINK( this, ScConsolidateDlg, GetFocusHdl ) ); 160 aEdDataArea .SetModifyHdl ( LINK( this, ScConsolidateDlg, ModifyHdl ) ); 161 aEdDestArea .SetModifyHdl ( LINK( this, ScConsolidateDlg, ModifyHdl ) ); 162 aLbConsAreas.SetSelectHdl ( LINK( this, ScConsolidateDlg, SelectHdl ) ); 163 aLbDataArea .SetSelectHdl ( LINK( this, ScConsolidateDlg, SelectHdl ) ); 164 aLbDestArea .SetSelectHdl ( LINK( this, ScConsolidateDlg, SelectHdl ) ); 165 aBtnOk .SetClickHdl ( LINK( this, ScConsolidateDlg, OkHdl ) ); 166 aBtnCancel .SetClickHdl ( LINK( this, ScConsolidateDlg, ClickHdl ) ); 167 aBtnAdd .SetClickHdl ( LINK( this, ScConsolidateDlg, ClickHdl ) ); 168 aBtnRemove .SetClickHdl ( LINK( this, ScConsolidateDlg, ClickHdl ) ); 169 170 aBtnMore.AddWindow( &aFlConsBy ); 171 aBtnMore.AddWindow( &aBtnByRow ); 172 aBtnMore.AddWindow( &aBtnByCol ); 173 aBtnMore.AddWindow( &aFlSep ); 174 aBtnMore.AddWindow( &aFlOptions ); 175 aBtnMore.AddWindow( &aBtnRefs ); 176 177 aBtnAdd.Disable(); 178 aBtnRemove.Disable(); 179 180 aBtnByRow.Check( theConsData.bByRow ); 181 aBtnByCol.Check( theConsData.bByCol ); 182 aBtnRefs .Check( theConsData.bReferenceData ); 183 184 aLbFunc.SelectEntryPos( FuncToLbPos( theConsData.eFunction ) ); 185 186 // Einlesen der Konsolidierungsbereiche 187 aLbConsAreas.Clear(); 188 const formula::FormulaGrammar::AddressConvention eConv = pDoc->GetAddressConvention(); 189 for ( i=0; i<theConsData.nDataAreaCount; i++ ) 190 { 191 const ScArea& rArea = *(theConsData.ppDataAreas[i] ); 192 if ( rArea.nTab < pDoc->GetTableCount() ) 193 { 194 ScRange( rArea.nColStart, rArea.nRowStart, rArea.nTab, 195 rArea.nColEnd, rArea.nRowEnd, rArea.nTab ).Format( aStr, 196 SCR_ABS_3D, pDoc, eConv ); 197 aLbConsAreas.InsertEntry( aStr ); 198 } 199 } 200 201 if ( theConsData.nTab < pDoc->GetTableCount() ) 202 { 203 ScAddress( theConsData.nCol, theConsData.nRow, theConsData.nTab 204 ).Format( aStr, SCA_ABS_3D, pDoc, eConv ); 205 aEdDestArea.SetText( aStr ); 206 } 207 else 208 aEdDestArea.SetText( EMPTY_STRING ); 209 210 //---------------------------------------------------------- 211 212 /* 213 * Aus den RangeNames und Datenbankbereichen werden sich 214 * in der Hilfsklasse ScAreaData die Bereichsnamen gemerkt, 215 * die in den ListBoxen erscheinen. 216 */ 217 218 ScRangeName* pRangeNames = pDoc->GetRangeName(); 219 ScDBCollection* pDbNames = pDoc->GetDBCollection(); 220 const sal_uInt16 nRangeCount = pRangeNames ? pRangeNames->GetCount() : 0; 221 const sal_uInt16 nDbCount = pDbNames ? pDbNames ->GetCount() : 0; 222 223 nAreaDataCount = nRangeCount+nDbCount; 224 pAreaData = NULL; 225 226 if ( nAreaDataCount > 0 ) 227 { 228 pAreaData = new ScAreaData[nAreaDataCount]; 229 230 String aStrName; 231 String aStrArea; 232 sal_uInt16 nAt = 0; 233 ScRange aRange; 234 ScAreaNameIterator aIter( pDoc ); 235 while ( aIter.Next( aStrName, aRange ) ) 236 { 237 aRange.Format( aStrArea, SCA_ABS_3D, pDoc, eConv ); 238 pAreaData[nAt++].Set( aStrName, aStrArea, aIter.WasDBName() ); 239 } 240 } 241 242 FillAreaLists(); 243 ModifyHdl( &aEdDestArea ); 244 aLbDataArea.SelectEntryPos( 0 ); 245 aEdDataArea.SetText( EMPTY_STRING ); 246 aEdDataArea.GrabFocus(); 247 248 aFlSep.SetStyle( aFlSep.GetStyle() | WB_VERT ); 249 250 //@BugID 54702 Enablen/Disablen nur noch in Basisklasse 251 //SFX_APPWINDOW->Enable(); 252 } 253 254 255 //---------------------------------------------------------------------------- 256 void ScConsolidateDlg::FillAreaLists() 257 { 258 aLbDataArea.Clear(); 259 aLbDestArea.Clear(); 260 aLbDataArea.InsertEntry( aStrUndefined ); 261 aLbDestArea.InsertEntry( aStrUndefined ); 262 263 if ( pRangeUtil && pAreaData && (nAreaDataCount > 0) ) 264 { 265 String aString; 266 267 for ( sal_uInt16 i=0; 268 (i<nAreaDataCount) && (pAreaData[i].aStrName.Len()>0); 269 i++ ) 270 { 271 aLbDataArea.InsertEntry( pAreaData[i].aStrName, i+1 ); 272 273 // if ( !pAreaData[i].bIsDbArea ) 274 aLbDestArea.InsertEntry( pAreaData[i].aStrName, i+1 ); 275 } 276 } 277 } 278 279 280 //---------------------------------------------------------------------------- 281 // Uebergabe eines mit der Maus selektierten Tabellenbereiches, der dann als 282 // neue Selektion im Referenz-Fenster angezeigt wird. 283 284 285 void ScConsolidateDlg::SetReference( const ScRange& rRef, ScDocument* pDocP ) 286 { 287 if ( pRefInputEdit ) 288 { 289 if ( rRef.aStart != rRef.aEnd ) 290 RefInputStart( pRefInputEdit ); 291 292 String aStr; 293 sal_uInt16 nFmt = SCR_ABS_3D; //!!! nCurTab fehlt noch 294 const formula::FormulaGrammar::AddressConvention eConv = pDocP->GetAddressConvention(); 295 296 if ( rRef.aStart.Tab() != rRef.aEnd.Tab() ) 297 nFmt |= SCA_TAB2_3D; 298 299 if ( pRefInputEdit == &aEdDataArea) 300 rRef.Format( aStr, nFmt, pDocP, eConv ); 301 else if ( pRefInputEdit == &aEdDestArea ) 302 rRef.aStart.Format( aStr, nFmt, pDocP, eConv ); 303 304 pRefInputEdit->SetRefString( aStr ); 305 } 306 307 ModifyHdl( pRefInputEdit ); 308 } 309 310 311 //---------------------------------------------------------------------------- 312 313 sal_Bool __EXPORT ScConsolidateDlg::Close() 314 { 315 return DoClose( ScConsolidateDlgWrapper::GetChildWindowId() ); 316 } 317 318 319 //---------------------------------------------------------------------------- 320 321 void ScConsolidateDlg::SetActive() 322 { 323 if ( bDlgLostFocus ) 324 { 325 bDlgLostFocus = sal_False; 326 327 if ( pRefInputEdit ) 328 { 329 pRefInputEdit->GrabFocus(); 330 ModifyHdl( pRefInputEdit ); 331 } 332 } 333 else 334 GrabFocus(); 335 336 RefInputDone(); 337 } 338 339 340 //---------------------------------------------------------------------------- 341 342 void __EXPORT ScConsolidateDlg::Deactivate() 343 { 344 bDlgLostFocus = sal_True; 345 } 346 347 348 //---------------------------------------------------------------------------- 349 350 sal_Bool ScConsolidateDlg::VerifyEdit( formula::RefEdit* pEd ) 351 { 352 if ( !pRangeUtil || !pDoc || !pViewData || 353 ((pEd != &aEdDataArea) && (pEd != &aEdDestArea)) ) 354 return sal_False; 355 356 SCTAB nTab = pViewData->GetTabNo(); 357 sal_Bool bEditOk = sal_False; 358 String theCompleteStr; 359 const formula::FormulaGrammar::AddressConvention eConv = pDoc->GetAddressConvention(); 360 361 if ( pEd == &aEdDataArea ) 362 { 363 bEditOk = pRangeUtil->IsAbsArea( pEd->GetText(), pDoc, 364 nTab, &theCompleteStr, NULL, NULL, eConv ); 365 } 366 else if ( pEd == &aEdDestArea ) 367 { 368 String aPosStr; 369 370 pRangeUtil->CutPosString( pEd->GetText(), aPosStr ); 371 bEditOk = pRangeUtil->IsAbsPos( aPosStr, pDoc, 372 nTab, &theCompleteStr, NULL, eConv ); 373 } 374 375 if ( bEditOk ) 376 pEd->SetText( theCompleteStr ); 377 378 return bEditOk; 379 } 380 381 382 //---------------------------------------------------------------------------- 383 // Handler: 384 // ======== 385 386 IMPL_LINK( ScConsolidateDlg, GetFocusHdl, Control*, pCtr ) 387 { 388 if ( pCtr ==(Control*)&aEdDataArea || 389 pCtr ==(Control*)&aEdDestArea) 390 { 391 pRefInputEdit = (formula::RefEdit*)pCtr; 392 } 393 else if(pCtr ==(Control*)&aLbDataArea ) 394 { 395 pRefInputEdit = &aEdDataArea; 396 } 397 else if(pCtr ==(Control*)&aLbDestArea ) 398 { 399 pRefInputEdit = &aEdDestArea; 400 } 401 return 0; 402 } 403 404 405 //---------------------------------------------------------------------------- 406 407 IMPL_LINK( ScConsolidateDlg, OkHdl, void*, EMPTYARG ) 408 { 409 sal_uInt16 nDataAreaCount = aLbConsAreas.GetEntryCount(); 410 411 if ( nDataAreaCount > 0 ) 412 { 413 ScRefAddress aDestAddress; 414 SCTAB nTab = pViewData->GetTabNo(); 415 String aDestPosStr( aEdDestArea.GetText() ); 416 const formula::FormulaGrammar::AddressConvention eConv = pDoc->GetAddressConvention(); 417 418 if ( pRangeUtil->IsAbsPos( aDestPosStr, pDoc, nTab, NULL, &aDestAddress, eConv ) ) 419 { 420 ScConsolidateParam theOutParam( theConsData ); 421 ScArea** ppDataAreas = new ScArea*[nDataAreaCount]; 422 ScArea* pArea; 423 sal_uInt16 i=0; 424 425 for ( i=0; i<nDataAreaCount; i++ ) 426 { 427 pArea = new ScArea; 428 pRangeUtil->MakeArea( aLbConsAreas.GetEntry( i ), 429 *pArea, pDoc, nTab, eConv ); 430 ppDataAreas[i] = pArea; 431 } 432 433 theOutParam.nCol = aDestAddress.Col(); 434 theOutParam.nRow = aDestAddress.Row(); 435 theOutParam.nTab = aDestAddress.Tab(); 436 theOutParam.eFunction = LbPosToFunc( aLbFunc.GetSelectEntryPos() ); 437 theOutParam.bByCol = aBtnByCol.IsChecked(); 438 theOutParam.bByRow = aBtnByRow.IsChecked(); 439 theOutParam.bReferenceData = aBtnRefs.IsChecked(); 440 theOutParam.SetAreas( ppDataAreas, nDataAreaCount ); 441 442 for ( i=0; i<nDataAreaCount; i++ ) 443 delete ppDataAreas[i]; 444 delete [] ppDataAreas; 445 446 ScConsolidateItem aOutItem( nWhichCons, &theOutParam ); 447 448 SetDispatcherLock( sal_False ); 449 SwitchToDocument(); 450 GetBindings().GetDispatcher()->Execute( SID_CONSOLIDATE, 451 SFX_CALLMODE_SLOT | SFX_CALLMODE_RECORD, 452 &aOutItem, 0L, 0L ); 453 Close(); 454 } 455 else 456 { 457 INFOBOX( STR_INVALID_TABREF ); 458 aEdDestArea.GrabFocus(); 459 } 460 } 461 else 462 Close(); // keine Datenbereiche definiert -> Cancel 463 return 0; 464 } 465 466 467 //---------------------------------------------------------------------------- 468 469 IMPL_LINK( ScConsolidateDlg, ClickHdl, PushButton*, pBtn ) 470 { 471 if ( pBtn == &aBtnCancel ) 472 Close(); 473 else if ( pBtn == &aBtnAdd ) 474 { 475 if ( aEdDataArea.GetText().Len() > 0 ) 476 { 477 String aNewEntry( aEdDataArea.GetText() ); 478 ScArea** ppAreas = NULL; 479 sal_uInt16 nAreaCount = 0; 480 const formula::FormulaGrammar::AddressConvention eConv = pDoc->GetAddressConvention(); 481 482 if ( pRangeUtil->IsAbsTabArea( aNewEntry, pDoc, &ppAreas, &nAreaCount, sal_True, eConv ) ) 483 { 484 // IsAbsTabArea() legt ein Array von ScArea-Zeigern an, 485 // welche ebenfalls dynamisch erzeugt wurden. 486 // Diese Objekte muessen hier abgeraeumt werden. 487 488 for ( sal_uInt16 i=0; i<nAreaCount; i++ ) 489 { 490 String aNewArea; 491 492 if ( ppAreas[i] ) 493 { 494 const ScArea& rArea = *(ppAreas[i]); 495 ScRange( rArea.nColStart, rArea.nRowStart, rArea.nTab, 496 rArea.nColEnd, rArea.nRowEnd, rArea.nTab 497 ).Format( aNewArea, SCR_ABS_3D, pDoc, eConv ); 498 499 if ( aLbConsAreas.GetEntryPos( aNewArea ) 500 == LISTBOX_ENTRY_NOTFOUND ) 501 { 502 aLbConsAreas.InsertEntry( aNewArea ); 503 } 504 delete ppAreas[i]; 505 } 506 } 507 delete [] ppAreas; 508 } 509 else if ( VerifyEdit( &aEdDataArea ) ) 510 { 511 String aNewArea( aEdDataArea.GetText() ); 512 513 if ( aLbConsAreas.GetEntryPos( aNewArea ) == LISTBOX_ENTRY_NOTFOUND ) 514 aLbConsAreas.InsertEntry( aNewArea ); 515 else 516 INFOBOX( STR_AREA_ALREADY_INSERTED ); 517 } 518 else 519 { 520 INFOBOX( STR_INVALID_TABREF ); 521 aEdDataArea.GrabFocus(); 522 } 523 } 524 } 525 else if ( pBtn == &aBtnRemove ) 526 { 527 while ( aLbConsAreas.GetSelectEntryCount() ) 528 aLbConsAreas.RemoveEntry( aLbConsAreas.GetSelectEntryPos() ); 529 aBtnRemove.Disable(); 530 } 531 return 0; 532 } 533 534 535 //---------------------------------------------------------------------------- 536 537 IMPL_LINK( ScConsolidateDlg, SelectHdl, ListBox*, pLb ) 538 { 539 if ( pLb == &aLbConsAreas ) 540 { 541 if ( aLbConsAreas.GetSelectEntryCount() > 0 ) 542 aBtnRemove.Enable(); 543 else 544 aBtnRemove.Disable(); 545 } 546 else if ( (pLb == &aLbDataArea) || (pLb == &aLbDestArea) ) 547 { 548 Edit* pEd = (pLb == &aLbDataArea) ? &aEdDataArea : &aEdDestArea; 549 sal_uInt16 nSelPos = pLb->GetSelectEntryPos(); 550 551 if ( pRangeUtil 552 && (nSelPos > 0) 553 && (nAreaDataCount > 0) 554 && (pAreaData != NULL) ) 555 { 556 if ( nSelPos <= nAreaDataCount ) 557 { 558 String aString( pAreaData[nSelPos-1].aStrArea ); 559 560 if ( pLb == &aLbDestArea ) 561 pRangeUtil->CutPosString( aString, aString ); 562 563 pEd->SetText( aString ); 564 565 if ( pEd == &aEdDataArea ) 566 aBtnAdd.Enable(); 567 } 568 } 569 else 570 { 571 pEd->SetText( EMPTY_STRING ); 572 if ( pEd == &aEdDataArea ) 573 aBtnAdd.Enable(); 574 } 575 } 576 return 0; 577 } 578 579 580 //---------------------------------------------------------------------------- 581 582 IMPL_LINK( ScConsolidateDlg, ModifyHdl, formula::RefEdit*, pEd ) 583 { 584 if ( pEd == &aEdDataArea ) 585 { 586 String aAreaStr( pEd->GetText() ); 587 if ( aAreaStr.Len() > 0 ) 588 { 589 aBtnAdd.Enable(); 590 } 591 else 592 aBtnAdd.Disable(); 593 } 594 else if ( pEd == &aEdDestArea ) 595 { 596 aLbDestArea.SelectEntryPos(0); 597 } 598 return 0; 599 } 600 601 602 //---------------------------------------------------------------------------- 603 // Verallgemeinern!!! : 604 // Resource der ListBox und diese beiden Umrechnungsmethoden gibt es 605 // auch noch in tpsubt bzw. ueberall, wo StarCalc-Funktionen 606 // auswaehlbar sind. 607 608 ScSubTotalFunc ScConsolidateDlg::LbPosToFunc( sal_uInt16 nPos ) 609 { 610 switch ( nPos ) 611 { 612 case 2: return SUBTOTAL_FUNC_AVE; 613 case 6: return SUBTOTAL_FUNC_CNT; 614 case 1: return SUBTOTAL_FUNC_CNT2; 615 case 3: return SUBTOTAL_FUNC_MAX; 616 case 4: return SUBTOTAL_FUNC_MIN; 617 case 5: return SUBTOTAL_FUNC_PROD; 618 case 7: return SUBTOTAL_FUNC_STD; 619 case 8: return SUBTOTAL_FUNC_STDP; 620 case 9: return SUBTOTAL_FUNC_VAR; 621 case 10: return SUBTOTAL_FUNC_VARP; 622 case 0: 623 default: 624 return SUBTOTAL_FUNC_SUM; 625 } 626 } 627 628 629 //---------------------------------------------------------------------------- 630 631 sal_uInt16 ScConsolidateDlg::FuncToLbPos( ScSubTotalFunc eFunc ) 632 { 633 switch ( eFunc ) 634 { 635 case SUBTOTAL_FUNC_AVE: return 2; 636 case SUBTOTAL_FUNC_CNT: return 6; 637 case SUBTOTAL_FUNC_CNT2: return 1; 638 case SUBTOTAL_FUNC_MAX: return 3; 639 case SUBTOTAL_FUNC_MIN: return 4; 640 case SUBTOTAL_FUNC_PROD: return 5; 641 case SUBTOTAL_FUNC_STD: return 7; 642 case SUBTOTAL_FUNC_STDP: return 8; 643 case SUBTOTAL_FUNC_VAR: return 9; 644 case SUBTOTAL_FUNC_VARP: return 10; 645 case SUBTOTAL_FUNC_NONE: 646 case SUBTOTAL_FUNC_SUM: 647 default: 648 return 0; 649 } 650 } 651 652