bump product version to 4.1.6.2
[LibreOffice.git] / sc / source / ui / unoobj / funcuno.cxx
blob7c57ee919c7fb91ae9ab53212a8ec048f023dd69
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <sfx2/app.hxx>
21 #include <svl/itemprop.hxx>
23 #include "scitems.hxx"
24 #include "funcuno.hxx"
25 #include "miscuno.hxx"
26 #include "cellsuno.hxx"
27 #include "scdll.hxx"
28 #include "document.hxx"
29 #include "compiler.hxx"
30 #include "formula/errorcodes.hxx"
31 #include "callform.hxx"
32 #include "addincol.hxx"
33 #include "rangeseq.hxx"
34 #include "formulacell.hxx"
35 #include "docoptio.hxx"
36 #include "optuno.hxx"
37 #include <docuno.hxx>
38 // for lcl_CopyData:
39 #include "markdata.hxx"
40 #include "patattr.hxx"
41 #include "docpool.hxx"
42 #include "attrib.hxx"
43 #include "clipparam.hxx"
44 #include "dociter.hxx"
45 #include "stringutil.hxx"
46 #include "tokenarray.hxx"
48 using namespace com::sun::star;
50 //------------------------------------------------------------------------
52 // registered as implementation for service FunctionAccess,
53 // also supports service SpreadsheetDocumentSettings (to set null date etc.)
55 #define SCFUNCTIONACCESS_SERVICE "com.sun.star.sheet.FunctionAccess"
56 #define SCDOCSETTINGS_SERVICE "com.sun.star.sheet.SpreadsheetDocumentSettings"
58 //------------------------------------------------------------------------
60 // helper to use cached document if not in use, temporary document otherwise
62 class ScTempDocSource
64 private:
65 ScTempDocCache& rCache;
66 ScDocument* pTempDoc;
68 static ScDocument* CreateDocument(); // create and initialize doc
70 public:
71 ScTempDocSource( ScTempDocCache& rDocCache );
72 ~ScTempDocSource();
74 ScDocument* GetDocument();
77 //------------------------------------------------------------------------
79 ScDocument* ScTempDocSource::CreateDocument()
81 ScDocument* pDoc = new ScDocument; // SCDOCMODE_DOCUMENT
82 pDoc->MakeTable( 0 );
83 return pDoc;
86 ScTempDocSource::ScTempDocSource( ScTempDocCache& rDocCache ) :
87 rCache( rDocCache ),
88 pTempDoc( NULL )
90 if ( rCache.IsInUse() )
91 pTempDoc = CreateDocument();
92 else
94 rCache.SetInUse( sal_True );
95 if ( !rCache.GetDocument() )
96 rCache.SetDocument( CreateDocument() );
100 ScTempDocSource::~ScTempDocSource()
102 if ( pTempDoc )
103 delete pTempDoc;
104 else
105 rCache.SetInUse( false );
108 ScDocument* ScTempDocSource::GetDocument()
110 if ( pTempDoc )
111 return pTempDoc;
112 else
113 return rCache.GetDocument();
116 //------------------------------------------------------------------------
118 ScTempDocCache::ScTempDocCache() :
119 pDoc( NULL ),
120 bInUse( false )
124 ScTempDocCache::~ScTempDocCache()
126 OSL_ENSURE( !bInUse, "ScTempDocCache dtor: bInUse" );
127 delete pDoc;
130 void ScTempDocCache::SetDocument( ScDocument* pNew )
132 OSL_ENSURE( !pDoc, "ScTempDocCache::SetDocument: already set" );
133 pDoc = pNew;
136 void ScTempDocCache::Clear()
138 OSL_ENSURE( !bInUse, "ScTempDocCache::Clear: bInUse" );
139 delete pDoc;
140 pDoc = NULL;
143 //------------------------------------------------------------------------
145 // copy results from one document into another
146 //! merge this with ScAreaLink::Refresh
147 //! copy directly without a clipboard document?
149 static sal_Bool lcl_CopyData( ScDocument* pSrcDoc, const ScRange& rSrcRange,
150 ScDocument* pDestDoc, const ScAddress& rDestPos )
152 SCTAB nSrcTab = rSrcRange.aStart.Tab();
153 SCTAB nDestTab = rDestPos.Tab();
155 ScRange aNewRange( rDestPos, ScAddress(
156 rSrcRange.aEnd.Col() - rSrcRange.aStart.Col() + rDestPos.Col(),
157 rSrcRange.aEnd.Row() - rSrcRange.aStart.Row() + rDestPos.Row(),
158 nDestTab ) );
160 ScDocument* pClipDoc = new ScDocument( SCDOCMODE_CLIP );
161 ScMarkData aSourceMark;
162 aSourceMark.SelectOneTable( nSrcTab ); // for CopyToClip
163 aSourceMark.SetMarkArea( rSrcRange );
164 ScClipParam aClipParam(rSrcRange, false);
165 pSrcDoc->CopyToClip(aClipParam, pClipDoc, &aSourceMark, false);
167 if ( pClipDoc->HasAttrib( 0,0,nSrcTab, MAXCOL,MAXROW,nSrcTab,
168 HASATTR_MERGED | HASATTR_OVERLAPPED ) )
170 ScPatternAttr aPattern( pSrcDoc->GetPool() );
171 aPattern.GetItemSet().Put( ScMergeAttr() ); // Defaults
172 aPattern.GetItemSet().Put( ScMergeFlagAttr() );
173 pClipDoc->ApplyPatternAreaTab( 0,0, MAXCOL,MAXROW, nSrcTab, aPattern );
176 ScMarkData aDestMark;
177 aDestMark.SelectOneTable( nDestTab );
178 aDestMark.SetMarkArea( aNewRange );
179 pDestDoc->CopyFromClip( aNewRange, aDestMark, IDF_ALL & ~IDF_FORMULA, NULL, pClipDoc, false );
181 delete pClipDoc;
182 return sal_True;
185 //------------------------------------------------------------------------
187 ScFunctionAccess::ScFunctionAccess() :
188 pOptions( NULL ),
189 aPropertyMap( ScDocOptionsHelper::GetPropertyMap() ),
190 mbArray( true ), // default according to behaviour of older Office versions
191 mbValid( true )
193 StartListening( *SFX_APP() ); // for SFX_HINT_DEINITIALIZING
196 ScFunctionAccess::~ScFunctionAccess()
198 delete pOptions;
201 void ScFunctionAccess::Notify( SfxBroadcaster&, const SfxHint& rHint )
203 if ( rHint.ISA(SfxSimpleHint) &&
204 ((SfxSimpleHint&)rHint).GetId() == SFX_HINT_DEINITIALIZING )
206 // document must not be used anymore
207 aDocCache.Clear();
208 mbValid = false;
212 // stuff for exService_...
214 uno::Reference<uno::XInterface> SAL_CALL ScFunctionAccess_CreateInstance(
215 const uno::Reference<lang::XMultiServiceFactory>& )
217 SolarMutexGuard aGuard;
218 ScDLL::Init();
219 static uno::Reference< uno::XInterface > xInst((::cppu::OWeakObject*) new ScFunctionAccess);
220 return xInst;
223 OUString ScFunctionAccess::getImplementationName_Static()
225 return OUString( "stardiv.StarCalc.ScFunctionAccess" );
228 uno::Sequence<OUString> ScFunctionAccess::getSupportedServiceNames_Static()
230 uno::Sequence<OUString> aRet(1);
231 OUString* pArray = aRet.getArray();
232 pArray[0] = OUString( SCFUNCTIONACCESS_SERVICE );
233 return aRet;
236 // XServiceInfo
238 OUString SAL_CALL ScFunctionAccess::getImplementationName() throw(uno::RuntimeException)
240 return OUString( "ScFunctionAccess");
243 sal_Bool SAL_CALL ScFunctionAccess::supportsService( const OUString& rServiceName )
244 throw(uno::RuntimeException)
246 String aServiceStr(rServiceName);
247 return aServiceStr.EqualsAscii( SCFUNCTIONACCESS_SERVICE ) ||
248 aServiceStr.EqualsAscii( SCDOCSETTINGS_SERVICE );
251 uno::Sequence<OUString> SAL_CALL ScFunctionAccess::getSupportedServiceNames()
252 throw(uno::RuntimeException)
254 uno::Sequence<OUString> aRet(2);
255 OUString* pArray = aRet.getArray();
256 pArray[0] = OUString( SCFUNCTIONACCESS_SERVICE );
257 pArray[1] = OUString( SCDOCSETTINGS_SERVICE );
258 return aRet;
261 // XPropertySet (document settings)
263 uno::Reference<beans::XPropertySetInfo> SAL_CALL ScFunctionAccess::getPropertySetInfo()
264 throw(uno::RuntimeException)
266 SolarMutexGuard aGuard;
267 static uno::Reference<beans::XPropertySetInfo> aRef(
268 new SfxItemPropertySetInfo( aPropertyMap ));
269 return aRef;
272 void SAL_CALL ScFunctionAccess::setPropertyValue(
273 const OUString& aPropertyName, const uno::Any& aValue )
274 throw(beans::UnknownPropertyException, beans::PropertyVetoException,
275 lang::IllegalArgumentException, lang::WrappedTargetException,
276 uno::RuntimeException)
278 SolarMutexGuard aGuard;
280 if ( aPropertyName == "IsArrayFunction" )
282 if( !(aValue >>= mbArray) )
283 throw lang::IllegalArgumentException();
285 else
287 if ( !pOptions )
288 pOptions = new ScDocOptions();
290 // options aren't initialized from configuration - always get the same default behaviour
292 sal_Bool bDone = ScDocOptionsHelper::setPropertyValue( *pOptions, aPropertyMap, aPropertyName, aValue );
293 if (!bDone)
294 throw beans::UnknownPropertyException();
298 uno::Any SAL_CALL ScFunctionAccess::getPropertyValue( const OUString& aPropertyName )
299 throw(beans::UnknownPropertyException, lang::WrappedTargetException,
300 uno::RuntimeException)
302 SolarMutexGuard aGuard;
304 if ( aPropertyName == "IsArrayFunction" )
305 return uno::Any( mbArray );
307 if ( !pOptions )
308 pOptions = new ScDocOptions();
310 // options aren't initialized from configuration - always get the same default behaviour
312 return ScDocOptionsHelper::getPropertyValue( *pOptions, aPropertyMap, aPropertyName );
315 SC_IMPL_DUMMY_PROPERTY_LISTENER( ScFunctionAccess )
317 // XFunctionAccess
319 static sal_Bool lcl_AddFunctionToken( ScTokenArray& rArray, const OUString& rName,const ScCompiler& rCompiler )
321 // function names are always case-insensitive
322 OUString aUpper = ScGlobal::pCharClass->uppercase(rName);
324 // same options as in ScCompiler::IsOpCode:
325 // 1. built-in function name
327 OpCode eOp = rCompiler.GetEnglishOpCode( aUpper );
328 if ( eOp != ocNone )
330 rArray.AddOpCode( eOp );
331 return true;
334 // 2. old add in functions
336 if (ScGlobal::GetFuncCollection()->findByName(aUpper))
338 rArray.AddExternal(aUpper.getStr());
339 return true;
342 // 3. new (uno) add in functions
344 OUString aIntName =
345 ScGlobal::GetAddInCollection()->FindFunction(aUpper, false);
346 if (!aIntName.isEmpty())
348 rArray.AddExternal(aIntName.getStr()); // international name
349 return true;
352 return false; // no valid function name
355 static void lcl_AddRef( ScTokenArray& rArray, long nStartRow, long nColCount, long nRowCount )
357 ScComplexRefData aRef;
358 aRef.InitFlags();
359 aRef.Ref1.nTab = 0;
360 aRef.Ref2.nTab = 0;
361 aRef.Ref1.nCol = 0;
362 aRef.Ref1.nRow = (SCROW) nStartRow;
363 aRef.Ref2.nCol = (SCCOL) (nColCount - 1);
364 aRef.Ref2.nRow = (SCROW) (nStartRow + nRowCount - 1);
365 rArray.AddDoubleReference(aRef);
368 class SimpleVisitor
370 protected:
371 bool mbArgError;
372 ScDocument* mpDoc;
373 public:
374 SimpleVisitor( ScDocument* pDoc ) : mbArgError( false ), mpDoc( pDoc ) {}
375 // could possibly just get away with JUST the following overload
376 // 1) virtual void visitElem( long& nCol, long& nRow, const double& elem )
377 // 2) virtual void visitElem( long& nCol, long& nRow, const OUString& elem )
378 // 3) virtual void visitElem( long& nCol, long& nRow, const uno::Any& elem )
379 // the other types methods are here just to reflect the orig code and for
380 // completeness.
382 void visitElem( long nCol, long nRow, const sal_Int16& elem )
384 mpDoc->SetValue( (SCCOL) nCol, (SCROW) nRow, 0, elem );
386 void visitElem( long nCol, long nRow, const sal_Int32& elem )
388 mpDoc->SetValue( (SCCOL) nCol, (SCROW) nRow, 0, elem );
390 void visitElem( long nCol, long nRow, const double& elem )
392 mpDoc->SetValue( (SCCOL) nCol, (SCROW) nRow, 0, elem );
394 void visitElem( long nCol, long nRow, const OUString& elem )
396 if (!elem.isEmpty())
398 ScSetStringParam aParam;
399 aParam.setTextInput();
400 mpDoc->SetString(ScAddress(nCol,nRow,0), elem, &aParam);
403 void visitElem( long nCol, long nRow, const uno::Any& rElement )
405 uno::TypeClass eElemClass = rElement.getValueTypeClass();
406 if ( eElemClass == uno::TypeClass_VOID )
408 // leave empty
410 else if ( eElemClass == uno::TypeClass_BYTE ||
411 eElemClass == uno::TypeClass_SHORT ||
412 eElemClass == uno::TypeClass_UNSIGNED_SHORT ||
413 eElemClass == uno::TypeClass_LONG ||
414 eElemClass == uno::TypeClass_UNSIGNED_LONG ||
415 eElemClass == uno::TypeClass_FLOAT ||
416 eElemClass == uno::TypeClass_DOUBLE )
418 // accept integer types because Basic passes a floating point
419 // variable as byte, short or long if it's an integer number.
420 double fVal(0.0);
421 rElement >>= fVal;
422 visitElem( nCol, nRow, fVal );
424 else if ( eElemClass == uno::TypeClass_STRING )
426 OUString aUStr;
427 rElement >>= aUStr;
428 visitElem( nCol, nRow, aUStr );
430 else
431 mbArgError = true;
433 bool hasArgError() const { return mbArgError; }
436 template< class seq >
437 class SequencesContainer
439 uno::Sequence< uno::Sequence< seq > > maSeq;
441 long& mrDocRow;
442 bool mbOverflow;
443 bool mbArgError;
444 ScDocument* mpDoc;
445 ScTokenArray& mrTokenArr;
447 public:
448 SequencesContainer( const uno::Any& rArg, ScTokenArray& rTokenArr, long& rDocRow, ScDocument* pDoc ) :
449 mrDocRow( rDocRow ), mbOverflow(false), mbArgError(false), mpDoc( pDoc ), mrTokenArr( rTokenArr )
451 rArg >>= maSeq;
454 void process()
456 SimpleVisitor aVisitor(mpDoc);
457 long nStartRow = mrDocRow;
458 long nRowCount = maSeq.getLength();
459 long nMaxColCount = 0;
460 const uno::Sequence< seq >* pRowArr = maSeq.getConstArray();
461 for ( long nRow=0; nRow<nRowCount; nRow++ )
463 long nColCount = pRowArr[nRow].getLength();
464 if ( nColCount > nMaxColCount )
465 nMaxColCount = nColCount;
466 const seq* pColArr = pRowArr[nRow].getConstArray();
467 for (long nCol=0; nCol<nColCount; nCol++)
468 if ( nCol <= MAXCOL && mrDocRow <= MAXROW )
469 aVisitor.visitElem( nCol, mrDocRow, pColArr[ nCol ] );
470 else
471 mbOverflow=true;
472 mrDocRow++;
474 mbArgError = aVisitor.hasArgError();
475 if ( nRowCount && nMaxColCount && !mbOverflow )
476 lcl_AddRef( mrTokenArr, nStartRow, nMaxColCount, nRowCount );
478 bool getOverflow() const { return mbOverflow; }
479 bool getArgError() const { return mbArgError; }
482 template <class T>
483 class ArrayOfArrayProc
485 public:
486 static void processSequences( ScDocument* pDoc, const uno::Any& rArg, ScTokenArray& rTokenArr,
487 long& rDocRow, sal_Bool& rArgErr, sal_Bool& rOverflow )
489 SequencesContainer< T > aContainer( rArg, rTokenArr, rDocRow, pDoc );
490 aContainer.process();
491 rArgErr = aContainer.getArgError();
492 rOverflow = aContainer.getOverflow();
496 uno::Any SAL_CALL ScFunctionAccess::callFunction( const OUString& aName,
497 const uno::Sequence<uno::Any>& aArguments )
498 throw(container::NoSuchElementException, lang::IllegalArgumentException,
499 uno::RuntimeException)
501 SolarMutexGuard aGuard;
503 if (!mbValid)
504 throw uno::RuntimeException();
506 // use cached document if not in use, temporary document otherwise
507 // (deleted in ScTempDocSource dtor)
508 ScTempDocSource aSource( aDocCache );
509 ScDocument* pDoc = aSource.GetDocument();
510 const static SCTAB nTempSheet = 1;
511 // Create an extra tab to contain the Function Cell
512 // this will allow full rows to be used.
513 if ( !pDoc->HasTable( nTempSheet ) )
514 pDoc->MakeTable( nTempSheet );
516 /// TODO: check
517 ScAddress aAdr;
518 ScCompiler aCompiler(pDoc,aAdr);
519 aCompiler.SetGrammar(pDoc->GetGrammar());
522 // find function
525 ScTokenArray aTokenArr;
526 if ( !lcl_AddFunctionToken( aTokenArr, aName,aCompiler ) )
528 // function not found
529 throw container::NoSuchElementException();
533 // set options (null date, etc.)
536 if ( pOptions )
537 pDoc->SetDocOptions( *pOptions );
540 // add arguments to token array
543 sal_Bool bArgErr = false;
544 sal_Bool bOverflow = false;
545 long nDocRow = 0;
546 long nArgCount = aArguments.getLength();
547 const uno::Any* pArgArr = aArguments.getConstArray();
549 aTokenArr.AddOpCode(ocOpen);
550 for (long nPos=0; nPos<nArgCount; nPos++)
552 if ( nPos > 0 )
553 aTokenArr.AddOpCode(ocSep);
555 const uno::Any& rArg = pArgArr[nPos];
557 uno::TypeClass eClass = rArg.getValueTypeClass();
558 uno::Type aType = rArg.getValueType();
559 if ( eClass == uno::TypeClass_BYTE ||
560 eClass == uno::TypeClass_BOOLEAN ||
561 eClass == uno::TypeClass_SHORT ||
562 eClass == uno::TypeClass_UNSIGNED_SHORT ||
563 eClass == uno::TypeClass_LONG ||
564 eClass == uno::TypeClass_UNSIGNED_LONG ||
565 eClass == uno::TypeClass_FLOAT ||
566 eClass == uno::TypeClass_DOUBLE )
568 // accept integer types because Basic passes a floating point
569 // variable as byte, short or long if it's an integer number.
570 double fVal = 0;
571 rArg >>= fVal;
572 aTokenArr.AddDouble( fVal );
574 else if ( eClass == uno::TypeClass_STRING )
576 OUString aUStr;
577 rArg >>= aUStr;
578 String aStr( aUStr );
579 aTokenArr.AddString( aStr.GetBuffer() );
581 else if ( aType.equals( getCppuType( (uno::Sequence< uno::Sequence<sal_Int16> > *)0 ) ) )
583 ArrayOfArrayProc<sal_Int16>::processSequences( pDoc, rArg, aTokenArr, nDocRow, bArgErr, bOverflow );
585 else if ( aType.equals( getCppuType( (uno::Sequence< uno::Sequence<sal_Int32> > *)0 ) ) )
587 ArrayOfArrayProc<sal_Int32>::processSequences( pDoc, rArg, aTokenArr, nDocRow, bArgErr, bOverflow );
589 else if ( aType.equals( getCppuType( (uno::Sequence< uno::Sequence<double> > *)0 ) ) )
591 ArrayOfArrayProc<double>::processSequences( pDoc, rArg, aTokenArr, nDocRow, bArgErr, bOverflow );
593 else if ( aType.equals( getCppuType( (uno::Sequence< uno::Sequence<OUString> > *)0 ) ) )
595 ArrayOfArrayProc<OUString>::processSequences( pDoc, rArg, aTokenArr, nDocRow, bArgErr, bOverflow );
597 else if ( aType.equals( getCppuType( (uno::Sequence< uno::Sequence<uno::Any> > *)0 ) ) )
599 ArrayOfArrayProc<uno::Any>::processSequences( pDoc, rArg, aTokenArr, nDocRow, bArgErr, bOverflow );
601 else if ( aType.equals( getCppuType( (uno::Reference<table::XCellRange>*)0 ) ) )
603 // currently, only our own cell ranges are supported
605 uno::Reference<table::XCellRange> xRange(rArg, uno::UNO_QUERY);
606 ScCellRangesBase* pImpl = ScCellRangesBase::getImplementation( xRange );
607 if ( pImpl )
609 ScDocument* pSrcDoc = pImpl->GetDocument();
610 const ScRangeList& rRanges = pImpl->GetRangeList();
611 if ( pSrcDoc && rRanges.size() == 1 )
613 ScRange aSrcRange = *rRanges[ 0 ];
615 long nStartRow = nDocRow;
616 long nColCount = aSrcRange.aEnd.Col() - aSrcRange.aStart.Col() + 1;
617 long nRowCount = aSrcRange.aEnd.Row() - aSrcRange.aStart.Row() + 1;
619 if ( nStartRow + nRowCount > MAXROWCOUNT )
620 bOverflow = sal_True;
621 else
623 // copy data
624 if ( !lcl_CopyData( pSrcDoc, aSrcRange, pDoc, ScAddress( 0, (SCROW)nDocRow, 0 ) ) )
625 bOverflow = sal_True;
628 nDocRow += nRowCount;
629 if ( !bOverflow )
630 lcl_AddRef( aTokenArr, nStartRow, nColCount, nRowCount );
632 else
633 bArgErr = sal_True;
635 else
636 bArgErr = sal_True;
638 else
639 bArgErr = sal_True; // invalid type
641 aTokenArr.AddOpCode(ocClose);
642 aTokenArr.AddOpCode(ocStop);
645 // execute formula
648 uno::Any aRet;
649 if ( !bArgErr && !bOverflow && nDocRow <= MAXROWCOUNT )
651 ScAddress aFormulaPos( 0, 0, nTempSheet );
652 // GRAM_PODF_A1 doesn't really matter for the token array but fits with
653 // other API compatibility grammars.
654 ScFormulaCell* pFormula = new ScFormulaCell( pDoc, aFormulaPos,
655 &aTokenArr, formula::FormulaGrammar::GRAM_PODF_A1, (sal_uInt8)(mbArray ? MM_FORMULA : MM_NONE) );
656 pDoc->SetFormulaCell(aFormulaPos, pFormula);
658 // call GetMatrix before GetErrCode because GetMatrix always recalculates
659 // if there is no matrix result
661 const ScMatrix* pMat = mbArray ? pFormula->GetMatrix() : 0;
662 sal_uInt16 nErrCode = pFormula->GetErrCode();
663 if ( nErrCode == 0 )
665 if ( pMat )
667 // array result
668 ScRangeToSequence::FillMixedArray( aRet, pMat );
670 else if ( pFormula->IsValue() )
672 // numeric value
673 aRet <<= (double) pFormula->GetValue();
675 else
677 // string result
678 OUString aStrVal = pFormula->GetString();
679 aRet <<= aStrVal;
682 else if ( nErrCode == NOTAVAILABLE )
684 // #N/A: leave result empty, no exception
686 else
688 // any other error: IllegalArgumentException
689 bArgErr = sal_True;
692 pDoc->DeleteAreaTab( 0, 0, MAXCOL, MAXROW, 0, IDF_ALL );
693 pDoc->DeleteAreaTab( 0, 0, 0, 0, nTempSheet, IDF_ALL );
696 if (bOverflow)
697 throw uno::RuntimeException();
699 if (bArgErr)
700 throw lang::IllegalArgumentException();
702 return aRet;
706 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */