diff options
author | Noel Power <noel.power@novell.com> | 2010-10-06 10:15:43 +0100 |
---|---|---|
committer | Noel Power <noel.power@novell.com> | 2010-10-06 10:15:43 +0100 |
commit | f13fd7b138caee676cf5dbeae3474e4a4b0b177a (patch) | |
tree | 58bbab934d3fd26a8fd886a2dbc52b5a2d283092 /sc/source/core | |
parent | 44231089eeda805727f6c7143729612059891b02 (diff) |
initial commit for vba blob ( not including container_control stuff )
Diffstat (limited to 'sc/source/core')
-rw-r--r-- | sc/source/core/data/cell.cxx | 46 | ||||
-rw-r--r-- | sc/source/core/data/column3.cxx | 15 | ||||
-rw-r--r-- | sc/source/core/data/documen2.cxx | 2 | ||||
-rw-r--r-- | sc/source/core/data/documen8.cxx | 8 | ||||
-rw-r--r-- | sc/source/core/data/document.cxx | 78 | ||||
-rw-r--r-- | sc/source/core/inc/interpre.hxx | 11 | ||||
-rw-r--r-- | sc/source/core/tool/address.cxx | 2 | ||||
-rw-r--r-- | sc/source/core/tool/appoptio.cxx | 4 | ||||
-rw-r--r-- | sc/source/core/tool/interpr1.cxx | 13 | ||||
-rw-r--r-- | sc/source/core/tool/interpr4.cxx | 134 | ||||
-rw-r--r-- | sc/source/core/tool/interpr5.cxx | 5 | ||||
-rw-r--r-- | sc/source/core/tool/rangelst.cxx | 19 |
12 files changed, 307 insertions, 30 deletions
diff --git a/sc/source/core/data/cell.cxx b/sc/source/core/data/cell.cxx index d12439bbad4f..72874b1b4995 100644 --- a/sc/source/core/data/cell.cxx +++ b/sc/source/core/data/cell.cxx @@ -51,6 +51,7 @@ #include "recursionhelper.hxx" #include "postit.hxx" #include "externalrefmgr.hxx" +#include "macromgr.hxx" #include <editeng/editobj.hxx> #include <svl/intitem.hxx> #include <editeng/flditem.hxx> @@ -819,6 +820,8 @@ ScFormulaCell::ScFormulaCell( const ScFormulaCell& rCell, ScDocument& rDoc, cons ScFormulaCell::~ScFormulaCell() { pDocument->RemoveFromFormulaTree( this ); + if (pCode->HasOpCode(ocMacro)) + pDocument->GetMacroManager()->RemoveDependentCell(this); if (pDocument->HasExternalRefManager()) pDocument->GetExternalRefManager()->removeRefCell(this); @@ -1742,6 +1745,36 @@ void ScFormulaCell::InterpretTail( ScInterpretTailParameter eTailParam ) // Reschedule verlangsamt das ganze erheblich, nur bei Prozentaenderung ausfuehren ScProgress::GetInterpretProgress()->SetStateCountDownOnPercent( pDocument->GetFormulaCodeInTree()/MIN_NO_CODES_PER_PROGRESS_UPDATE ); + + switch (p->GetVolatileType()) + { + case ScInterpreter::VOLATILE: + // Volatile via built-in volatile functions. No actions needed. + break; + case ScInterpreter::VOLATILE_MACRO: + // The formula contains a volatile macro. + pCode->SetRecalcModeAlways(); + pDocument->PutInFormulaTree(this); + StartListeningTo(pDocument); + break; + case ScInterpreter::NOT_VOLATILE: + if (pCode->IsRecalcModeAlways()) + { + // The formula was previously volatile, but no more. + EndListeningTo(pDocument); + pCode->SetRecalcModeNormal(); + } + else + { + // non-volatile formula. End listening to the area in case + // it's listening due to macro module change. + pDocument->EndListeningArea(BCA_LISTEN_ALWAYS, this); + } + pDocument->RemoveFromFormulaTree(this); + break; + default: + ; + } } else { @@ -1809,7 +1842,7 @@ void __EXPORT ScFormulaCell::Notify( SvtBroadcaster&, const SfxHint& rHint) else { bForceTrack = !bDirty; - bDirty = TRUE; + SetDirtyVar(); } // #35962# Don't remove from FormulaTree to put in FormulaTrack to // put in FormulaTree again and again, only if necessary. @@ -1832,7 +1865,7 @@ void ScFormulaCell::SetDirty() if ( !IsInChangeTrack() ) { if ( pDocument->GetHardRecalcState() ) - bDirty = TRUE; + SetDirtyVar(); else { // Mehrfach-FormulaTracking in Load und in CompileAll @@ -1841,7 +1874,7 @@ void ScFormulaCell::SetDirty() // setzen, z.B. in CompileTokenArray if ( !bDirty || !pDocument->IsInFormulaTree( this ) ) { - bDirty = TRUE; + SetDirtyVar(); pDocument->AppendToFormulaTrack( this ); pDocument->TrackFormulas(); } @@ -1852,6 +1885,13 @@ void ScFormulaCell::SetDirty() } } +void ScFormulaCell::SetDirtyVar() +{ + bDirty = TRUE; + // mark the sheet of this cell to be calculated + //#FIXME do we need to revert this remnant of old fake vba events? pDocument->AddCalculateTable( aPos.Tab() ); +} + void ScFormulaCell::SetDirtyAfterLoad() { bDirty = TRUE; diff --git a/sc/source/core/data/column3.cxx b/sc/source/core/data/column3.cxx index bf437cf62ccd..bb38f634940e 100644 --- a/sc/source/core/data/column3.cxx +++ b/sc/source/core/data/column3.cxx @@ -829,8 +829,10 @@ ScBaseCell* ScColumn::CloneCell(SCSIZE nIndex, USHORT nFlags, ScDocument& rDestD bool bCloneValue = (nFlags & IDF_VALUE) != 0; bool bCloneDateTime = (nFlags & IDF_DATETIME) != 0; bool bCloneString = (nFlags & IDF_STRING) != 0; + bool bCloneSpecialBoolean = (nFlags & IDF_SPECIAL_BOOLEAN) != 0; bool bCloneFormula = (nFlags & IDF_FORMULA) != 0; bool bCloneNote = (nFlags & IDF_NOTE) != 0; + bool bForceFormula = false; ScBaseCell* pNew = 0; ScBaseCell& rSource = *pItems[nIndex].pCell; @@ -854,7 +856,18 @@ ScBaseCell* ScColumn::CloneCell(SCSIZE nIndex, USHORT nFlags, ScDocument& rDestD break; case CELLTYPE_FORMULA: - if (bCloneFormula) + if ( bCloneSpecialBoolean ) + { + ScFormulaCell& rForm = (ScFormulaCell&)rSource; + rtl::OUStringBuffer aBuf; + // #TODO #FIXME do we have a localisation issue here? + rForm.GetFormula( aBuf ); + rtl::OUString aVal( aBuf.makeStringAndClear() ); + if ( aVal.equalsAscii( "=TRUE()" ) + || aVal.equalsAscii( "=FALSE()" ) ) + bForceFormula = true; + } + if (bForceFormula || bCloneFormula) { // note will be cloned below pNew = rSource.CloneWithoutNote( rDestDoc, rDestPos ); diff --git a/sc/source/core/data/documen2.cxx b/sc/source/core/data/documen2.cxx index 8c695c7ee467..55e7173a6d3d 100644 --- a/sc/source/core/data/documen2.cxx +++ b/sc/source/core/data/documen2.cxx @@ -94,6 +94,7 @@ #include "tabprotection.hxx" #include "formulaparserpool.hxx" #include "clipparam.hxx" +#include "macromgr.hxx" using namespace com::sun::star; @@ -156,6 +157,7 @@ ScDocument::ScDocument( ScDocumentMode eMode, pCacheFieldEditEngine( NULL ), pDocProtection( NULL ), mpClipParam( NULL), + mpMacroMgr( NULL ), pExternalRefMgr( NULL ), pViewOptions( NULL ), pDocOptions( NULL ), diff --git a/sc/source/core/data/documen8.cxx b/sc/source/core/data/documen8.cxx index e3c9d251fab7..55a82a6d18d3 100644 --- a/sc/source/core/data/documen8.cxx +++ b/sc/source/core/data/documen8.cxx @@ -93,6 +93,7 @@ #include "globstr.hrc" #include "sc.hrc" #include "charthelper.hxx" +#include "macromgr.hxx" #include "dpobject.hxx" #define GET_SCALEVALUE(set,id) ((const SfxUInt16Item&)(set.Get( id ))).GetValue() @@ -412,6 +413,13 @@ BYTE ScDocument::GetEditTextDirection(SCTAB nTab) const return sal::static_int_cast<BYTE>(eRet); } +ScMacroManager* ScDocument::GetMacroManager() +{ + if (!mpMacroMgr.get()) + mpMacroMgr.reset(new ScMacroManager(this)); + return mpMacroMgr.get(); +} + //------------------------------------------------------------------------ void ScDocument::InvalidateTextWidth( const ScAddress* pAdrFrom, const ScAddress* pAdrTo, diff --git a/sc/source/core/data/document.cxx b/sc/source/core/data/document.cxx index d3630ac451da..467c55aec245 100644 --- a/sc/source/core/data/document.cxx +++ b/sc/source/core/data/document.cxx @@ -97,6 +97,8 @@ #include <map> #include <limits> +using namespace ::com::sun::star; + namespace WritingMode2 = ::com::sun::star::text::WritingMode2; using ::com::sun::star::uno::Sequence; using ::com::sun::star::sheet::TablePageBreakData; @@ -184,6 +186,13 @@ BOOL ScDocument::GetCodeName( SCTAB nTab, String& rName ) const return FALSE; } +NameToNameMap* +ScDocument::GetLocalNameMap( SCTAB& rTab ) +{ + if ( !HasTable( rTab ) ) + return NULL; + return &pTab[rTab]->localNameToGlobalName; +} BOOL ScDocument::GetTable( const String& rName, SCTAB& rTab ) const { @@ -448,6 +457,7 @@ BOOL ScDocument::DeleteTab( SCTAB nTab, ScDocument* pRefUndoDoc ) delete pTab[nTab]; for (i=nTab + 1; i < nTabCount; i++) pTab[i - 1] = pTab[i]; + pTab[nTabCount - 1] = NULL; --nMaxTableNumber; // UpdateBroadcastAreas must be called between UpdateDeleteTab, @@ -1608,6 +1618,40 @@ void ScDocument::CopyToClip(const ScClipParam& rClipParam, pClipDoc->ExtendMerge(aClipRange, true); } +// Copy the content of the Range into clipboard. Adding this method for VBA API: Range.Copy(). +void ScDocument::CopyToClip4VBA(const ScClipParam& rClipParam, ScDocument* pClipDoc, bool bKeepScenarioFlags, bool bIncludeObjects, bool bCloneNoteCaptions) +{ + if ( !bIsClip ) + { + pClipDoc = pClipDoc ? pClipDoc : SC_MOD()->GetClipDoc(); + if ( !pClipDoc ) + { + return; + } + ScRange aClipRange = rClipParam.getWholeRange(); + SCTAB nTab = aClipRange.aStart.Tab(); + pClipDoc->aDocName = aDocName; + pClipDoc->SetClipParam( rClipParam ); + pClipDoc->ResetClip( this, nTab ); + + CopyRangeNamesToClip( pClipDoc, aClipRange, nTab ); + + if ( pTab[nTab] && pClipDoc->pTab[nTab] ) + { + pTab[nTab]->CopyToClip( rClipParam.maRanges, pClipDoc->pTab[nTab], bKeepScenarioFlags, bCloneNoteCaptions ); + if ( pDrawLayer && bIncludeObjects ) + { + // Also copy drawing objects. + Rectangle aObjRect = GetMMRect( aClipRange.aStart.Col(), aClipRange.aStart.Row(), aClipRange.aEnd.Col(), aClipRange.aEnd.Row(), nTab ); + pDrawLayer->CopyToClip( pClipDoc, nTab, aObjRect ); + } + } + + // Make sure to mark overlapped cells. + pClipDoc->ExtendMerge( aClipRange, true ); + } +} + void ScDocument::CopyTabToClip(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, SCTAB nTab, ScDocument* pClipDoc) @@ -1729,6 +1773,31 @@ void ScDocument::CopyRangeNamesToClip(ScDocument* pClipDoc, const ScRange& rClip } } +void ScDocument::CopyRangeNamesToClip(ScDocument* pClipDoc, const ScRange& rClipRange, SCTAB nTab) +{ + // Indexes of named ranges that are used in the copied cells + std::set<USHORT> aUsedNames; + if ( pTab[nTab] && pClipDoc->pTab[nTab] ) + { + pTab[nTab]->FindRangeNamesInUse( rClipRange.aStart.Col(), rClipRange.aStart.Row(), rClipRange.aEnd.Col(), rClipRange.aEnd.Row(), aUsedNames ); + } + + pClipDoc->pRangeName->FreeAll(); + for ( USHORT i = 0; i < pRangeName->GetCount(); i++ ) + { + USHORT nIndex = ((ScRangeData*)((*pRangeName)[i]))->GetIndex(); + bool bInUse = ( aUsedNames.find(nIndex) != aUsedNames.end() ); + if ( bInUse ) + { + ScRangeData* pData = new ScRangeData(*((*pRangeName)[i])); + if ( !pClipDoc->pRangeName->Insert(pData) ) + delete pData; + else + pData->SetIndex(nIndex); + } + } +} + ScDocument::NumFmtMergeHandler::NumFmtMergeHandler(ScDocument* pDoc, ScDocument* pSrcDoc) : mpDoc(pDoc) { @@ -4488,6 +4557,15 @@ BOOL ScDocument::HasSelectedBlockMatrixFragment( SCCOL nStartCol, SCROW nStartRo return !bOk; } +BOOL ScDocument::HasSelectedBlockMatrixFragment( SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow, SCTAB nTab ) const +{ + BOOL bOk = TRUE; + if ( pTab[nTab] && pTab[nTab]->HasBlockMatrixFragment( nStartCol, nStartRow, nEndCol, nEndRow ) ) + { + bOk = FALSE; + } + return !bOk; +} BOOL ScDocument::GetMatrixFormulaRange( const ScAddress& rCellPos, ScRange& rMatrix ) { diff --git a/sc/source/core/inc/interpre.hxx b/sc/source/core/inc/interpre.hxx index edecaadb39f0..44cc257d11d5 100644 --- a/sc/source/core/inc/interpre.hxx +++ b/sc/source/core/inc/interpre.hxx @@ -134,6 +134,15 @@ public: static inline double div( const double& fNumerator, const double& fDenominator ); ScMatrixRef GetNewMat(SCSIZE nC, SCSIZE nR); + + enum VolatileType { + VOLATILE, + VOLATILE_MACRO, + NOT_VOLATILE + }; + + VolatileType GetVolatileType() const; + private: static ScTokenStack* pGlobalStack; static BOOL bGlobalStackInUse; @@ -168,6 +177,8 @@ private: BOOL bCalcAsShown; // precision as shown BOOL bMatrixFormula; // formula cell is a matrix formula + VolatileType meVolaileType; + //---------------------------------Funktionen in interpre.cxx--------- // nMust <= nAct <= nMax ? ok : PushError inline BOOL MustHaveParamCount( short nAct, short nMust ); diff --git a/sc/source/core/tool/address.cxx b/sc/source/core/tool/address.cxx index 462bcd042c86..00bd35c1b1a3 100644 --- a/sc/source/core/tool/address.cxx +++ b/sc/source/core/tool/address.cxx @@ -1367,7 +1367,7 @@ lcl_ScRange_Parse_OOo( ScRange &aRange, const String& r, ScDocument* pDoc, ScAdd } nRes1 = ( ( nRes1 | nRes2 ) & SCA_VALID ) | nRes1 - | ( ( nRes2 & 0x070F ) << 4 ); + | ( ( nRes2 & SCA_BITS ) << 4 ); return nRes1; } diff --git a/sc/source/core/tool/appoptio.cxx b/sc/source/core/tool/appoptio.cxx index 857efd972886..958db9806b13 100644 --- a/sc/source/core/tool/appoptio.cxx +++ b/sc/source/core/tool/appoptio.cxx @@ -82,6 +82,9 @@ ScAppOptions::~ScAppOptions() void ScAppOptions::SetDefaults() { + // Set default tab count for new spreadsheet. + nTabCountInNewSpreadsheet = 3; + if ( ScOptionsUtil::IsMetricSystem() ) eMetric = FUNIT_CM; // default for countries with metric system else @@ -119,6 +122,7 @@ void ScAppOptions::SetDefaults() const ScAppOptions& ScAppOptions::operator=( const ScAppOptions& rCpy ) { + nTabCountInNewSpreadsheet = rCpy.nTabCountInNewSpreadsheet; eMetric = rCpy.eMetric; eZoomType = rCpy.eZoomType; bSynchronizeZoom = rCpy.bSynchronizeZoom; diff --git a/sc/source/core/tool/interpr1.cxx b/sc/source/core/tool/interpr1.cxx index 1e4c02967152..601b0546b869 100644 --- a/sc/source/core/tool/interpr1.cxx +++ b/sc/source/core/tool/interpr1.cxx @@ -71,6 +71,7 @@ #include "rangenam.hxx" #include "compiler.hxx" #include "externalrefmgr.hxx" +#include <basic/sbstar.hxx> #include "doubleref.hxx" #include "queryparam.hxx" @@ -4177,7 +4178,17 @@ void ScInterpreter::ScMatch() } } if ( rEntry.bQueryByString ) - rParam.bRegExp = MayBeRegExp( *rEntry.pStr, pDok ); + { + BOOL bIsVBAMode = FALSE; + if ( pDok ) + bIsVBAMode = pDok->IsInVBAMode(); + + // #TODO handle MSO wildcards + if ( bIsVBAMode ) + rParam.bRegExp = FALSE; + else + rParam.bRegExp = MayBeRegExp( *rEntry.pStr, pDok ); + } if (pMatSrc) // The source data is matrix array. { diff --git a/sc/source/core/tool/interpr4.cxx b/sc/source/core/tool/interpr4.cxx index 47cde7186067..542557cdb171 100644 --- a/sc/source/core/tool/interpr4.cxx +++ b/sc/source/core/tool/interpr4.cxx @@ -33,10 +33,14 @@ #include <sfx2/app.hxx> #include <sfx2/docfile.hxx> #include <sfx2/objsh.hxx> +#include <sfx2/docfilt.hxx> #include <basic/sbmeth.hxx> #include <basic/sbmod.hxx> #include <basic/sbstar.hxx> #include <basic/sbx.hxx> +#include <basic/sbxobj.hxx> +#include <basic/sbuno.hxx> +#include <svl/zforlist.hxx> #include <svl/zforlist.hxx> #include <tools/urlobj.hxx> #include <rtl/logfile.hxx> @@ -45,6 +49,8 @@ #include <signal.h> #include <com/sun/star/table/XCellRange.hpp> +#include <com/sun/star/sheet/XSheetCellRange.hpp> +#include <comphelper/processfactory.hxx> #include "interpre.hxx" #include "global.hxx" @@ -65,6 +71,8 @@ #include "jumpmatrix.hxx" #include "parclass.hxx" #include "externalrefmgr.hxx" +#include "formula/FormulaCompiler.hxx" +#include "macromgr.hxx" #include "doubleref.hxx" #include <math.h> @@ -72,6 +80,8 @@ #include <map> #include <algorithm> #include <functional> +#include <basic/basmgr.hxx> +#include <vbahelper/vbaaccesshelper.hxx> #include <memory> using namespace com::sun::star; @@ -2689,6 +2699,61 @@ void ScInterpreter::ScMissing() PushTempToken( new FormulaMissingToken ); } +uno::Any lcl_getSheetModule( const uno::Reference<table::XCellRange>& xCellRange, ScDocument* pDok ) +{ + uno::Reference< sheet::XSheetCellRange > xSheetRange( xCellRange, uno::UNO_QUERY_THROW ); + uno::Reference< beans::XPropertySet > xProps( xSheetRange->getSpreadsheet(), uno::UNO_QUERY_THROW ); + rtl::OUString sCodeName; + xProps->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("CodeName") ) ) >>= sCodeName; + // #TODO #FIXME ideally we should 'throw' here if we don't get a valid parent, but... it is possible + // to create a module ( and use 'Option VBASupport 1' ) for a calc document, in this scenario there + // are *NO* special document module objects ( of course being able to switch between vba/non vba mode at + // the document in the future could fix this, especially IF the switching of the vba mode takes care to + // create the special document module objects if they don't exist. + BasicManager* pBasMgr = pDok->GetDocumentShell()->GetBasicManager(); + + uno::Reference< uno::XInterface > xIf; + if ( pBasMgr && pBasMgr->GetName().Len() ) + { + String sProj = String( RTL_CONSTASCII_USTRINGPARAM( "Standard" ) ); + if ( pDok->GetDocumentShell()->GetBasicManager()->GetName().Len() ) + sProj = pDok->GetDocumentShell()->GetBasicManager()->GetName(); + StarBASIC* pBasic = pDok->GetDocumentShell()->GetBasicManager()->GetLib( sProj ); + if ( pBasic ) + { + SbModule* pMod = pBasic->FindModule( sCodeName ); + if ( pMod ) + xIf = pMod->GetUnoModule(); + } + } + return uno::makeAny( xIf ); +} + +bool +lcl_setVBARange( ScRange& aRange, ScDocument* pDok, SbxVariable* pPar ) +{ + bool bOk = false; + try + { + uno::Reference< uno::XInterface > xVBARange; + uno::Reference<table::XCellRange> xCellRange = ScCellRangeObj::CreateRangeFromDoc( pDok, aRange ); + uno::Sequence< uno::Any > aArgs(2); + aArgs[0] = lcl_getSheetModule( xCellRange, pDok ); + aArgs[1] = uno::Any( xCellRange ); + xVBARange = ooo::vba::createVBAUnoAPIServiceWithArgs( pDok->GetDocumentShell(), "ooo.vba.excel.Range", aArgs ); + if ( xVBARange.is() ) + { + String sDummy(RTL_CONSTASCII_USTRINGPARAM("A-Range") ); + SbxObjectRef aObj = GetSbUnoObject( sDummy, uno::Any( xVBARange ) ); + SetSbUnoObjectDfltPropName( aObj ); + bOk = pPar->PutObject( aObj ); + } + } + catch( uno::Exception& ) + { + } + return bOk; +} void ScInterpreter::ScMacro() { @@ -2726,8 +2791,11 @@ void ScInterpreter::ScMacro() return; } + bool bVolatileMacro = false; SbMethod* pMethod = (SbMethod*)pVar; + SbModule* pModule = pMethod->GetModule(); + bool bUseVBAObjects = pModule->IsVBACompat(); SbxObject* pObject = pModule->GetParent(); DBG_ASSERT(pObject->IsA(TYPE(StarBASIC)), "Kein Basic gefunden!"); String aMacroStr = pObject->GetName(); @@ -2737,7 +2805,13 @@ void ScInterpreter::ScMacro() aMacroStr += pMethod->GetName(); String aBasicStr; if (pObject->GetParent()) + { aBasicStr = pObject->GetParent()->GetName(); // Dokumentenbasic + const SfxFilter* pFilter = NULL; + SfxMedium* pMedium = pDok->GetDocumentShell()->GetMedium(); + if ( pMedium ) + pFilter = pMedium->GetFilter(); + } else aBasicStr = SFX_APP()->GetName(); // Applikationsbasic @@ -2761,7 +2835,13 @@ void ScInterpreter::ScMacro() { ScAddress aAdr; PopSingleRef( aAdr ); - bOk = SetSbxVariable( pPar, aAdr ); + if ( bUseVBAObjects ) + { + ScRange aRange( aAdr ); + bOk = lcl_setVBARange( aRange, pDok, pPar ); + } + else + bOk = SetSbxVariable( pPar, aAdr ); } break; case svDoubleRef: @@ -2780,24 +2860,32 @@ void ScInterpreter::ScMacro() } else { - SbxDimArrayRef refArray = new SbxDimArray; - refArray->AddDim32( 1, nRow2 - nRow1 + 1 ); - refArray->AddDim32( 1, nCol2 - nCol1 + 1 ); - ScAddress aAdr( nCol1, nRow1, nTab1 ); - for( SCROW nRow = nRow1; bOk && nRow <= nRow2; nRow++ ) + if ( bUseVBAObjects ) { - aAdr.SetRow( nRow ); - INT32 nIdx[ 2 ]; - nIdx[ 0 ] = nRow-nRow1+1; - for( SCCOL nCol = nCol1; bOk && nCol <= nCol2; nCol++ ) + ScRange aRange( nCol1, nRow1, nTab1, nCol2, nRow2, nTab2 ); + bOk = lcl_setVBARange( aRange, pDok, pPar ); + } + else + { + SbxDimArrayRef refArray = new SbxDimArray; + refArray->AddDim32( 1, nRow2 - nRow1 + 1 ); + refArray->AddDim32( 1, nCol2 - nCol1 + 1 ); + ScAddress aAdr( nCol1, nRow1, nTab1 ); + for( SCROW nRow = nRow1; bOk && nRow <= nRow2; nRow++ ) { - aAdr.SetCol( nCol ); - nIdx[ 1 ] = nCol-nCol1+1; - SbxVariable* p = refArray->Get32( nIdx ); - bOk = SetSbxVariable( p, aAdr ); + aAdr.SetRow( nRow ); + INT32 nIdx[ 2 ]; + nIdx[ 0 ] = nRow-nRow1+1; + for( SCCOL nCol = nCol1; bOk && nCol <= nCol2; nCol++ ) + { + aAdr.SetCol( nCol ); + nIdx[ 1 ] = nCol-nCol1+1; + SbxVariable* p = refArray->Get32( nIdx ); + bOk = SetSbxVariable( p, aAdr ); + } } + pPar->PutObject( refArray ); } - pPar->PutObject( refArray ); } } break; @@ -2845,6 +2933,13 @@ void ScInterpreter::ScMacro() pDok->DecMacroInterpretLevel(); pDok->UnlockTable( aPos.Tab() ); + ScMacroManager* pMacroMgr = pDok->GetMacroManager(); + if (pMacroMgr) + { + bVolatileMacro = pMacroMgr->GetUserFuncVolatile( pMethod->GetName() ); + pMacroMgr->AddDependentCell(pModule->GetName(), pMyFormulaCell); + } + SbxDataType eResType = refRes->GetType(); if( pVar->GetError() ) SetError( errNoValue); @@ -2916,6 +3011,9 @@ void ScInterpreter::ScMacro() } pSfxApp->LeaveBasicCall(); + + if (bVolatileMacro && meVolaileType == NOT_VOLATILE) + meVolaileType = VOLATILE_MACRO; } @@ -3288,7 +3386,8 @@ ScInterpreter::ScInterpreter( ScFormulaCell* pCell, ScDocument* pDoc, pMyFormulaCell( pCell ), pFormatter( pDoc->GetFormatTable() ), mnStringNoValueError( errNoValue), - bCalcAsShown( pDoc->GetDocOptions().IsCalcAsShown() ) + bCalcAsShown( pDoc->GetDocOptions().IsCalcAsShown() ), + meVolaileType(NOT_VOLATILE) { RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScTTT" ); // pStack = new ScToken*[ MAXSTACK ]; @@ -3735,6 +3834,9 @@ StackVar ScInterpreter::Interpret() continue; // while( ( pCur = aCode.Next() ) != NULL ... } + if (FormulaCompiler::IsOpCodeVolatile(eOp)) + meVolaileType = VOLATILE; + // Remember result matrix in case it could be reused. if (pTokenMatrixMap && sp && GetStackType() == svMatrix) pTokenMatrixMap->insert( ScTokenMatrixMap::value_type( pCur, diff --git a/sc/source/core/tool/interpr5.cxx b/sc/source/core/tool/interpr5.cxx index 73794cf15b2d..a51b4b256712 100644 --- a/sc/source/core/tool/interpr5.cxx +++ b/sc/source/core/tool/interpr5.cxx @@ -324,6 +324,11 @@ ScMatrixRef ScInterpreter::GetNewMat(SCSIZE nC, SCSIZE nR) return pMat; } +ScInterpreter::VolatileType ScInterpreter::GetVolatileType() const +{ + return meVolaileType; +} + ScMatrixRef ScInterpreter::CreateMatrixFromDoubleRef( const FormulaToken* pToken, SCCOL nCol1, SCROW nRow1, SCTAB nTab1, SCCOL nCol2, SCROW nRow2, SCTAB nTab2 ) diff --git a/sc/source/core/tool/rangelst.cxx b/sc/source/core/tool/rangelst.cxx index 1ab978866c67..11935a6e7d00 100644 --- a/sc/source/core/tool/rangelst.cxx +++ b/sc/source/core/tool/rangelst.cxx @@ -83,15 +83,18 @@ USHORT ScRangeList::Parse( const String& rStr, ScDocument* pDoc, USHORT nMask, for ( USHORT i=0; i<nTCount; i++ ) { aOne = rStr.GetToken( i, cDelimiter ); - // FIXME : broken for Lotus - if ( aOne.Search( ':' ) == STRING_NOTFOUND ) - { // Range muss es sein - String aStrTmp( aOne ); - aOne += ':'; - aOne += aStrTmp; - } aRange.aStart.SetTab( nTab ); // Default Tab wenn nicht angegeben - USHORT nRes = aRange.Parse( aOne, pDoc, eConv ); + USHORT nRes = aRange.ParseAny( aOne, pDoc, eConv ); + USHORT nEndRangeBits = SCA_VALID_COL2 | SCA_VALID_ROW2 | +SCA_VALID_TAB2; + USHORT nTmp1 = ( nRes & SCA_BITS ); + USHORT nTmp2 = ( nRes & nEndRangeBits ); + // If we have a valid single range with + // any of the address bits we are interested in + // set - set the equiv end range bits + if ( (nRes & SCA_VALID ) && nTmp1 && ( nTmp2 != nEndRangeBits ) ) + nRes |= ( nTmp1 << 4 ); + if ( (nRes & nMask) == nMask ) Append( aRange ); nResult &= nRes; // alle gemeinsamen Bits bleiben erhalten |