Anonymous avatar Anonymous committed 3c78fad

vbasupportdev300_HG: Document modules as parent objects

Comments (0)

Files changed (30)

basic/inc/basic/sbmod.hxx

 #ifndef _SB_SBMOD_HXX
 #define _SB_SBMOD_HXX
 
+#include <com/sun/star/script/XInvocation.hpp>
 #include <basic/sbdef.hxx>
 #include <basic/sbxobj.hxx>
 #include <basic/sbxdef.hxx>
 	SbModule(const SbModule&);
 
 protected:
+    com::sun::star::uno::Reference< com::sun::star::script::XInvocation > mxWrapper;
     ::rtl::OUString     aOUSource;
     String              aComment;
     SbiImage*           pImage;        // the Image
 	bool GetIsProxyModule() { return bIsProxyModule; }
         void AddVarName( const String& aName );
         void RemoveVars();
+    ::com::sun::star::uno::Reference< ::com::sun::star::script::XInvocation > GetUnoModule();
 };
 
 #ifndef __SB_SBMODULEREF_HXX

basic/source/classes/sbxmod.cxx

 #include <cppuhelper/implbase1.hxx>
 #include <comphelper/anytostring.hxx>
 #include <com/sun/star/document/XVbaMethodParameter.hpp> //liuchen 2009-7-21
+#include <com/sun/star/beans/XPropertySet.hpp>
+
 extern void unoToSbxValue( SbxVariable* pVar, const ::com::sun::star::uno::Any& aValue ); //liuchen 2009-7-21
 extern ::com::sun::star::uno::Any sbxToUnoValue( SbxVariable* pVar );  //liuchen 2009-7-21
 
 #include <com/sun/star/frame/XDesktop.hpp>
 #include <vcl/svapp.hxx>
+#include <map>
+#include <com/sun/star/reflection/XProxyFactory.hpp>
+#include <cppuhelper/implbase1.hxx>
+#include <basic/sbobjmod.hxx>
+#include <com/sun/star/uno/XAggregation.hpp>
+#include <map>
+#include <com/sun/star/script/XInvocation.hpp>
+
 using namespace ::com::sun::star; 
+using namespace com::sun::star::lang;
+using namespace com::sun::star::reflection;
+using namespace com::sun::star::beans;
+using namespace com::sun::star::script;
+
+typedef ::cppu::WeakImplHelper1< XInvocation > DocObjectWrapper_BASE;
+typedef ::std::map< sal_Int16, Any, ::std::less< sal_Int16 > > OutParamMap;
+::com::sun::star::uno::Any sbxToUnoValue( SbxVariable* pVar );
+void unoToSbxValue( SbxVariable* pVar, const ::com::sun::star::uno::Any& aValue );
+
+class DocObjectWrapper : public DocObjectWrapper_BASE
+{
+    Reference< XAggregation >  m_xAggProxy;
+    Reference< XInvocation >  m_xAggInv;
+    Reference< XTypeProvider > m_xAggregateTypeProv;
+    Sequence< Type >           m_Types;
+    SbModule*                m_pMod;
+    SbMethodRef getMethod( const rtl::OUString& aName ) throw (RuntimeException);
+    SbPropertyRef getProperty( const rtl::OUString& aName ) throw (RuntimeException);
+    String mName; // for debugging
+
+public:    
+    DocObjectWrapper( SbModule* pMod );
+    ~DocObjectWrapper();
+
+    virtual void SAL_CALL acquire() throw();
+    virtual void SAL_CALL release() throw();
+
+    virtual Sequence< sal_Int8 > SAL_CALL getImplementationId()
+        throw ( com::sun::star::uno::RuntimeException )
+    {
+        return m_xAggregateTypeProv->getImplementationId();
+
+    }
+
+    virtual Reference< XIntrospectionAccess > SAL_CALL getIntrospection(  ) throw (RuntimeException);
+
+    virtual Any SAL_CALL invoke( const ::rtl::OUString& aFunctionName, const Sequence< Any >& aParams, Sequence< ::sal_Int16 >& aOutParamIndex, Sequence< Any >& aOutParam ) throw (IllegalArgumentException, CannotConvertException, InvocationTargetException, RuntimeException);
+    virtual void SAL_CALL setValue( const ::rtl::OUString& aPropertyName, const Any& aValue ) throw (UnknownPropertyException, CannotConvertException, InvocationTargetException, RuntimeException);
+    virtual Any SAL_CALL getValue( const ::rtl::OUString& aPropertyName ) throw (UnknownPropertyException, RuntimeException);
+    virtual ::sal_Bool SAL_CALL hasMethod( const ::rtl::OUString& aName ) throw (RuntimeException);
+    virtual ::sal_Bool SAL_CALL hasProperty( const ::rtl::OUString& aName ) throw (RuntimeException);
+    virtual  Any SAL_CALL queryInterface( const Type& aType ) throw ( RuntimeException );
+    
+    virtual Sequence< Type > SAL_CALL getTypes() throw ( RuntimeException );
+};
+
+DocObjectWrapper::DocObjectWrapper( SbModule* pVar ) : m_pMod( pVar ), mName( pVar->GetName() )
+{   
+    SbObjModule* pMod = PTR_CAST(SbObjModule,pVar);
+    if ( pMod )
+    {
+        sal_Int16 nType = pMod->GetModuleType();
+        if ( pMod->GetModuleType() == ModuleType::DOCUMENT ) 
+        {
+            Reference< XMultiServiceFactory > xFactory = comphelper::getProcessServiceFactory();
+            // Use proxy factory service to create aggregatable proxy.
+            SbUnoObject* pUnoObj = PTR_CAST(SbUnoObject,pMod->GetObject() );
+            Reference< XInterface > xIf;
+            if ( pUnoObj )
+            {
+                   Any aObj = pUnoObj->getUnoAny(); 
+                   aObj >>= xIf;
+                   if ( xIf.is() )
+                   {
+                       m_xAggregateTypeProv.set( xIf, UNO_QUERY );
+                       m_xAggInv.set( xIf, UNO_QUERY );
+                   }
+            }
+            if ( xIf.is() )
+            {
+                try
+                {
+                    Reference< XMultiComponentFactory > xMFac( xFactory, UNO_QUERY_THROW );
+                    Reference< XPropertySet> xPSMPropertySet( xMFac, UNO_QUERY_THROW );
+                    Reference< XComponentContext >  xCtx;
+                    xPSMPropertySet->getPropertyValue(
+                    String( RTL_CONSTASCII_USTRINGPARAM("DefaultContext") ) ) >>= xCtx;
+                    Reference< XProxyFactory > xProxyFac( xMFac->createInstanceWithContext( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.reflection.ProxyFactory" ) ), xCtx  ), UNO_QUERY_THROW );
+                    m_xAggProxy = xProxyFac->createProxy( xIf );
+                }
+                catch(  Exception& )
+                {
+                    OSL_ENSURE( false, "DocObjectWrapper::DocObjectWrapper: Caught exception!" );
+                }
+            }
+     
+            if ( m_xAggProxy.is() )
+            {
+                osl_incrementInterlockedCount( &m_refCount );
+      
+                /* i35609 - Fix crash on Solaris. The setDelegator call needs
+                    to be in its own block to ensure that all temporary Reference
+                    instances that are acquired during the call are released
+                    before m_refCount is decremented again */
+                {
+                    m_xAggProxy->setDelegator( static_cast< cppu::OWeakObject * >( this ) );
+                }
+        
+                 osl_decrementInterlockedCount( &m_refCount );
+            }
+        }
+    }
+}
+
+void SAL_CALL 
+DocObjectWrapper::acquire() throw ()
+{
+    osl_incrementInterlockedCount( &m_refCount );
+    OSL_TRACE("DocObjectWrapper::acquire(%s) 0x%x refcount is now %d", rtl::OUStringToOString( mName, RTL_TEXTENCODING_UTF8 ).getStr(), this, m_refCount );
+}
+void SAL_CALL 
+DocObjectWrapper::release() throw ()
+{
+    if ( osl_decrementInterlockedCount( &m_refCount ) == 0 )
+    {
+        OSL_TRACE("DocObjectWrapper::release(%s) 0x%x refcount is now %d", rtl::OUStringToOString( mName, RTL_TEXTENCODING_UTF8 ).getStr(), this, m_refCount );
+        delete this;
+    }
+    else
+        OSL_TRACE("DocObjectWrapper::release(%s) 0x%x refcount is now %d", rtl::OUStringToOString( mName, RTL_TEXTENCODING_UTF8 ).getStr(), this, m_refCount );
+}
+
+DocObjectWrapper::~DocObjectWrapper() 
+{   
+}
+
+Sequence< Type > SAL_CALL DocObjectWrapper::getTypes()
+    throw ( RuntimeException )
+{
+    if ( m_Types.getLength() == 0 )
+    { 
+        Sequence< Type > sTypes;
+        if ( m_xAggregateTypeProv.is() )
+            sTypes = m_xAggregateTypeProv->getTypes();
+        m_Types.realloc( sTypes.getLength() + 1 );
+        Type* pPtr = m_Types.getArray();
+        for ( int i=0; i<m_Types.getLength(); ++i, ++pPtr )
+        {
+            if ( i == 0 ) 
+                *pPtr = XInvocation::static_type( NULL );
+            else
+                *pPtr = sTypes[ i - 1 ];
+        }
+    }
+    return m_Types;
+}
+
+Reference< XIntrospectionAccess > SAL_CALL 
+DocObjectWrapper::getIntrospection(  ) throw (RuntimeException)
+{
+    return NULL;
+}
+
+Any SAL_CALL 
+DocObjectWrapper::invoke( const ::rtl::OUString& aFunctionName, const Sequence< Any >& aParams, Sequence< ::sal_Int16 >& aOutParamIndex, Sequence< Any >& aOutParam ) throw (IllegalArgumentException, CannotConvertException, InvocationTargetException, RuntimeException)
+{
+    if ( m_xAggInv.is() &&  m_xAggInv->hasMethod( aFunctionName ) )
+            return m_xAggInv->invoke( aFunctionName, aParams, aOutParamIndex, aOutParam );
+    SbMethodRef pMethod = getMethod( aFunctionName );
+    if ( !pMethod )
+        throw RuntimeException();
+    // check number of parameters
+    sal_Int32 nParamsCount = aParams.getLength();
+    SbxInfo* pInfo = pMethod->GetInfo();
+    if ( pInfo )
+    {
+        sal_Int32 nSbxOptional = 0;
+        USHORT n = 1;
+        for ( const SbxParamInfo* pParamInfo = pInfo->GetParam( n ); pParamInfo; pParamInfo = pInfo->GetParam( ++n ) )
+        {
+            if ( ( pParamInfo->nFlags & SBX_OPTIONAL ) != 0 )
+                ++nSbxOptional;
+            else
+                nSbxOptional = 0;
+        }
+        sal_Int32 nSbxCount = n - 1;
+        if ( nParamsCount < nSbxCount - nSbxOptional )
+        {
+            throw RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "wrong number of parameters!" ) ), Reference< XInterface >() );
+        }
+    }
+    // set parameters
+    SbxArrayRef xSbxParams;
+    if ( nParamsCount > 0 )
+    {
+        xSbxParams = new SbxArray;
+        const Any* pParams = aParams.getConstArray();
+        for ( sal_Int32 i = 0; i < nParamsCount; ++i )
+        {
+            SbxVariableRef xSbxVar = new SbxVariable( SbxVARIANT );
+            unoToSbxValue( static_cast< SbxVariable* >( xSbxVar ), pParams[i] );
+            xSbxParams->Put( xSbxVar, static_cast< USHORT >( i ) + 1 );
+
+            // Enable passing by ref
+            if ( xSbxVar->GetType() != SbxVARIANT )
+                xSbxVar->SetFlag( SBX_FIXED );
+        }
+    }
+    if ( xSbxParams.Is() )
+        pMethod->SetParameters( xSbxParams );
+
+    // call method
+    SbxVariableRef xReturn = new SbxVariable;
+    ErrCode nErr = SbxERR_OK;
+
+    nErr = pMethod->Call( xReturn );
+    Any aReturn;
+    // get output parameters
+    if ( xSbxParams.Is() )
+    {
+        SbxInfo* pInfo_ = pMethod->GetInfo();
+        if ( pInfo_ )
+        {
+            OutParamMap aOutParamMap;
+            for ( USHORT n = 1, nCount = xSbxParams->Count(); n < nCount; ++n )
+            {
+                const SbxParamInfo* pParamInfo = pInfo_->GetParam( n );
+                if ( pParamInfo && ( pParamInfo->eType & SbxBYREF ) != 0 )
+                {
+                    SbxVariable* pVar = xSbxParams->Get( n );
+                    if ( pVar )
+                    {
+                        SbxVariableRef xVar = pVar;
+                        aOutParamMap.insert( OutParamMap::value_type( n - 1, sbxToUnoValue( xVar ) ) );
+                    }
+                }
+            }
+            sal_Int32 nOutParamCount = aOutParamMap.size();
+            aOutParamIndex.realloc( nOutParamCount );
+            aOutParam.realloc( nOutParamCount );
+            sal_Int16* pOutParamIndex = aOutParamIndex.getArray();
+            Any* pOutParam = aOutParam.getArray();
+            for ( OutParamMap::iterator aIt = aOutParamMap.begin(); aIt != aOutParamMap.end(); ++aIt, ++pOutParamIndex, ++pOutParam )
+            {
+                *pOutParamIndex = aIt->first;
+                *pOutParam = aIt->second;
+            }
+        }
+    }
+
+    // get return value
+    aReturn = sbxToUnoValue( xReturn );
+
+    pMethod->SetParameters( NULL );
+
+    return aReturn;
+}
+
+void SAL_CALL 
+DocObjectWrapper::setValue( const ::rtl::OUString& aPropertyName, const Any& aValue ) throw (UnknownPropertyException, CannotConvertException, InvocationTargetException, RuntimeException)
+{
+    if ( m_xAggInv.is() &&  m_xAggInv->hasProperty( aPropertyName ) )
+            return m_xAggInv->setValue( aPropertyName, aValue );
+    
+    SbPropertyRef pProperty = getProperty( aPropertyName );
+    if ( !pProperty.Is() )
+       throw UnknownPropertyException();
+    unoToSbxValue( (SbxVariable*) pProperty, aValue );
+}
+
+Any SAL_CALL 
+DocObjectWrapper::getValue( const ::rtl::OUString& aPropertyName ) throw (UnknownPropertyException, RuntimeException)
+{
+    if ( m_xAggInv.is() &&  m_xAggInv->hasProperty( aPropertyName ) )
+            return m_xAggInv->getValue( aPropertyName );
+
+    SbPropertyRef pProperty = getProperty( aPropertyName );
+    if ( !pProperty.Is() )
+       throw UnknownPropertyException();
+
+    SbxVariable* pProp = ( SbxVariable* ) pProperty;
+    if ( pProp->GetType() == SbxEMPTY )
+        pProperty->Broadcast( SBX_HINT_DATAWANTED );
+
+    Any aRet = sbxToUnoValue( pProp );
+    return aRet;
+}
+
+::sal_Bool SAL_CALL 
+DocObjectWrapper::hasMethod( const ::rtl::OUString& aName ) throw (RuntimeException)
+{
+    if ( m_xAggInv.is() && m_xAggInv->hasMethod( aName ) )
+        return sal_True;        
+    return getMethod( aName ).Is();
+}
+
+::sal_Bool SAL_CALL 
+DocObjectWrapper::hasProperty( const ::rtl::OUString& aName ) throw (RuntimeException)
+{
+    sal_Bool bRes = sal_False;
+    if ( m_xAggInv.is() && m_xAggInv->hasProperty( aName ) )
+        bRes = sal_True;        
+    else bRes = getProperty( aName ).Is();
+    return bRes;
+}
+
+Any SAL_CALL DocObjectWrapper::queryInterface( const Type& aType )
+    throw ( RuntimeException )
+{
+    Any aRet = DocObjectWrapper_BASE::queryInterface( aType );
+    if ( aRet.hasValue() )
+        return aRet;
+    else if ( m_xAggProxy.is() )
+        aRet = m_xAggProxy->queryAggregation( aType );
+    return aRet;
+}
+
+SbMethodRef DocObjectWrapper::getMethod( const rtl::OUString& aName ) throw (RuntimeException)
+{
+    SbMethodRef pMethod = NULL;
+    if ( m_pMod )
+    {
+        USHORT nSaveFlgs = m_pMod->GetFlags();
+        // Limit search to this module
+        m_pMod->ResetFlag( SBX_GBLSEARCH );
+        pMethod = (SbMethod*) m_pMod->SbModule::Find( aName,  SbxCLASS_METHOD );
+        m_pMod->SetFlags( nSaveFlgs );
+    }
+
+    return pMethod;
+}
+
+SbPropertyRef DocObjectWrapper::getProperty( const rtl::OUString& aName ) throw (RuntimeException)
+{
+    SbPropertyRef pProperty = NULL;
+    if ( m_pMod )
+    {
+        USHORT nSaveFlgs = m_pMod->GetFlags();
+        // Limit search to this module.
+        m_pMod->ResetFlag( SBX_GBLSEARCH );
+        pProperty = (SbProperty*)m_pMod->SbModule::Find( aName,  SbxCLASS_PROPERTY );
+        m_pMod->SetFlag( nSaveFlgs );
+    }
+
+    return pProperty;
+}
+
 
 TYPEINIT1(SbModule,SbxObject)
 TYPEINIT1(SbMethod,SbxMethod)
 
 SbModule::~SbModule()
 {
+    OSL_TRACE("Module named %s is destructing", rtl::OUStringToOString( GetName(), RTL_TEXTENCODING_UTF8 ).getStr() );
 	if( pImage )
 		delete pImage;
 	if( pBreaks )
 		delete pBreaks;
 	if( pClassData )
 		delete pClassData;
+        mxWrapper = NULL;
 }
 
+uno::Reference< script::XInvocation >
+SbModule::GetUnoModule()
+{
+    if ( !mxWrapper.is() )
+        mxWrapper = new DocObjectWrapper( this );
+
+    OSL_TRACE("Module named %s returning wrapper mxWrapper (0x%x)", rtl::OUStringToOString( GetName(), RTL_TEXTENCODING_UTF8 ).getStr(), mxWrapper.get() );
+    return mxWrapper;
+}
 BOOL SbModule::IsCompiled() const
 {
 	return BOOL( pImage != 0 );

sc/source/core/tool/interpr4.cxx

 #include <signal.h>
 
 #include <com/sun/star/table/XCellRange.hpp>
+#include <com/sun/star/sheet/XSheetCellRange.hpp>
 #include <comphelper/processfactory.hxx>
 
 #include "interpre.hxx"
     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 )
 {
 		uno::Reference< uno::XInterface > xVBARange;
 		uno::Reference<table::XCellRange> xCellRange = ScCellRangeObj::CreateRangeFromDoc( pDok, aRange );
 		uno::Sequence< uno::Any > aArgs(2);
-		aArgs[0] = uno::Any( uno::Reference< uno::XInterface >() ); // dummy parent
+		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() )
 	}
 	return bOk;
 }
+
 void ScInterpreter::ScMacro()
 {
     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScMacro" );

sc/source/ui/unoobj/servuno.cxx

 #include <comphelper/componentcontext.hxx>
 #include <cppuhelper/component_context.hxx>
 #include <vbahelper/vbaaccesshelper.hxx>
+#include <com/sun/star/script/XVBACompat.hpp>
+
 using namespace ::com::sun::star;
 
+bool isInVBAMode( ScDocShell& rDocSh )
+{
+    uno::Reference<script::XLibraryContainer> xLibContainer = rDocSh.GetBasicContainer();
+    uno::Reference<script::XVBACompat> xVBACompat( xLibContainer, uno::UNO_QUERY );
+    if ( xVBACompat.is() )
+        return xVBACompat->getVBACompatModeOn();
+    return false;
+}
+
 
 class ScVbaObjectForCodeNameProvider : public ::cppu::WeakImplHelper1< container::XNameAccess >
 {
             throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("")), uno::Reference< uno::XInterface >() );
 
         uno::Sequence< uno::Any > aArgs(2);
-        aArgs[0] = uno::Any( uno::Reference< uno::XInterface >() );
+        // access the application object ( parent for workbook )
+        aArgs[0] = uno::Any( ooo::vba::createVBAUnoAPIServiceWithArgs( mpDocShell, "ooo.vba.Application", uno::Sequence< uno::Any >() ) );
         aArgs[1] = uno::Any( mpDocShell->GetModel() );
         maWorkbook <<= ooo::vba::createVBAUnoAPIServiceWithArgs( mpDocShell, "ooo.vba.excel.Workbook", aArgs );
     }
             }
             break;
         case SC_SERVICE_VBACODENAMEPROVIDER:
-            if ( pDocShell && ooo::vba::isAlienExcelDoc( *pDocShell ) )
+            if ( pDocShell && ooo::vba::isAlienExcelDoc( *pDocShell ) && isInVBAMode( *pDocShell ) )
             {
                 OSL_TRACE("**** creating VBA Object provider");
                 xRet.set(static_cast<document::XCodeNameQuery*>(new ScVbaCodeNameProvider( pDocShell )));

sc/source/ui/vba/excelvbahelper.cxx

 #include "scmod.hxx"
 #include "cellsuno.hxx"
 #include <comphelper/processfactory.hxx>
+#include <com/sun/star/sheet/XSheetCellRange.hpp>
 
 using namespace ::com::sun::star;
 using namespace ::ooo::vba;
 namespace excel
 {
 
-
 uno::Reference< sheet::XDatabaseRanges > 
 GetDataBaseRanges( ScDocShell* pShell ) throw ( uno::RuntimeException )
 {
 	return sal_False;
 }
 
+uno::Reference< XHelperInterface > 
+getUnoSheetModuleObj( const uno::Reference< table::XCellRange >& xRange ) throw ( uno::RuntimeException )
+{
+    uno::Reference< sheet::XSheetCellRange > xSheetRange( xRange, 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.
+    uno::Reference< XHelperInterface > xParent( ov::getUnoDocModule( sCodeName, GetDocShellFromRange( xRange ) ), uno::UNO_QUERY );
+
+    return xParent;
+}
+
+uno::Reference< XHelperInterface > 
+getUnoSheetModuleObj( const uno::Reference< sheet::XSheetCellRangeContainer >& xRanges ) throw ( uno::RuntimeException )
+{
+    uno::Reference< container::XEnumerationAccess > xEnumAccess( xRanges, uno::UNO_QUERY_THROW );
+    uno::Reference< container::XEnumeration > xEnum = xEnumAccess->createEnumeration();
+    uno::Reference< table::XCellRange > xRange( xEnum->nextElement(), uno::UNO_QUERY_THROW );
+
+    return getUnoSheetModuleObj( xRange );
+}
+
 SfxItemSet*
 ScVbaCellRangeAccess::GetDataSet( ScCellRangesBase* pRangeObj )
 {
 	return pRangeObj ? pRangeObj->GetCurrentDataSet( true ) : 0;
 }
 
+
 } //excel
 } //vba 
 } //ooo 

sc/source/ui/vba/excelvbahelper.hxx

 #include <docsh.hxx>
 #include <com/sun/star/sheet/XDatabaseRanges.hpp>
 #include <com/sun/star/sheet/XDatabaseRange.hpp>
+#include <com/sun/star/table/XCellRange.hpp>
+#include <com/sun/star/sheet/XSheetCellRangeContainer.hpp>
+#include <ooo/vba/XHelperInterface.hpp>
+
 
 class ScCellRangesBase;
 
             css::uno::Reference< css::sheet::XDatabaseRanges > GetDataBaseRanges( ScDocShell* pShell ) throw ( css::uno::RuntimeException );
 
             css::uno::Reference< css::sheet::XDatabaseRange > GetAutoFiltRange( ScDocShell* pShell, sal_Int16 nSheet, rtl::OUString& sName ) throw ( css::uno::RuntimeException );
-
+            css::uno::Reference< ooo::vba::XHelperInterface > getUnoSheetModuleObj( const css::uno::Reference< css::sheet::XSheetCellRangeContainer >& xRanges ) throw ( css::uno::RuntimeException );
+            css::uno::Reference< ooo::vba::XHelperInterface > getUnoSheetModuleObj( const css::uno::Reference< css::table::XCellRange >& xRange ) throw ( css::uno::RuntimeException );
             ScDocShell* GetDocShellFromRange( const css::uno::Reference< css::uno::XInterface >& xRange ) throw ( css::uno::RuntimeException );
             ScDocument* GetDocumentFromRange( const css::uno::Reference< css::uno::XInterface >& xRange ) throw ( css::uno::RuntimeException );
             css::uno::Reference< css::frame::XModel > GetModelFromRange( const css::uno::Reference< css::uno::XInterface >& xRange ) throw ( css::uno::RuntimeException );

sc/source/ui/vba/vbaapplication.cxx

 uno::Reference< excel::XWorkbook >
 ScVbaApplication::getActiveWorkbook() throw (uno::RuntimeException)
 {
-	return new ActiveWorkbook( this, mxContext ); 
+    uno::Reference< excel::XWorkbook > xWrkbk;
+    ScDocShell* pShell = excel::getDocShell( getCurrentExcelDoc( mxContext ) );
+    if ( pShell )
+    {
+        String aName;
+        if ( pShell->GetDocument() )
+        {
+            aName = pShell->GetDocument()->GetCodeName();
+            xWrkbk.set( getUnoDocModule(  aName, pShell ), uno::UNO_QUERY );
+            // fallback ( e.g. it's possible a new document was created via the api )
+            // in that case the document will not have the appropriate Document Modules
+            // #TODO #FIXME ( needs to be fixes as part of providing support for an overall document 
+            // vba mode etc. )
+            if ( !xWrkbk.is() )
+                return new ActiveWorkbook( this, mxContext );
+        }
+    }
+    return xWrkbk; 
 }
 
 uno::Reference< excel::XWorkbook > SAL_CALL 
 ScVbaApplication::getThisWorkbook() throw (uno::RuntimeException)
 {
-	uno::Reference< frame::XModel > xModel = getThisExcelDoc(mxContext);
-	if( !xModel.is() )
-		return uno::Reference< excel::XWorkbook >();
-
-	ScVbaWorkbook *pWb = new ScVbaWorkbook( this, mxContext, xModel );
-	return uno::Reference< excel::XWorkbook > (pWb);
+    uno::Reference< excel::XWorkbook > xWrkbk;
+    ScDocShell* pShell = excel::getDocShell( getThisExcelDoc( mxContext ) );
+    if ( pShell )
+    {
+        String aName;
+        if ( pShell->GetDocument() )
+        {
+            aName = pShell->GetDocument()->GetCodeName();
+            xWrkbk.set( getUnoDocModule( aName, pShell ), uno::UNO_QUERY );
+            // fallback ( e.g. it's possible a new document was created via the api )
+            // in that case the document will not have the appropriate Document Modules
+            // #TODO #FIXME ( needs to be fixes as part of providing support for an overall document 
+            // vba mode etc. )
+            if ( !xWrkbk.is() )
+                return new ActiveWorkbook( this, mxContext );
+        }
+    }
+    return xWrkbk;
 }
 
 uno::Reference< XAssistant > SAL_CALL
 	    {
 		    uno::Reference< sheet::XSheetCellRangeContainer > xRanges( aSelection, ::uno::UNO_QUERY);
 		    if ( xRanges.is() )
-			    return uno::makeAny( uno::Reference< excel::XRange >( new ScVbaRange( this, mxContext, xRanges ) ) );
+                return uno::makeAny( uno::Reference< excel::XRange >( new ScVbaRange( excel::getUnoSheetModuleObj( xRanges ), mxContext, xRanges ) ) );
 
 	    }
-	    return uno::makeAny( uno::Reference< excel::XRange >(new ScVbaRange( this, mxContext, xRange ) ) );
+        return uno::makeAny( uno::Reference< excel::XRange >(new ScVbaRange( excel::getUnoSheetModuleObj( xRange ), mxContext, xRange ) ) );
     }
     else
     {
 	ScDocShell* pDocShell = excel::getDocShell( xModel );
 	if ( aCellRanges.Count() == 1 )
 	{
-		xRefRange = new ScVbaRange( uno::Reference< XHelperInterface >(), mxContext, new ScCellRangeObj( pDocShell, *aCellRanges.First() ) );
+                uno::Reference< table::XCellRange > xRange( new ScCellRangeObj( pDocShell, *aCellRanges.First() ));
+		xRefRange = new ScVbaRange( excel::getUnoSheetModuleObj( xRange ), mxContext, xRange );
 	}
 	else if ( aCellRanges.Count() > 1 )
 	{
 		uno::Reference< sheet::XSheetCellRangeContainer > xRanges( new ScCellRangesObj( pDocShell, aCellRanges ) );
-		xRefRange = new ScVbaRange( uno::Reference< XHelperInterface >(), mxContext, xRanges );
+		xRefRange = new ScVbaRange( excel::getUnoSheetModuleObj( xRanges ) , mxContext, xRanges );
 
 	}
 	return xRefRange;
 	if ( aCellRanges.Count() == 1 ) 
 	{
 	// normal range
-		xRange = new ScVbaRange( uno::Reference< XHelperInterface >(), mxContext, new ScCellRangeObj( pDocShell, *aCellRanges.First() ) );
+                uno::Reference< table::XCellRange > xCalcRange( new ScCellRangeObj( pDocShell, *aCellRanges.First() ) );
+		xRange = new ScVbaRange( excel::getUnoSheetModuleObj( xCalcRange ), mxContext, xCalcRange );
 	}
 	else if ( aCellRanges.Count() > 1 ) // Multi-Area
 	{
 		uno::Reference< sheet::XSheetCellRangeContainer > xRanges( new ScCellRangesObj( pDocShell, aCellRanges ) );
-    	xRange = new ScVbaRange( uno::Reference< XHelperInterface >(), mxContext, xRanges );
+    	xRange = new ScVbaRange( excel::getUnoSheetModuleObj( xRanges ), mxContext, xRanges );
 	}
 	
     // #FIXME need proper (WorkSheet) parent

sc/source/ui/vba/vbachartobjects.cxx

 class ChartObjectEnumerationImpl : public EnumerationHelperImpl
 {
 	uno::Reference< drawing::XDrawPageSupplier > xDrawPageSupplier;
-	uno::Reference< XHelperInterface > xParent;
 	
 public:
 
-	ChartObjectEnumerationImpl( const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< container::XEnumeration >& xEnumeration, const uno::Reference< drawing::XDrawPageSupplier >& _xDrawPageSupplier, const uno::Reference< XHelperInterface >& _xParent ) throw ( uno::RuntimeException ) : EnumerationHelperImpl( xContext, xEnumeration ), xDrawPageSupplier( _xDrawPageSupplier ), xParent( _xParent ) {}
+    ChartObjectEnumerationImpl( const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< container::XEnumeration >& xEnumeration, const uno::Reference< drawing::XDrawPageSupplier >& _xDrawPageSupplier, const uno::Reference< XHelperInterface >& _xParent ) throw ( uno::RuntimeException ) : EnumerationHelperImpl( _xParent, xContext, xEnumeration ), xDrawPageSupplier( _xDrawPageSupplier ) {}
 	virtual uno::Any SAL_CALL nextElement(  ) throw (container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException) 
 	{ 
 		uno::Reference< table::XTableChart > xTableChart( m_xEnumeration->nextElement(), uno::UNO_QUERY_THROW );
 		// parent Object is sheet
-		return uno::makeAny(  uno::Reference< excel::XChartObject > ( new ScVbaChartObject(  xParent, m_xContext, xTableChart, xDrawPageSupplier ) ) );
+        return uno::makeAny(  uno::Reference< excel::XChartObject > ( new ScVbaChartObject(  m_xParent, m_xContext, xTableChart, xDrawPageSupplier ) ) );
 	}
 };
 

sc/source/ui/vba/vbacomments.cxx

 class CommentEnumeration : public EnumerationHelperImpl
 {
 public:
-	CommentEnumeration( const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< container::XEnumeration >& xEnumeration ) throw ( uno::RuntimeException ) : EnumerationHelperImpl( xContext, xEnumeration ) {}
+    CommentEnumeration( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< container::XEnumeration >& xEnumeration ) throw ( uno::RuntimeException ) : EnumerationHelperImpl( xParent, xContext, xEnumeration ) {}
 
 	virtual uno::Any SAL_CALL nextElement() throw (container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException)
 	{ 
 {
 	uno::Reference< container::XEnumerationAccess > xEnumAccess( m_xIndexAccess, uno::UNO_QUERY_THROW );
 
-	return new CommentEnumeration( mxContext, xEnumAccess->createEnumeration() );
+    return new CommentEnumeration( mxParent, mxContext, xEnumAccess->createEnumeration() );
 }
 
 uno::Any

sc/source/ui/vba/vbaeventshelper.cxx

     INSERT_WORKBOOK_EVENT_INFO( WINDOWRESIZE, "WindowResize" );
 }
 
-uno::Any ScVbaEventsHelper::createWorkSheet( SfxObjectShell* pShell, SCTAB nTab )
+uno::Any ScVbaEventsHelper::createWorkSheet( ScDocument* pDok, SCTAB nTab )
 {
 	uno::Any aRet;
 	try
 	{
-		uno::Reference< lang::XMultiComponentFactory > xSMgr( ::comphelper::getProcessServiceFactory(), uno::UNO_QUERY_THROW );
-		uno::Reference< beans::XPropertySet > xProps( xSMgr, uno::UNO_QUERY_THROW );
-		uno::Reference<uno::XComponentContext > xCtx( xProps->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DefaultContext" ))), uno::UNO_QUERY_THROW );
-		// Eventually we will be able to pull the Workbook/Worksheet objects
-		// directly from basic and register them as listeners
-
-		// create Workbook
-		uno::Sequence< uno::Any > aArgs(2);
-		aArgs[0] = uno::Any( uno::Reference< uno::XInterface >() );
-		aArgs[1] = uno::Any( pShell->GetModel() );
-		uno::Reference< uno::XInterface > xWorkbook( ov::createVBAUnoAPIServiceWithArgs( pShell, "ooo.vba.excel.Workbook", aArgs ), uno::UNO_QUERY );
-
-		// create WorkSheet
-		String sSheetName;
-		pDoc->GetName( nTab, sSheetName );
-		aArgs = uno::Sequence< uno::Any >(3);
-		aArgs[ 0 ] <<= xWorkbook;
-		aArgs[ 1 ] <<= pShell->GetModel();
-		aArgs[ 2 ] = uno::makeAny( rtl::OUString( sSheetName ) );
-		aRet <<= ov::createVBAUnoAPIServiceWithArgs( pShell, "ooo.vba.excel.Worksheet", aArgs );
+            String tmpCodeName;
+	    pDok->GetCodeName( nTab, tmpCodeName );
+            aRet <<= ov::getUnoDocModule( tmpCodeName, pDok->GetDocumentShell() );
 	}
 	catch( uno::Exception& e )
 	{
 		{
 			uno::Reference<uno::XComponentContext > xCtx( xProps->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DefaultContext" ))), uno::UNO_QUERY_THROW );
 			uno::Sequence< uno::Any > aArgs(2);
-			aArgs[0] = uno::Any( uno::Reference< uno::XInterface >() ); // dummy parent
 			if ( xRanges.is() )
 			{
+			        aArgs[0] = uno::makeAny( excel::getUnoSheetModuleObj( xRanges ) );
 				aArgs[1] <<= xRanges;
 			}
 			else if ( xRange.is() )
 			{
+			        aArgs[0] = uno::makeAny( excel::getUnoSheetModuleObj( xRange ) );
 				aArgs[1] <<= xRange;
 			}
 			else
         uno::Reference< lang::XMultiServiceFactory > xSF( comphelper::getProcessServiceFactory(), uno::UNO_QUERY );
         uno::Reference< frame::XModel > xModel( pShell->GetModel(), uno::UNO_QUERY );
         uno::Sequence< uno::Any > aWindowArgs(2);
-        aWindowArgs[0] = uno::Any( uno::Reference< uno::XInterface > () );
+        aWindowArgs[0] = uno::Any( createVBAUnoAPIService( pShell, "ooo.vba.Application" ) );
         aWindowArgs[1] = uno::Any( xModel );
         uno::Reference< uno::XInterface > xWindow( xSF->createInstanceWithArguments( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("ooo.vba.excel.Window" ) ), aWindowArgs ), uno::UNO_QUERY );
         if( xWindow.is() )
             case VBAEVENT_WORKBOOK_NEWSHEET:
             {
 				aArgs = uno::Sequence< uno::Any >(1);
-				aArgs[0] = createWorkSheet( pShell, nTab ); 
+				aArgs[0] = createWorkSheet( pDoc, nTab ); 
 				break;
             }
 			case VBAEVENT_WORKSHEET_CHANGE:
             {
 				uno::Any aRange = createRange( rArgs[0] );
 				aArgs = uno::Sequence< uno::Any >(2);
-				aArgs[0] = createWorkSheet( pShell, nTab );
+				aArgs[0] = createWorkSheet( pDoc, nTab );
 				aArgs[1] = aRange;
 				break;
             }
             {
 				uno::Any aRange = createRange( rArgs[0] );
 				aArgs = uno::Sequence< uno::Any >(3);
-				aArgs[0] = createWorkSheet( pShell, nTab );
+				aArgs[0] = createWorkSheet( pDoc, nTab );
 				aArgs[1] = aRange;
 				aArgs[2] <<= bCancel;
 				// TODO: process "cancel" action  
             {
 				uno::Any aHyperlink = createHyperlink( rArgs[0] );
 				aArgs = uno::Sequence< uno::Any >(2);
-				aArgs[0] = createWorkSheet( pShell, nTab );
+				aArgs[0] = createWorkSheet( pDoc, nTab );
 				aArgs[1] = aHyperlink;
 				break;
             }

sc/source/ui/vba/vbaeventshelper.hxx

     css::uno::WeakReference< ::ooo::vba::excel::XApplication > m_xApplication;
 
 	String getSheetModuleName( SCTAB nTab );
-	css::uno::Any createWorkSheet( SfxObjectShell* pShell, SCTAB nTab );
+	css::uno::Any createWorkSheet( ScDocument* pDoc, SCTAB nTab );
 	css::uno::Any createRange( const css::uno::Any& aRange );
 	css::uno::Any createHyperlink( const css::uno::Any& rCell );
 	css::uno::Any createWindow( SfxObjectShell* pShell );

sc/source/ui/vba/vbaformatconditions.cxx

 ScVbaFormatConditions::ScVbaFormatConditions( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext > & xContext, const uno::Reference< sheet::XSheetConditionalEntries >& _xSheetConditionalEntries, const uno::Reference< frame::XModel >& xModel ) : ScVbaFormatConditions_BASE( xParent, xContext, uno::Reference< container::XIndexAccess >( _xSheetConditionalEntries, uno::UNO_QUERY_THROW ) ), mxSheetConditionalEntries( _xSheetConditionalEntries )
 {
 	mxRangeParent.set( xParent, uno::UNO_QUERY_THROW );
-	uno::Reference< excel::XWorkbook > xWorkbook = new ScVbaWorkbook(  uno::Reference< XHelperInterface >( Application(), uno::UNO_QUERY_THROW ), xContext, xModel );
-	mxStyles.set( xWorkbook->Styles( uno::Any() ), uno::UNO_QUERY_THROW );
+    uno::Reference< excel::XApplication> xApp( Application(), uno::UNO_QUERY_THROW );
+    mxStyles.set( xApp->getThisWorkbook()->Styles( uno::Any() ), uno::UNO_QUERY_THROW );
 	uno::Reference< sheet::XCellRangeAddressable > xCellRange( mxRangeParent->getCellRange(), uno::UNO_QUERY_THROW );
 	mxParentRangePropertySet.set( xCellRange, uno::UNO_QUERY_THROW );
 	

sc/source/ui/vba/vbanames.cxx

 	uno::WeakReference< XHelperInterface > m_xParent;
 	uno::Reference< sheet::XNamedRanges > m_xNames;
 public:
-	NamesEnumeration( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< container::XEnumeration >& xEnumeration,  const uno::Reference< frame::XModel >& xModel , const uno::Reference< sheet::XNamedRanges >& xNames ) throw ( uno::RuntimeException ) : EnumerationHelperImpl( xContext, xEnumeration ), m_xModel( xModel ), m_xParent( xParent ), m_xNames( xNames ) {}
+    NamesEnumeration( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< container::XEnumeration >& xEnumeration,  const uno::Reference< frame::XModel >& xModel , const uno::Reference< sheet::XNamedRanges >& xNames ) throw ( uno::RuntimeException ) : EnumerationHelperImpl( xParent, xContext, xEnumeration ), m_xModel( xModel ), m_xParent( xParent ), m_xNames( xNames ) {}
 
 	virtual uno::Any SAL_CALL nextElement(  ) throw (container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException)
 	{

sc/source/ui/vba/vbapivottables.cxx

 class PivotTableEnumeration : public EnumerationHelperImpl
 {
 public:
-	PivotTableEnumeration( const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< container::XEnumeration >& xEnumeration ) throw ( uno::RuntimeException ) : EnumerationHelperImpl( xContext, xEnumeration ) {}
+    PivotTableEnumeration( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< container::XEnumeration >& xEnumeration ) throw ( uno::RuntimeException ) : EnumerationHelperImpl( xParent, xContext, xEnumeration ) {}
 
 	virtual uno::Any SAL_CALL nextElement(  ) throw (container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException) 
 	{ 
 ScVbaPivotTables::createEnumeration() throw (uno::RuntimeException)
 {
 	uno::Reference< container::XEnumerationAccess > xEnumAccess( m_xIndexAccess, uno::UNO_QUERY_THROW );
-	return new PivotTableEnumeration( mxContext, xEnumAccess->createEnumeration() );
+    return new PivotTableEnumeration( mxParent, mxContext, xEnumAccess->createEnumeration() );
 }
 
 uno::Any

sc/source/ui/vba/vbarange.cxx

 	return nVal;
 }
 
-uno::Any lcl_makeRange( uno::Reference< uno::XComponentContext >& xContext, const uno::Any aAny, bool bIsRows, bool bIsColumns )
+uno::Any lcl_makeRange( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Any aAny, bool bIsRows, bool bIsColumns )
 {
 	uno::Reference< table::XCellRange > xCellRange( aAny, uno::UNO_QUERY_THROW );
-	// #FIXME need proper (WorkSheet) parent
-	return uno::makeAny( uno::Reference< excel::XRange >( new ScVbaRange( uno::Reference< XHelperInterface >(), xContext, xCellRange, bIsRows, bIsColumns ) ) );
+    return uno::makeAny( uno::Reference< excel::XRange >( new ScVbaRange( xParent, xContext, xCellRange, bIsRows, bIsColumns ) ) );
 }
 
 uno::Reference< excel::XRange > lcl_makeXRangeFromSheetCellRanges( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< sheet::XSheetCellRanges >& xLocSheetCellRanges, ScDocShell* pDoc )
 	if ( aCellRanges.First() == aCellRanges.Last() )
 	{
 		uno::Reference< table::XCellRange > xTmpRange( new ScCellRangeObj( pDoc, *aCellRanges.First() ) );
-		// #FIXME need proper (WorkSheet) parent
 		xRange = new ScVbaRange( xParent, xContext, xTmpRange );
 	}
 	else
 	{
 		uno::Reference< sheet::XSheetCellRangeContainer > xRanges( new ScCellRangesObj( pDoc, aCellRanges ) );
-		// #FIXME need proper (WorkSheet) parent
 		xRange = new ScVbaRange( xParent, xContext, xRanges );
 	}
 	}
 
 class SingleRangeEnumeration : public EnumerationHelper_BASE
 {
+    uno::Reference< XHelperInterface > m_xParent;
 	uno::Reference< table::XCellRange > m_xRange;
 	uno::Reference< uno::XComponentContext > mxContext;
 	bool bHasMore;
 public:
 
-	SingleRangeEnumeration( const uno::Reference< css::uno::XComponentContext >& xContext, const uno::Reference< table::XCellRange >& xRange ) throw ( uno::RuntimeException ) : m_xRange( xRange ), mxContext( xContext ), bHasMore( true ) { }
+    SingleRangeEnumeration( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< css::uno::XComponentContext >& xContext, const uno::Reference< table::XCellRange >& xRange ) throw ( uno::RuntimeException ) : m_xParent( xParent ), m_xRange( xRange ), mxContext( xContext ), bHasMore( true ) { }
 	virtual ::sal_Bool SAL_CALL hasMoreElements(  ) throw (uno::RuntimeException) { return bHasMore; }
 	virtual uno::Any SAL_CALL nextElement(  ) throw (container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException) 
 	{
 class SingleRangeIndexAccess : public SingleRange_BASE
 {
 private:
+    uno::Reference< XHelperInterface > mxParent;
 	uno::Reference< table::XCellRange > m_xRange;
 	uno::Reference< uno::XComponentContext > mxContext;
 	SingleRangeIndexAccess(); // not defined
 public:
-	SingleRangeIndexAccess( const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< table::XCellRange >& xRange ):m_xRange( xRange ), mxContext( xContext ) {}
+    SingleRangeIndexAccess( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< table::XCellRange >& xRange ):mxParent( xParent ), m_xRange( xRange ), mxContext( xContext ) {}
 	// XIndexAccess
 	virtual ::sal_Int32 SAL_CALL getCount() throw (::uno::RuntimeException) { return 1; }
 	virtual uno::Any SAL_CALL getByIndex( ::sal_Int32 Index ) throw (lang::IndexOutOfBoundsException, lang::WrappedTargetException, uno::RuntimeException)
  
         virtual ::sal_Bool SAL_CALL hasElements() throw (uno::RuntimeException) { return sal_True; }
 	// XEnumerationAccess
-	virtual uno::Reference< container::XEnumeration > SAL_CALL createEnumeration() throw (uno::RuntimeException) { return new SingleRangeEnumeration( mxContext, m_xRange ); }
+    virtual uno::Reference< container::XEnumeration > SAL_CALL createEnumeration() throw (uno::RuntimeException) { return new SingleRangeEnumeration( mxParent, mxContext, m_xRange ); }
 
 };
 
 	bool mbIsColumns;
 public:
 
-	RangesEnumerationImpl( const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< container::XEnumeration >& xEnumeration, bool bIsRows, bool bIsColumns ) throw ( uno::RuntimeException ) : EnumerationHelperImpl( xContext, xEnumeration ), mbIsRows( bIsRows ), mbIsColumns( bIsColumns ) {}
+    RangesEnumerationImpl( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< container::XEnumeration >& xEnumeration, bool bIsRows, bool bIsColumns ) throw ( uno::RuntimeException ) : EnumerationHelperImpl( xParent, xContext, xEnumeration ), mbIsRows( bIsRows ), mbIsColumns( bIsColumns ) {}
 	virtual uno::Any SAL_CALL nextElement(  ) throw (container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException) 
 	{ 
-		return lcl_makeRange( m_xContext, m_xEnumeration->nextElement(), mbIsRows, mbIsColumns );
+        return lcl_makeRange( m_xParent, m_xContext, m_xEnumeration->nextElement(), mbIsRows, mbIsColumns );
 	}
 };
 
 	bool mbIsRows;
 	bool mbIsColumns;
 public:
-	ScVbaRangeAreas( const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< container::XIndexAccess >& xIndexAccess, bool bIsRows, bool bIsColumns ) : ScVbaCollectionBaseImpl( uno::Reference< XHelperInterface >(), xContext, xIndexAccess ), mbIsRows( bIsRows ), mbIsColumns( bIsColumns ) {}
+    ScVbaRangeAreas( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< container::XIndexAccess >& xIndexAccess, bool bIsRows, bool bIsColumns ) : ScVbaCollectionBaseImpl( xParent, xContext, xIndexAccess ), mbIsRows( bIsRows ), mbIsColumns( bIsColumns ) {}
 
 	// XEnumerationAccess
 	virtual uno::Reference< container::XEnumeration > SAL_CALL createEnumeration() throw (uno::RuntimeException);
 ScVbaRangeAreas::createEnumeration() throw (uno::RuntimeException)
 {
 	uno::Reference< container::XEnumerationAccess > xEnumAccess( m_xIndexAccess, uno::UNO_QUERY_THROW );
-	return new RangesEnumerationImpl( mxContext, xEnumAccess->createEnumeration(), mbIsRows, mbIsColumns );
+    return new RangesEnumerationImpl( mxParent, mxContext, xEnumAccess->createEnumeration(), mbIsRows, mbIsColumns );
 
 }
 
 uno::Any 
 ScVbaRangeAreas::createCollectionObject( const uno::Any& aSource )
 {
-	return lcl_makeRange( mxContext, aSource, mbIsRows, mbIsColumns );
+    return lcl_makeRange( mxParent, mxContext, aSource, mbIsRows, mbIsColumns );
 }
 
 ScDocument* 
 
 class CellsEnumeration : public CellsEnumeration_BASE
 {
+    uno::WeakReference< XHelperInterface > mxParent;
 	uno::Reference< uno::XComponentContext > mxContext;
 	uno::Reference< XCollection > m_xAreas;
 	vCellPos m_CellPositions;	
 		}
 	}
 public:
-	CellsEnumeration( const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< XCollection >& xAreas ): mxContext( xContext ), m_xAreas( xAreas )
+    CellsEnumeration( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< XCollection >& xAreas ): mxParent( xParent ), mxContext( xContext ), m_xAreas( xAreas )
 	{
 		sal_Int32 nItems = m_xAreas->getCount();
 		for ( sal_Int32 index=1; index <= nItems; ++index )
 		
 		uno::Reference< table::XCellRange > xRangeArea = getArea( aPos.m_nArea );
 		uno::Reference< table::XCellRange > xCellRange( xRangeArea->getCellByPosition(  aPos.m_nCol, aPos.m_nRow ), uno::UNO_QUERY_THROW );
-		// #FIXME need proper (WorkSheet) parent
-		return uno::makeAny( uno::Reference< excel::XRange >( new ScVbaRange( uno::Reference< XHelperInterface >(), mxContext, xCellRange ) ) );
+        return uno::makeAny( uno::Reference< excel::XRange >( new ScVbaRange( mxParent, mxContext, xCellRange ) ) );
 
 	}
 };
 		return 	uno::Reference< sheet::XSheetCellCursor >( getSpreadSheet()->createCursorByRange( getSheetCellRange() ), uno::UNO_QUERY_THROW );
 	}	
 
-	static uno::Reference< excel::XRange > createRangeFromRange( const uno::Reference<uno::XComponentContext >& xContext, const uno::Reference< table::XCellRange >& xRange, const uno::Reference< sheet::XCellRangeAddressable >& xCellRangeAddressable, sal_Int32 nStartColOffset = 0, sal_Int32 nStartRowOffset = 0,
+    static uno::Reference< excel::XRange > createRangeFromRange( const uno::Reference< XHelperInterface >& xParent, const uno::Reference<uno::XComponentContext >& xContext, const uno::Reference< table::XCellRange >& xRange, const uno::Reference< sheet::XCellRangeAddressable >& xCellRangeAddressable, sal_Int32 nStartColOffset = 0, sal_Int32 nStartRowOffset = 0,
 		sal_Int32 nEndColOffset = 0, sal_Int32 nEndRowOffset = 0 )
 	{
-		// #FIXME need proper (WorkSheet) parent
-		return uno::Reference< excel::XRange >( new ScVbaRange( uno::Reference< XHelperInterface >(), xContext, 
+        return uno::Reference< excel::XRange >( new ScVbaRange( xParent, xContext, 
 			xRange->getCellRangeByPosition(
 				xCellRangeAddressable->getRangeAddress().StartColumn + nStartColOffset,
 				xCellRangeAddressable->getRangeAddress().StartRow + nStartRowOffset,
 	if ( aCellRanges.First() == aCellRanges.Last() )
 	{
 		uno::Reference< table::XCellRange > xRange( new ScCellRangeObj( pDocSh, *aCellRanges.First() ) );
-		// #FIXME need proper (WorkSheet) parent
-		return new ScVbaRange( uno::Reference< XHelperInterface >(), xContext, xRange );
+        uno::Reference< XHelperInterface > xFixThisParent = excel::getUnoSheetModuleObj( xRange ); 
+        return new ScVbaRange( xFixThisParent, xContext, xRange );
 	}
 	uno::Reference< sheet::XSheetCellRangeContainer > xRanges( new ScCellRangesObj( pDocSh, aCellRanges ) );
- 	
-	// #FIXME need proper (WorkSheet) parent
-	return new ScVbaRange( uno::Reference< XHelperInterface >(), xContext, xRanges );
+
+    uno::Reference< XHelperInterface > xFixThisParent = excel::getUnoSheetModuleObj( xRanges ); 
+    return new ScVbaRange( xFixThisParent, xContext, xRanges );
 }
 
 css::uno::Reference< excel::XRange >
 	uno::Reference< container::XIndexAccess >  xIndex;
 	if ( mxRange.is() )
 	{
-		xIndex = new SingleRangeIndexAccess( mxContext, mxRange );
+        xIndex = new SingleRangeIndexAccess( mxParent, mxContext, mxRange );
 	}
 	else if ( mxRanges.is() )
 	{
 		xIndex.set( mxRanges, uno::UNO_QUERY_THROW );
 	}
-	m_Areas = new ScVbaRangeAreas( mxContext, xIndex, mbIsRows, mbIsColumns );
+    m_Areas = new ScVbaRangeAreas( mxParent, mxContext, xIndex, mbIsRows, mbIsColumns );
 }
 
 ScVbaRange::ScVbaRange( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< table::XCellRange >& xRange, sal_Bool bIsRows, sal_Bool bIsColumns ) throw( lang::IllegalArgumentException )
 	if  ( !xRange.is() )
 		throw lang::IllegalArgumentException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "range is not set " ) ), uno::Reference< uno::XInterface >() , 1 );
 
-	uno::Reference< container::XIndexAccess > xIndex( new SingleRangeIndexAccess( mxContext, xRange ) );
-	m_Areas = new ScVbaRangeAreas( mxContext, xIndex, mbIsRows, mbIsColumns );
+    uno::Reference< container::XIndexAccess > xIndex( new SingleRangeIndexAccess( mxParent, mxContext, xRange ) );
+    m_Areas = new ScVbaRangeAreas( mxParent, mxContext, xIndex, mbIsRows, mbIsColumns );
 
 }
 
 
 {
 	uno::Reference< container::XIndexAccess >  xIndex( mxRanges, uno::UNO_QUERY_THROW );
-	m_Areas	 = new ScVbaRangeAreas( mxContext, xIndex, mbIsRows, mbIsColumns );
+    m_Areas	 = new ScVbaRangeAreas( xParent, mxContext, xIndex, mbIsRows, mbIsColumns );
 
 }
 
 	if ( aCellRanges.Count() > 1 ) // Multi-Area
 	{
 		uno::Reference< sheet::XSheetCellRangeContainer > xRanges( new ScCellRangesObj( pUnoRangesBase->GetDocShell(), aCellRanges ) );
-		return new ScVbaRange( getParent(), mxContext, xRanges );
+		return new ScVbaRange( mxParent, mxContext, xRanges );
 	}
 	// normal range
 	uno::Reference< table::XCellRange > xRange( new ScCellRangeObj( pUnoRangesBase->GetDocShell(), *aCellRanges.First() ) );
-	return new ScVbaRange( getParent(), mxContext, xRange  );
+	return new ScVbaRange( mxParent, mxContext, xRange  );
 }
 
 uno::Reference< excel::XRange >
 		helper.getSheetCellCursor();
 	xSheetCellCursor->collapseToCurrentRegion();
 	uno::Reference< sheet::XCellRangeAddressable > xCellRangeAddressable(xSheetCellCursor, uno::UNO_QUERY_THROW);
-	return RangeHelper::createRangeFromRange( mxContext, helper.getCellRangeFromSheet(), xCellRangeAddressable );	
+    return RangeHelper::createRangeFromRange( mxParent, mxContext, helper.getCellRangeFromSheet(), xCellRangeAddressable );	
 }
 
 uno::Reference< excel::XRange >
 		helper.getSheetCellCursor();
 	xSheetCellCursor->collapseToCurrentArray();
 	uno::Reference< sheet::XCellRangeAddressable > xCellRangeAddressable(xSheetCellCursor, uno::UNO_QUERY_THROW);
-	return RangeHelper::createRangeFromRange( mxContext, helper.getCellRangeFromSheet(), xCellRangeAddressable );	
+    return RangeHelper::createRangeFromRange( mxParent, mxContext, helper.getCellRangeFromSheet(), xCellRangeAddressable );	
 }
 
 uno::Any
 	uno::Reference< table::XCellRange > xSheetRange = thisRange.getCellRangeFromSheet();
 	if( !bIsIndex && !bIsColumnIndex ) // .Cells
 		// #FIXE needs proper parent ( Worksheet )
-		return uno::Reference< excel::XRange >( new ScVbaRange( uno::Reference< XHelperInterface >(), mxContext, mxRange ) );
+		return uno::Reference< excel::XRange >( new ScVbaRange( mxParent, mxContext, mxRange ) );
 
 	sal_Int32 nIndex = --nRow;
 	if( bIsIndex && !bIsColumnIndex ) // .Cells(n)
 		--nColumn;
 	nRow = nRow + thisRangeAddress.StartRow;
 	nColumn =  nColumn + thisRangeAddress.StartColumn;	
-	return new ScVbaRange( getParent(), mxContext, xSheetRange->getCellRangeByPosition( nColumn, nRow,                                        nColumn, nRow ) );
+	return new ScVbaRange( mxParent, mxContext, xSheetRange->getCellRangeByPosition( nColumn, nRow,                                        nColumn, nRow ) );
 }
 
 void
 			throw uno::RuntimeException( rtl::OUString::createFromAscii("Internal failure, illegal param"), uno::Reference< uno::XInterface >() );
 		// return a normal range ( even for multi-selection
 		uno::Reference< table::XCellRange > xRange( new ScCellRangeObj( pUnoRangesBase->GetDocShell(), aRange ) );
-		return new ScVbaRange( getParent(), mxContext, xRange, true  );
+		return new ScVbaRange( mxParent, mxContext, xRange, true  );
 	}
 	// Rows() - no params
 	if ( m_Areas->getCount() > 1 )
-		return new ScVbaRange(  getParent(), mxContext, mxRanges, true );
-	return new ScVbaRange(  getParent(), mxContext, mxRange, true );
+		return new ScVbaRange(  mxParent, mxContext, mxRanges, true );
+	return new ScVbaRange(  mxParent, mxContext, mxRange, true );
 }	
 
 uno::Reference< excel::XRange >
 			throw uno::RuntimeException( rtl::OUString::createFromAscii("Internal failure, illegal param"), uno::Reference< uno::XInterface >() );
 	}
 	// Columns() - no params
-	//return new ScVbaRange(  getParent(), mxContext, mxRange, false, true );
 	uno::Reference< table::XCellRange > xRange( new ScCellRangeObj( pUnoRangesBase->GetDocShell(), aRange ) );
-	return new ScVbaRange( getParent(), mxContext, xRange, false, true  );
+	return new ScVbaRange( mxParent, mxContext, xRange, false, true  );
 }	
 
 void
 	xCursor->collapseToSize( nColumnSize, nRowSize );
 	uno::Reference< sheet::XCellRangeAddressable > xCellRangeAddressable(xCursor, ::uno::UNO_QUERY_THROW );
 	uno::Reference< table::XCellRange > xRange( xSheetRange->getSpreadsheet(), ::uno::UNO_QUERY_THROW );
-	return new ScVbaRange( getParent(), mxContext,xRange->getCellRangeByPosition(
+	return new ScVbaRange( mxParent, mxContext,xRange->getCellRangeByPosition(
 										xCellRangeAddressable->getRangeAddress().StartColumn,
 										xCellRangeAddressable->getRangeAddress().StartRow,
 										xCellRangeAddressable->getRangeAddress().EndColumn,
 		}
 	}
 		
-	return new ScVbaRange( getParent(), mxContext, xCellRange );
+	return new ScVbaRange( mxParent, mxContext, xCellRange );
 
 }
 
 	{
 		uno::Reference< sheet::XSheetCellRangeContainer > xRanges( new ScCellRangesObj( pUnoRangesBase->GetDocShell(), aCellRanges ) );
 		
-		return new ScVbaRange( getParent(), mxContext, xRanges, !bColumn, bColumn );
+		return new ScVbaRange( mxParent, mxContext, xRanges, !bColumn, bColumn );
 	}
 	uno::Reference< table::XCellRange > xRange( new ScCellRangeObj( pUnoRangesBase->GetDocShell(), *aCellRanges.First() ) );
-	return new ScVbaRange( getParent(), mxContext, xRange, !bColumn, bColumn  );
+	return new ScVbaRange( mxParent, mxContext, xRange, !bColumn, bColumn  );
 }
 
 uno::Reference< excel::XRange > SAL_CALL 
         }
         if ( xCellRange.is() )
         {
-            uno::Reference< excel::XRange > xResultRange = new ScVbaRange( this, mxContext, xCellRange );
+            uno::Reference< excel::XRange > xResultRange = new ScVbaRange( mxParent, mxContext, xCellRange );
             if( xResultRange.is() )
             {
                 xResultRange->Select();
 
 	ScRange aNewRange( (SCCOL)nNewX, (SCROW)nNewY, nTab, (SCCOL)nNewX, (SCROW)nNewY, nTab );
 	uno::Reference< table::XCellRange > xCellRange( new ScCellRangeObj( getScDocShell(), aNewRange ) );
-	uno::Reference< excel::XRange > xResultRange = new ScVbaRange( getParent(), mxContext, xCellRange );
+	uno::Reference< excel::XRange > xResultRange = new ScVbaRange( mxParent, mxContext, xCellRange );
 	return xResultRange;
 }
 
                 return new ColumnsRowEnumeration( mxContext, xRange, nElems );
 		
 	}
-	return new CellsEnumeration( mxContext, m_Areas );
+    return new CellsEnumeration( mxParent, mxContext, m_Areas );
 }
 
 ::rtl::OUString SAL_CALL 
 			uno::Reference< table::XCellRange > xRange = xReferrer->getReferredCells();
 			if ( xRange.is() )
 			{
-				// #FIXME need proper (WorkSheet) parent
-				uno::Reference< excel::XRange > xVbRange =  new  ScVbaRange( uno::Reference< XHelperInterface >(), xContext, xRange );
+				uno::Reference< excel::XRange > xVbRange =  new ScVbaRange( excel::getUnoSheetModuleObj( xRange ), xContext, xRange );
 				return xVbRange;
 			}
 		}
 	}
 
 	uno::Reference< table::XCellRange > xSheetRange( xSpreadsheet, uno::UNO_QUERY_THROW );
-	ScVbaRange* pRange = new ScVbaRange( uno::Reference< XHelperInterface >(), xContext, xSheetRange );
+	ScVbaRange* pRange = new ScVbaRange( excel::getUnoSheetModuleObj( xSheetRange ), xContext, xSheetRange );
 	uno::Reference< excel::XRange > xVbSheetRange( pRange );
 	return pRange->Range( Cell1, Cell2, true ); 
 }
 		// After the insert ( this range ) actually has moved
 		ScRange aRange( static_cast< SCCOL >( thisAddress.StartColumn ), static_cast< SCROW >( thisAddress.StartRow ), static_cast< SCTAB >( thisAddress.Sheet ), static_cast< SCCOL >( thisAddress.EndColumn ), static_cast< SCROW >( thisAddress.EndRow ), static_cast< SCTAB >( thisAddress.Sheet ) );
 	 	uno::Reference< table::XCellRange > xRange( new ScCellRangeObj( excel::GetDocShellFromRange( mxRange ) , aRange ) );
-		uno::Reference< excel::XRange > xVbaRange( new ScVbaRange( getParent(), mxContext, xRange, mbIsRows, mbIsColumns ) );	
+		uno::Reference< excel::XRange > xVbaRange( new ScVbaRange( mxParent, mxContext, xRange, mbIsRows, mbIsColumns ) );	
 		xVbaRange->PasteSpecial( uno::Any(), uno::Any(), uno::Any(), uno::Any() );
 	}
 }
             if( aCellAddress.StartColumn ==0 && aCellAddress.EndColumn==0 &&
                 aCellAddress.StartRow==0 && aCellAddress.EndRow==0)
             {
-                return new ScVbaRange( getParent(),mxContext,mxRange );
+                return new ScVbaRange( mxParent,mxContext,mxRange );
             }
             else
             {
                 ScRange refRange( static_cast< SCCOL >( aCellAddress.StartColumn ), static_cast< SCROW >( aCellAddress.StartRow ), static_cast< SCTAB >( aCellAddress.Sheet ), 
                                   static_cast< SCCOL >( aCellAddress.EndColumn ), static_cast< SCROW >( aCellAddress.EndRow ), static_cast< SCTAB >( aCellAddress.Sheet ) );
                 uno::Reference< table::XCellRange > xRange( new ScCellRangeObj( getScDocShell() , refRange ) );
-                return new ScVbaRange( getParent(),mxContext,xRange );
+                return new ScVbaRange( mxParent, mxContext,xRange );
             }
         }
     }
-    return new ScVbaRange( getParent(),mxContext,mxRange );
+    return new ScVbaRange( mxParent, mxContext, mxRange );
 }
 
 //2008-08-25 add by limingl
 
 	uno::Reference< table::XCellRange > xRange( new ScCellRangeObj( getScDocShell() , refRange ) );
 	
-	return new ScVbaRange( getParent(), mxContext, xRange );
+	return new ScVbaRange( mxParent, mxContext, xRange );
 }
 
 uno::Reference< excel::XRange > SAL_CALL 
 				if ( aCellRanges.First() == aCellRanges.Last() )
 				{
 					uno::Reference< table::XCellRange > xRange( new ScCellRangeObj( getScDocShell(), *aCellRanges.First() ) );
-				// #FIXME need proper (WorkSheet) parent
-					return new ScVbaRange( getParent(), mxContext, xRange );
+					return new ScVbaRange( mxParent, mxContext, xRange );
 				}
 				uno::Reference< sheet::XSheetCellRangeContainer > xRanges( new ScCellRangesObj( getScDocShell(), aCellRanges ) );
  	
-				// #FIXME need proper (WorkSheet) parent
-				return new ScVbaRange( getParent(), mxContext, xRanges );
+				return new ScVbaRange( mxParent, mxContext, xRanges );
 			}
 			else if ( bIsSingleCell )
 			{

sc/source/ui/vba/vbaworkbook.cxx

 using namespace ::ooo::vba;
 using namespace ::com::sun::star;
 
+class ActiveSheet : public ScVbaWorksheet
+{
+protected:
+	virtual uno::Reference< frame::XModel > getModel()
+	{ 	
+		return getCurrentExcelDoc( mxContext ); 
+	}
+	virtual uno::Reference< sheet::XSpreadsheet > getSheet()
+	{ 
+		uno::Reference< frame::XModel > xModel = getModel();
+		uno::Reference< sheet::XSpreadsheet > xSheet;
+		if ( xModel.is() )
+		{
+			uno::Reference< sheet::XSpreadsheetView > xSpreadsheet(
+                        	xModel->getCurrentController(), uno::UNO_QUERY );
+			if ( xSpreadsheet.is() )
+				xSheet = xSpreadsheet->getActiveSheet(); 
+		}
+		return xSheet;
+	}
+public:
+	ActiveSheet( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext ) : ScVbaWorksheet( xParent, xContext ) {}
+		
+};
+
 uno::Sequence< sal_Int32 > ScVbaWorkbook::ColorData;
 
 void ScVbaWorkbook::initColorData( const uno::Sequence< sal_Int32 >& sColors )

sc/source/ui/vba/vbaworkbooks.cxx

 #include <com/sun/star/document/XTypeDetection.hpp>
 #include <com/sun/star/uri/XUriReference.hpp>
 #include <com/sun/star/uri/XUriReferenceFactory.hpp>
+#include <com/sun/star/script/XVBACompat.hpp>
+#include <com/sun/star/script/XVBAModuleInfo.hpp>
+#include <com/sun/star/script/ModuleInfo.hpp>
+#include <com/sun/star/script/ModuleType.hpp>
 
 #include <sfx2/objsh.hxx>
 #include <tools/urlobj.hxx>
 #include <vbahelper/vbahelper.hxx>
 
 #include <hash_map>
+#include <vector>
 #include <osl/file.hxx>
 using namespace ::ooo::vba;
 using namespace ::com::sun::star;
 
 const sal_Int16 CUSTOM_CHAR = 5;
 
+void setUpDocumentModules( const uno::Reference< sheet::XSpreadsheetDocument >& xDoc )
+{
+    uno::Reference< frame::XModel > xModel( xDoc, uno::UNO_QUERY );
+    ScDocShell* pShell = excel::getDocShell( xModel );
+    if ( pShell )
+    {
+        uno::Reference<script::XLibraryContainer> xLibContainer = pShell->GetBasicContainer();
+        uno::Reference<script::XVBACompat> xVBACompat( xLibContainer, uno::UNO_QUERY_THROW );
+        xVBACompat->setVBACompatModeOn( sal_True );
+        String aPrjName( RTL_CONSTASCII_USTRINGPARAM( "VBAProject" ) );
+        pShell->GetBasicManager()->SetName( aPrjName );
+
+        if( xLibContainer.is() )
+        {
+	    if( !xLibContainer->hasByName( aPrjName ) )
+                xLibContainer->createLibrary( aPrjName );    
+            uno::Any aLibAny = xLibContainer->getByName( aPrjName );
+            uno::Reference< container::XNameContainer > xLib;
+	    aLibAny >>= xLib;
+            if( xLib.is()  )
+            {           
+                uno::Reference< script::XVBAModuleInfo > xVBAModuleInfo( xLib, uno::UNO_QUERY_THROW );
+                uno::Reference< lang::XMultiServiceFactory> xSF( pShell->GetModel(), uno::UNO_QUERY_THROW);
+                // bootstrap vbaglobals
+                 xSF->createInstance( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "ooo.vba.VBAGlobals")));
+                uno::Reference< container::XNameAccess > xVBACodeNamedObjectAccess( xSF->createInstance( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "ooo.vba.VBAObjectModuleObjectProvider"))), uno::UNO_QUERY_THROW );
+                // set up the module info for the workbook and sheets in the nealy created
+                // spreadsheet
+                ScDocument* pDoc = pShell->GetDocument();
+                String sCodeName = pDoc->GetCodeName();
+                if ( sCodeName.Len() == 0 )
+                {
+                    sCodeName = String( RTL_CONSTASCII_USTRINGPARAM("ThisWorkbook") );
+                    pDoc->SetCodeName( sCodeName );
+                }
+
+                std::vector< rtl::OUString > sDocModuleNames;
+                sDocModuleNames.push_back( sCodeName );
+
+                uno::Reference<container::XNameAccess > xSheets( xDoc->getSheets(), uno::UNO_QUERY_THROW );
+                uno::Sequence< rtl::OUString > sSheets( xSheets->getElementNames() );
+
+                for ( sal_Int32 index=0; index < sSheets.getLength() ; ++index )
+                {
+                    sDocModuleNames.push_back( sSheets[ index ] );
+                }
+
+                std::vector<rtl::OUString>::iterator it_end = sDocModuleNames.end();
+
+                for ( std::vector<rtl::OUString>::iterator it = sDocModuleNames.begin(); it != it_end; ++it )
+                {
+                    script::ModuleInfo sModuleInfo;
+    
+                    sModuleInfo.ModuleObject.set( xVBACodeNamedObjectAccess->getByName( *it ), uno::UNO_QUERY );
+                    sModuleInfo.ModuleType = script::ModuleType::DOCUMENT;
+                    xVBAModuleInfo->insertModuleInfo( *it, sModuleInfo );
+                    if( xLib->hasByName( *it ) )
+                        xLib->replaceByName( *it, uno::makeAny( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "Option VBASupport 1\n") ) ) );
+                    else
+                        xLib->insertByName( *it, uno::makeAny( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "Option VBASupport 1\n" ) ) ) );
+                }
+            }
+        } 
+    }
+}
+
 static uno::Any
-getWorkbook( uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< sheet::XSpreadsheetDocument > &xDoc, const uno::Any& aApplication )
+getWorkbook( uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< sheet::XSpreadsheetDocument > &xDoc, const uno::Reference< XHelperInterface >& xParent )
 {
 	// FIXME: fine as long as ScVbaWorkbook is stateless ...
 	uno::Reference< frame::XModel > xModel( xDoc, uno::UNO_QUERY );
 	if( !xModel.is() )
 		return uno::Any();
 	
-	ScVbaWorkbook *pWb = new ScVbaWorkbook(  uno::Reference< XHelperInterface >( aApplication, uno::UNO_QUERY_THROW ), xContext, xModel );
+	ScDocShell* pShell = excel::getDocShell( xModel );
+	if ( pShell )
+	{
+		String sCodeName = pShell->GetDocument()->GetCodeName();
+		uno::Reference< uno::XInterface > xIf = getUnoDocModule( sCodeName, pShell );
+                if ( xIf.is() )
+                {
+                    OSL_TRACE(" *** Returning Module uno Object *** ");
+                    return  uno::makeAny( xIf );
+                }
+	}
+
+	ScVbaWorkbook *pWb = new ScVbaWorkbook(  xParent, xContext, xModel );
 	return uno::Any( uno::Reference< excel::XWorkbook > (pWb) );
 }
 
 {
 	uno::Any m_aApplication;
 public:
-	WorkBookEnumImpl( const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< container::XEnumeration >& xEnumeration, const uno::Any& aApplication ) throw ( uno::RuntimeException ) : EnumerationHelperImpl( xContext, xEnumeration ), m_aApplication( aApplication ) {}
+	WorkBookEnumImpl( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< container::XEnumeration >& xEnumeration, const uno::Any& aApplication ) throw ( uno::RuntimeException ) : EnumerationHelperImpl( xParent, xContext, xEnumeration ), m_aApplication( aApplication ) {}
 
 	virtual uno::Any SAL_CALL nextElement(  ) throw (container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException) 
 	{ 
 		uno::Reference< sheet::XSpreadsheetDocument > xDoc( m_xEnumeration->nextElement(), uno::UNO_QUERY_THROW );
-		return getWorkbook( m_xContext, xDoc, m_aApplication );
+		return getWorkbook( m_xContext, xDoc, m_xParent );
 	}
 
 };
 	// safer to create an enumeration based on this objects state
 	// rather than one effectively based of the desktop component
     uno::Reference< container::XEnumerationAccess > xEnumerationAccess( m_xIndexAccess, uno::UNO_QUERY_THROW );
-	return new WorkBookEnumImpl( mxContext, xEnumerationAccess->createEnumeration(), Application() );
+	return new WorkBookEnumImpl( mxParent, mxContext, xEnumerationAccess->createEnumeration(), Application() );
 }
 
 uno::Any
 ScVbaWorkbooks::createCollectionObject( const css::uno::Any& aSource )
 {
 	uno::Reference< sheet::XSpreadsheetDocument > xDoc( aSource, uno::UNO_QUERY_THROW );
-	return getWorkbook( mxContext, xDoc, Application() );
+	return getWorkbook( mxContext, xDoc, mxParent );
 }
 
 
 ScVbaWorkbooks::Add() throw (uno::RuntimeException)
 {
     uno::Reference <sheet::XSpreadsheetDocument> xSpreadDoc( VbaDocumentsBase::Add() , uno::UNO_QUERY_THROW );
-                                                                                                                             
+
+    // need to set up the document modules ( and vba mode ) here                                
+    setUpDocumentModules( xSpreadDoc );
     if( xSpreadDoc.is() )
-        return getWorkbook( mxContext, xSpreadDoc, Application() );
+        return getWorkbook( mxContext, xSpreadDoc, mxParent );
     return uno::Any();
 }
 
 		throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Bad Format")), uno::Reference< uno::XInterface >() );
 	
 	uno::Reference <sheet::XSpreadsheetDocument> xSpreadDoc( VbaDocumentsBase::Open( rFileName, ReadOnly, sProps ), uno::UNO_QUERY_THROW );
-	uno::Any aRet = getWorkbook( mxContext, xSpreadDoc, Application() );
+	uno::Any aRet = getWorkbook( mxContext, xSpreadDoc, mxParent );
 	uno::Reference< excel::XWorkbook > xWBook( aRet, uno::UNO_QUERY );
 	if ( xWBook.is() )
 		xWBook->Activate();

sc/source/ui/vba/vbaworksheet.cxx

 	return xModel;
 }
 
-
-void ScVbaWorksheet::initDocModuleHelper()
+ScVbaWorksheet::ScVbaWorksheet( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext ) : WorksheetImpl_BASE( xParent, xContext )
 {
-    rtl::OUString aSheetName = getName();
-
-    uno::Reference <sheet::XSpreadsheetDocument> xSpreadDoc( getModel(), uno::UNO_QUERY_THROW );
-    SCTAB nTab=0;
-    bool bSheetExists = nameExists (xSpreadDoc, aSheetName, nTab);
-    ScDocShell* pDocSh = excel::getDocShell( getModel() );
-    if ( bSheetExists && pDocSh )
-    {
-        String sCodeName;
-        pDocSh->GetDocument()->GetCodeName( nTab, sCodeName );
-
-        mpDocModuleHelper = new DocModuleHelper( pDocSh->GetBasicManager(), sCodeName );
-    }
 }
-
-ScVbaWorksheet::ScVbaWorksheet( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext ) : WorksheetImpl_BASE( xParent, xContext ), mpDocModuleHelper( NULL )
+ScVbaWorksheet::ScVbaWorksheet(const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext,
+		const uno::Reference< sheet::XSpreadsheet >& xSheet, 
+		const uno::Reference< frame::XModel >& xModel ) throw (uno::RuntimeException) : WorksheetImpl_BASE( xParent, xContext ), mxSheet( xSheet ), mxModel(xModel)
 {
 }
 
-ScVbaWorksheet::ScVbaWorksheet(const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext,
-		const uno::Reference< sheet::XSpreadsheet >& xSheet, 
-        const uno::Reference< frame::XModel >& xModel ) throw (uno::RuntimeException) : WorksheetImpl_BASE( xParent, xContext ), mxSheet( xSheet ), mxModel(xModel), mpDocModuleHelper( NULL )
-
-{
-    initDocModuleHelper();
-}
-
 ScVbaWorksheet::ScVbaWorksheet( uno::Sequence< uno::Any> const & args,
-    uno::Reference< uno::XComponentContext> const & xContext ) throw ( lang::IllegalArgumentException ) :  WorksheetImpl_BASE( getXSomethingFromArgs< XHelperInterface >( args, 0 ), xContext ), mxModel( getXSomethingFromArgs< frame::XModel >( args, 1 ) ), mpDocModuleHelper( NULL )
+    uno::Reference< uno::XComponentContext> const & xContext ) throw ( lang::IllegalArgumentException ) :  WorksheetImpl_BASE( getXSomethingFromArgs< XHelperInterface >( args, 0 ), xContext ), mxModel( getXSomethingFromArgs< frame::XModel >( args, 1 ) )
 {
 	if ( args.getLength() < 2 )
 		throw lang::IllegalArgumentException();
 	uno::Reference< sheet::XSpreadsheetDocument > xSpreadDoc( mxModel, uno::UNO_QUERY_THROW );
 	uno::Reference< container::XNameAccess > xNameAccess( xSpreadDoc->getSheets(), uno::UNO_QUERY_THROW );			
 	mxSheet.set( xNameAccess->getByName( sSheetName ), uno::UNO_QUERY_THROW );
-    initDocModuleHelper();
 }
 
-ScVbaWorksheet::~ScVbaWorksheet()
-{
-    if ( mpDocModuleHelper )
-    {
-        delete mpDocModuleHelper;
-        mpDocModuleHelper = NULL;
-    }
-}
-
-
 ::rtl::OUString
 ScVbaWorksheet::getName() throw (uno::RuntimeException)
 {
 }
 
 uno::Any SAL_CALL 
-ScVbaWorksheet::invoke( const ::rtl::OUString& aFunctionName, const uno::Sequence< uno::Any >& aParams, uno::Sequence< ::sal_Int16 >& aOutParamIndex, uno::Sequence< uno::Any >& aOutParam ) throw (lang::IllegalArgumentException, script::CannotConvertException, reflection::InvocationTargetException, uno::RuntimeException)
+ScVbaWorksheet::invoke( const ::rtl::OUString& aFunctionName, const uno::Sequence< uno::Any >& /*aParams*/, uno::Sequence< ::sal_Int16 >& /*aOutParamIndex*/, uno::Sequence< uno::Any >& /*aOutParam*/ ) throw (lang::IllegalArgumentException, script::CannotConvertException, reflection::InvocationTargetException, uno::RuntimeException)
 {
-    if ( !mpDocModuleHelper )
-        throw uno::RuntimeException();
-    return mpDocModuleHelper->invoke( aFunctionName, aParams, aOutParamIndex, aOutParam  );
+	OSL_TRACE("** ScVbaWorksheet::invoke( %s ), will barf",
+		rtl::OUStringToOString( aFunctionName, RTL_TEXTENCODING_UTF8 ).getStr() );
+	
+	throw uno::RuntimeException(); // unsupported operation
 }
 
 void SAL_CALL 
 ScVbaWorksheet::setValue( const ::rtl::OUString& aPropertyName, const uno::Any& aValue ) throw (beans::UnknownPropertyException, script::CannotConvertException, reflection::InvocationTargetException, uno::RuntimeException)
 {
-    if ( !mpDocModuleHelper )
-        throw uno::RuntimeException();
-    mpDocModuleHelper->setValue( aPropertyName, aValue );
+    setDefaultPropByIntrospection( uno::makeAny( getValue( aPropertyName ) ), aValue );
 }
-
-bool lcl_hasControl( const ::rtl::OUString& aName, const uno::Reference< container::XNameAccess >& xFormControls )
-{
-    sal_Bool bRes = sal_False;
-    if ( xFormControls.is() )
-         bRes = xFormControls->hasByName( aName );
-    return bRes; 
-} 
-
 uno::Any SAL_CALL 
 ScVbaWorksheet::getValue( const ::rtl::OUString& aPropertyName ) throw (beans::UnknownPropertyException, uno::RuntimeException)
 {
-    // detect sheet controls ( which are like properties of this object )
-    if ( lcl_hasControl( aPropertyName, getFormControls() ) )
-    {  
-        uno::Reference< drawing::XControlShape > xControlShape( getControlShape( aPropertyName ), uno::UNO_QUERY_THROW );
-        
-        uno::Reference<lang::XMultiComponentFactory > xServiceManager( mxContext->getServiceManager(), uno::UNO_QUERY_THROW );
-        uno::Reference< XControlProvider > xControlProvider( xServiceManager->createInstanceWithContext( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ooo.vba.ControlProvider" ) ), mxContext ), uno::UNO_QUERY_THROW );
-        uno::Reference< msforms::XControl > xControl( xControlProvider->createControl(  xControlShape, getModel() ) );
-        return uno::makeAny( xControl );
-    }
-    if ( !mpDocModuleHelper )
-        throw uno::RuntimeException();
-    return mpDocModuleHelper->getValue( aPropertyName );
+    uno::Reference< drawing::XControlShape > xControlShape( getControlShape( aPropertyName ), uno::UNO_QUERY_THROW );
+    
+    uno::Reference<lang::XMultiComponentFactory > xServiceManager( mxContext->getServiceManager(), uno::UNO_QUERY_THROW );
+    uno::Reference< XControlProvider > xControlProvider( xServiceManager->createInstanceWithContext( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ooo.vba.ControlProvider" ) ), mxContext ), uno::UNO_QUERY_THROW );
+    uno::Reference< msforms::XControl > xControl( xControlProvider->createControl(  xControlShape, getModel() ) );
+    return uno::makeAny( xControl );
 }
 
 ::sal_Bool SAL_CALL 
-ScVbaWorksheet::hasMethod( const ::rtl::OUString& aName ) throw (uno::RuntimeException)
+ScVbaWorksheet::hasMethod( const ::rtl::OUString& /*aName*/ ) throw (uno::RuntimeException)
 {
-    if ( !mpDocModuleHelper )
-        throw uno::RuntimeException();
-    return mpDocModuleHelper->hasMethod( aName );
+	return sal_False;
 }
 
 uno::Reference< container::XNameAccess > 
 ::sal_Bool SAL_CALL 
 ScVbaWorksheet::hasProperty( const ::rtl::OUString& aName ) throw (uno::RuntimeException)
 {
-    // Controls on the sheet are exposed as properties
-    if ( lcl_hasControl( aName, getFormControls() ) )
-        return sal_True;
-    if ( !mpDocModuleHelper )
-        throw uno::RuntimeException();
-    return mpDocModuleHelper->hasProperty( aName );
+	uno::Reference< container::XNameAccess > xFormControls( getFormControls() );
+	if ( xFormControls.is() )
+		return xFormControls->hasByName( aName );
+	return sal_False;
 }
 
 uno::Any

sc/source/ui/vba/vbaworksheet.hxx

 #include <com/sun/star/container/XNamed.hpp>
 
 #include <vbahelper/vbahelperinterface.hxx>
-#include <vbahelper/vbadocmodule.hxx>
 #include "address.hxx"
 
 typedef InheritedHelperInterfaceImpl1< ov::excel::XWorksheet >  WorksheetImpl_BASE;
+
 class ScVbaWorksheet : public WorksheetImpl_BASE
 {
 	css::uno::Reference< css::sheet::XSpreadsheet > mxSheet;
 	css::uno::Reference< css::frame::XModel > mxModel;
 	css::uno::Reference< ov::excel::XChartObjects > mxCharts;
-    DocModuleHelper* mpDocModuleHelper;
-
+		
 	css::uno::Reference< ov::excel::XWorksheet > getSheetAtOffset(SCTAB offset) throw (css::uno::RuntimeException);
 	css::uno::Reference< ov::excel::XRange > getSheetRange() throw (css::uno::RuntimeException);
 
 	css::uno::Reference< css::container::XNameAccess > getFormControls();
 	css::uno::Any getControlShape( const rtl::OUString& sName );
-    void initDocModuleHelper();
 protected:
 
 	ScVbaWorksheet( const css::uno::Reference< ov::XHelperInterface >& xParent,  const css::uno::Reference< css::uno::XComponentContext >& xContext );
 		const css::uno::Reference< css::frame::XModel >& xModel )throw (css::uno::RuntimeException)  ;
 	ScVbaWorksheet( css::uno::Sequence< css::uno::Any > const& aArgs, css::uno::Reference< css::uno::XComponentContext >const& xContext ) throw ( css::lang::IllegalArgumentException );
 
-    virtual ~ScVbaWorksheet();
+	virtual ~ScVbaWorksheet() {}
 
 	virtual css::uno::Reference< css::frame::XModel > getModel()
 	{ return mxModel; }

sc/source/ui/vba/vbaworksheets.cxx

 #include "vbaglobals.hxx"
 #include "vbaworksheet.hxx"
 #include "vbaworkbook.hxx"
+#include <unonames.hxx>
 
 using namespace ::ooo::vba;
 using namespace ::com::sun::star;
 // (as added ) of the items
 typedef std::vector< uno::Reference< sheet::XSpreadsheet > >  SheetMap;
 
+
+// #FIXME #TODO the implementation of the Sheets collections sucks,
+// e.g. there is no support for tracking sheets added/removed from the collection
+
+uno::Reference< uno::XInterface > 
+lcl_getModulAsUnoObject( const uno::Reference< sheet::XSpreadsheet >& xSheet, const uno::Reference< frame::XModel >& xModel ) throw ( uno::RuntimeException )
+{
+    uno::Reference< uno::XInterface > xRet;
+    if ( !xSheet.is() )
+        throw uno::RuntimeException();
+    uno::Reference< beans::XPropertySet > xProps( xSheet, uno::UNO_QUERY_THROW );
+    rtl::OUString sName;
+    xProps->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( SC_UNO_CODENAME ) ) ) >>= sName;
+
+    ScDocShell* pShell = excel::getDocShell( xModel );
+    
+    if ( pShell )
+        xRet = getUnoDocModule(  sName, pShell );
+    return xRet;
+}
+
 class WorkSheetsEnumeration : public SheetEnumeration_BASE
 {
 	SheetMap mSheetMap;
 class SheetsEnumeration : public EnumerationHelperImpl
 {
 	uno::Reference< frame::XModel > m_xModel;
-	uno::WeakReference< XHelperInterface > m_xParent;
 public:
-	SheetsEnumeration( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< container::XEnumeration >& xEnumeration,  const uno::Reference< frame::XModel >& xModel  ) throw ( uno::RuntimeException ) : EnumerationHelperImpl( xContext, xEnumeration ), m_xModel( xModel ), m_xParent( xParent ) {}
+    SheetsEnumeration( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< container::XEnumeration >& xEnumeration,  const uno::Reference< frame::XModel >& xModel  ) throw ( uno::RuntimeException ) : EnumerationHelperImpl( xParent, xContext, xEnumeration ), m_xModel( xModel ) {}
 
 	virtual uno::Any SAL_CALL nextElement(  ) throw (container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException) 
 	{ 
 		uno::Reference< sheet::XSpreadsheet > xSheet( m_xEnumeration->nextElement(), uno::UNO_QUERY_THROW );
-		return uno::makeAny( uno::Reference< excel::XWorksheet > ( new ScVbaWorksheet( m_xParent, m_xContext, xSheet, m_xModel ) ) );
+		uno::Reference< uno::XInterface > xIf = lcl_getModulAsUnoObject( xSheet, m_xModel );
+		uno::Any aRet;
+		if ( !xIf.is() )
+                {
+			// if the Sheet is in a document created by the api unfortunately ( at the 
+			// moment, it actually wont have the special Document modules
+			uno::Reference< excel::XWorksheet > xNewSheet( new ScVbaWorksheet( m_xParent, m_xContext, xSheet, m_xModel ) );
+			aRet <<= xNewSheet; 
+                }
+                else
+			aRet <<= xIf; 
+		return aRet;
 	}
 
 };
 ScVbaWorksheets::createCollectionObject( const uno::Any& aSource )
 {
 	uno::Reference< sheet::XSpreadsheet > xSheet( aSource, uno::UNO_QUERY );
-	return uno::makeAny( uno::Reference< excel::XWorksheet > ( new ScVbaWorksheet( getParent(), mxContext, xSheet, mxModel ) ) );
+	uno::Reference< XInterface > xIf = lcl_getModulAsUnoObject( xSheet, mxModel );
+	uno::Any aRet;
+	if ( !xIf.is() )
+	{
+		// if the Sheet is in a document created by the api unfortunately ( at the 
+		// moment, it actually wont have the special Document modules
+		uno::Reference< excel::XWorksheet > xNewSheet( new ScVbaWorksheet( getParent(), mxContext, xSheet, mxModel ) );
+		aRet <<= xNewSheet;
+	}
+	else
+		aRet <<= xIf;
+	return aRet;
 }
 
 // XWorksheets

sw/source/ui/vba/vbabookmarks.cxx

 class BookmarksEnumeration : public EnumerationHelperImpl
 {
 	uno::Reference< frame::XModel > mxModel;
-	uno::WeakReference< XHelperInterface > mxParent;
 public:
-	BookmarksEnumeration( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< container::XEnumeration >& xEnumeration,  const uno::Reference< frame::XModel >& xModel  ) throw ( uno::RuntimeException ) : EnumerationHelperImpl( xContext, xEnumeration ), mxModel( xModel ), mxParent( xParent ) {}
+	BookmarksEnumeration( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< container::XEnumeration >& xEnumeration,  const uno::Reference< frame::XModel >& xModel  ) throw ( uno::RuntimeException ) : EnumerationHelperImpl( xParent, xContext, xEnumeration ), mxModel( xModel ) {}
 
 	virtual uno::Any SAL_CALL nextElement(  ) throw (container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException) 
 	{ 
 		uno::Reference< container::XNamed > xNamed( m_xEnumeration->nextElement(), uno::UNO_QUERY_THROW );
         rtl::OUString aName = xNamed->getName();
-		return uno::makeAny( uno::Reference< word::XBookmark > ( new SwVbaBookmark( mxParent, m_xContext, mxModel, aName ) ) );
+		return uno::makeAny( uno::Reference< word::XBookmark > ( new SwVbaBookmark( m_xParent, m_xContext, mxModel, aName ) ) );
 	}
 
 };

sw/source/ui/vba/vbadocuments.cxx

 {
 	uno::Any m_aApplication;
 public:
-	DocumentEnumImpl( const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< container::XEnumeration >& xEnumeration, const uno::Any& aApplication ) throw ( uno::RuntimeException ) : EnumerationHelperImpl( xContext, xEnumeration ), m_aApplication( aApplication ) {}
+	DocumentEnumImpl( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< container::XEnumeration >& xEnumeration, const uno::Any& aApplication ) throw ( uno::RuntimeException ) : EnumerationHelperImpl( xParent, xContext, xEnumeration ), m_aApplication( aApplication ) {}
 
 	virtual uno::Any SAL_CALL nextElement(  ) throw (container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException) 
 	{ 
 	// safer to create an enumeration based on this objects state
 	// rather than one effectively based of the desktop component
     uno::Reference< container::XEnumerationAccess > xEnumerationAccess( m_xIndexAccess, uno::UNO_QUERY_THROW );
-	return new DocumentEnumImpl( mxContext, xEnumerationAccess->createEnumeration(), Application() );
+	return new DocumentEnumImpl( mxParent, mxContext, xEnumerationAccess->createEnumeration(), Application() );
 }
 
 uno::Any

sw/source/ui/vba/vbarevisions.cxx

 class RevisionsEnumeration : public EnumerationHelperImpl
 {
 	uno::Reference< frame::XModel > m_xModel;
-	uno::WeakReference< XHelperInterface > m_xParent;
 public:
-	RevisionsEnumeration( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< container::XEnumeration >& xEnumeration,  const uno::Reference< frame::XModel >& xModel  ) throw ( uno::RuntimeException ) : EnumerationHelperImpl( xContext, xEnumeration ), m_xModel( xModel ), m_xParent( xParent ){}
+	RevisionsEnumeration( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< container::XEnumeration >& xEnumeration,  const uno::Reference< frame::XModel >& xModel  ) throw ( uno::RuntimeException ) : EnumerationHelperImpl( xParent, xContext, xEnumeration ), m_xModel( xModel ) {}
 
 	virtual uno::Any SAL_CALL nextElement(  ) throw (container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException) 
 	{ 

sw/source/ui/vba/vbasections.cxx

 class SectionsEnumWrapper : public EnumerationHelperImpl
 {
 	uno::Reference< frame::XModel > mxModel;
-	uno::WeakReference< XHelperInterface > mxParent;
 public:
-	SectionsEnumWrapper( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< container::XEnumeration >& xEnumeration,  const uno::Reference< frame::XModel >& xModel  ) throw ( uno::RuntimeException ) : EnumerationHelperImpl( xContext, xEnumeration ), mxModel( xModel ), mxParent( xParent ) {}
+	SectionsEnumWrapper( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< container::XEnumeration >& xEnumeration,  const uno::Reference< frame::XModel >& xModel  ) throw ( uno::RuntimeException ) : EnumerationHelperImpl( xParent, xContext, xEnumeration ), mxModel( xModel ){}
 
 	virtual uno::Any SAL_CALL nextElement(  ) throw (container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException) 
 	{ 
 		uno::Reference< beans::XPropertySet > xPageProps( m_xEnumeration->nextElement(), uno::UNO_QUERY_THROW );
-		return uno::makeAny( uno::Reference< word::XSection > ( new SwVbaSection( mxParent, m_xContext, mxModel, xPageProps ) ) );
+		return uno::makeAny( uno::Reference< word::XSection > ( new SwVbaSection( m_xParent, m_xContext, mxModel, xPageProps ) ) );
 	}
 };
 

vbahelper/inc/vbahelper/vbacollectionimpl.hxx

 class VBAHELPER_DLLPUBLIC EnumerationHelperImpl : public EnumerationHelper_BASE
 {
 protected:
+	css::uno::WeakReference< ov::XHelperInterface > m_xParent;
 	css::uno::Reference< css::uno::XComponentContext > m_xContext;
 	css::uno::Reference< css::container::XEnumeration > m_xEnumeration;
 public:
 
-	EnumerationHelperImpl( const css::uno::Reference< css::uno::XComponentContext >& xContext, const css::uno::Reference< css::container::XEnumeration >& xEnumeration ) throw ( css::uno::RuntimeException ) : m_xContext( xContext ),  m_xEnumeration( xEnumeration ) { }
+	EnumerationHelperImpl( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext >& xContext, const css::uno::Reference< css::container::XEnumeration >& xEnumeration ) throw ( css::uno::RuntimeException ) : m_xParent( xParent ), m_xContext( xContext ),  m_xEnumeration( xEnumeration ) { }
 	virtual ::sal_Bool SAL_CALL hasMoreElements(  ) throw (css::uno::RuntimeException) { return m_xEnumeration->hasMoreElements(); }
 };
 

vbahelper/inc/vbahelper/vbahelper.hxx

 				throw css::lang::IllegalArgumentException();
 			return aSomething;
 		}
+        VBAHELPER_DLLPUBLIC css::uno::Reference<  css::uno::XInterface > getUnoDocModule( const String& aModName, SfxObjectShell* pShell );
         VBAHELPER_DLLPUBLIC SfxObjectShell* getSfxObjShell( const css::uno::Reference< css::frame::XModel >& xModel ) throw ( css::uno::RuntimeException);
         VBAHELPER_DLLPUBLIC css::uno::Reference< css::uno::XInterface > createVBAUnoAPIService( SfxObjectShell* pShell,  const sal_Char* _pAsciiName ) throw (css::uno::RuntimeException);
 

vbahelper/prj/d.lst

 ..\inc\vbahelper\vbashaperange.hxx %_DEST%\inc%_EXT%\vbahelper\vbashaperange.hxx
 ..\inc\vbahelper\vbapagesetupbase.hxx %_DEST%\inc%_EXT%\vbahelper\vbapagesetupbase.hxx
 ..\inc\vbahelper\vbaeventshelperbase.hxx %_DEST%\inc%_EXT%\vbahelper\vbaeventshelperbase.hxx
-..\inc\vbahelper\vbadocmodule.hxx %_DEST%\inc%_EXT%\vbahelper\vbadocmodule.hxx

vbahelper/source/vbahelper/makefile.mk

     $(SLO)$/vbatextframe.obj \
     $(SLO)$/vbapagesetupbase.obj \
     $(SLO)$/vbaeventshelperbase.obj \
-    $(SLO)$/vbadocmodule.obj \
 
 # --- Targets -------------------------------------------------------
 

vbahelper/source/vbahelper/vbaglobalbase.cxx

 
 rtl::OUString sApplication( RTL_CONSTASCII_USTRINGPARAM("Application") );
 
+// special key to return the Application
+rtl::OUString sAppService( RTL_CONSTASCII_USTRINGPARAM("ooo.vba.Application") );
+
 VbaGlobalsBase::VbaGlobalsBase( 
 const uno::Reference< ov::XHelperInterface >& xParent, 
 const uno::Reference< uno::XComponentContext >& xContext, const rtl::OUString& sDocCtxName ) 
 VbaGlobalsBase::createInstance( const ::rtl::OUString& aServiceSpecifier ) throw (uno::Exception, uno::RuntimeException)
 {
     uno::Reference< uno::XInterface > xReturn;
-
-    if ( hasServiceName( aServiceSpecifier ) )
+    if ( aServiceSpecifier.equals( sAppService ) )
+    {
+        // try to extract the Application from the context
+        uno::Reference< container::XNameContainer > xNameContainer( mxContext, uno::UNO_QUERY );
+        xNameContainer->getByName( sApplication ) >>= xReturn;
+    }
+    else if ( hasServiceName( aServiceSpecifier ) )
         xReturn = mxContext->getServiceManager()->createInstanceWithContext( aServiceSpecifier, mxContext );
     return xReturn;
 }
 
 uno::Reference< uno::XInterface > SAL_CALL 
-VbaGlobalsBase::createInstanceWithArguments( const ::rtl::OUString& ServiceSpecifier, const uno::Sequence< uno::Any >& Arguments ) throw (uno::Exception, uno::RuntimeException)
+VbaGlobalsBase::createInstanceWithArguments( const ::rtl::OUString& aServiceSpecifier, const uno::Sequence< uno::Any >& Arguments ) throw (uno::Exception, uno::RuntimeException)
 {
     
     uno::Reference< uno::XInterface > xReturn;
-    if ( hasServiceName( ServiceSpecifier ) )
-        xReturn = mxContext->getServiceManager()->createInstanceWithArgumentsAndContext( ServiceSpecifier, Arguments, mxContext );
+    if ( aServiceSpecifier.equals( sAppService ) )
+    {
+        // try to extract the Application from the context
+        uno::Reference< container::XNameContainer > xNameContainer( mxContext, uno::UNO_QUERY );
+        xNameContainer->getByName( sApplication ) >>= xReturn;
+    }
+    else if ( hasServiceName( aServiceSpecifier ) )
+        xReturn = mxContext->getServiceManager()->createInstanceWithArgumentsAndContext( aServiceSpecifier, Arguments, mxContext );
     return xReturn;
 }
 

vbahelper/source/vbahelper/vbahelper.cxx

 	void SAL_CALL VBADispatchListener::disposing( const lang::EventObject& /*aEvent*/ ) throw( uno::RuntimeException )
 	{
 	}
-        
+
+        uno::Reference< uno::XInterface > getUnoDocModule( const String& aModName, SfxObjectShell* pShell )
+        {
+            uno::Reference<  uno::XInterface > xIf;
+            if ( pShell )
+            {
+                rtl::OUString sProj( RTL_CONSTASCII_USTRINGPARAM("Standard") );
+                BasicManager* pBasMgr = pShell->GetBasicManager();
+                if ( pBasMgr && pBasMgr->GetName().Len() )
+                    sProj = pShell->GetBasicManager()->GetName();
+                StarBASIC* pBasic = pShell->GetBasicManager()->GetLib( sProj );
+                if ( pBasic )
+                {
+                    SbModule* pMod = pBasic->FindModule( aModName );
+                    if ( pMod )
+                        xIf = pMod->GetUnoModule();
+                }
+            }             
+            return xIf;
+        }