summaryrefslogtreecommitdiff
path: root/sc/source/core
diff options
context:
space:
mode:
authorNoel Power <noel.power@novell.com>2010-10-06 10:15:43 +0100
committerNoel Power <noel.power@novell.com>2010-10-06 10:15:43 +0100
commitf13fd7b138caee676cf5dbeae3474e4a4b0b177a (patch)
tree58bbab934d3fd26a8fd886a2dbc52b5a2d283092 /sc/source/core
parent44231089eeda805727f6c7143729612059891b02 (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.cxx46
-rw-r--r--sc/source/core/data/column3.cxx15
-rw-r--r--sc/source/core/data/documen2.cxx2
-rw-r--r--sc/source/core/data/documen8.cxx8
-rw-r--r--sc/source/core/data/document.cxx78
-rw-r--r--sc/source/core/inc/interpre.hxx11
-rw-r--r--sc/source/core/tool/address.cxx2
-rw-r--r--sc/source/core/tool/appoptio.cxx4
-rw-r--r--sc/source/core/tool/interpr1.cxx13
-rw-r--r--sc/source/core/tool/interpr4.cxx134
-rw-r--r--sc/source/core/tool/interpr5.cxx5
-rw-r--r--sc/source/core/tool/rangelst.cxx19
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