Excel Automatisierung



  • Hey ho,

    versuche mich gerade daran Excel aus einer MFC (dialogbasierenden Anwendung) heraus zu starten.
    Das funzt soweit ganz gut. Kann auch Macros des Workbooks ausführen und so weiter.
    Realisiert wird das ganze mit der Typbibliothek von Excel (excel9.olb). Diese wurde mit dem Klassenassistenten der MFC gewählt, der wiederum eine neue Klasse mit den nötigen Funktionen und Objekten erzeugt hat.
    Das einzige was nicht funzt ist die Reaktion auf Events.

    Habe das mal nach Anleitung von Microsoft gemacht (http://support.microsoft.com/kb/q183599/).
    Das ganze ist zwar für Word geschrieben (was auch wunderbar funzt), sollte aber für Excel genauso klappen. Dachte ich...
    Habe folgende Änderungen gegenüber Microsofts Tut für Word gemacht:
    (ich schreibe mal absichtlich nur die Veränderungen hin, da der Code sonst dem von Microsoft entspricht)

    //....
    
          // Start Automation server.
          COleException e;
          if(!m_app.CreateDispatch("Excel.Application.9", &e)) {
             sprintf(buf, "Error on CreateDispatch(): %ld (%08lx)",
               e.m_sc, e.m_sc);
             AfxMessageBox(buf, MB_SETFOREGROUND);
             return;
    
          }
    
          // ....
    
          // Declare the events you want to catch.
    
          // {00024413-0000-0000-C000-000000000046}
          static const GUID IID_IExcel9AppEvents =
          {0x00024413,0x000,0x0000,{0xc0,0x00,0x0,0x00,0x00,0x00,0x00,0x46 } };
    
          // Find connection point for events you're interested in.
          hr = pConnPtContainer->FindConnectionPoint(
             IID_IExcel9AppEvents,
             &m_pConnectionPoint
          );
          ASSERT(!FAILED(hr));
    
          //....
    

    Das wäre der Hauptteil gewesen. In der Klasse "MyEventSink" kann ich nun Events aufnehemen.
    Das sieht dann am ende etwa so aus:

    (MyEventSink.h)
    
    class MyEventSink : public CCmdTarget
    {
    	DECLARE_DYNCREATE(MyEventSink)
    
    	MyEventSink();           // Dynamische Erstellung verwendet geschützten Konstruktor
    
    // Attribute
    public:
    
    // Operationen
    public:
    
    // Überschreibungen
    	// Vom Klassen-Assistenten generierte virtuelle Funktionsüberschreibungen
    	//{{AFX_VIRTUAL(MyEventSink)
    	public:
    	virtual void OnFinalRelease();
    	//}}AFX_VIRTUAL
    
        virtual ~MyEventSink();
    // Implementierung
    protected:
    //	virtual ~MyEventSink();
    
    	// Generierte Nachrichtenzuordnungsfunktionen
    	//{{AFX_MSG(MyEventSink)
    		// HINWEIS - Der Klassen-Assistent fügt hier Member-Funktionen ein und entfernt diese.
    	//}}AFX_MSG
    
    	DECLARE_MESSAGE_MAP()
    	// Generierte OLE-Dispatch-Zuordnungsfunktionen
    	//{{AFX_DISPATCH(MyEventSink)
    	afx_msg void WorkbookNewSheet();
    	//}}AFX_DISPATCH
    	DECLARE_DISPATCH_MAP()
    	DECLARE_INTERFACE_MAP()
    };
    
    (MyEventSink.cpp)
    
    //.....
    
    BEGIN_MESSAGE_MAP(MyEventSink, CCmdTarget)
    	//{{AFX_MSG_MAP(MyEventSink)
    		// HINWEIS - Der Klassen-Assistent fügt hier Zuordnungsmakros ein und entfernt diese.
    	//}}AFX_MSG_MAP
    END_MESSAGE_MAP()
    
    BEGIN_DISPATCH_MAP(MyEventSink, CCmdTarget)
    	//{{AFX_DISPATCH_MAP(MyEventSink)
    	DISP_FUNCTION_ID(MyEventSink, "WorkbookNewSheet", 1573 , WorkbookNewSheet, VT_EMPTY, VTS_NONE)
    	//}}AFX_DISPATCH_MAP
    END_DISPATCH_MAP()
    
    static const IID IID_IMyEventSink =
    { 0x00024413, 0x000, 0x0000, {0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46} };
    
    BEGIN_INTERFACE_MAP(MyEventSink, CCmdTarget)
    	INTERFACE_PART(MyEventSink, IID_IMyEventSink, Dispatch)
    END_INTERFACE_MAP()
    
    /////////////////////////////////////////////////////////////////////////////
    // Behandlungsroutinen für Nachrichten MyEventSink 
    
    void MyEventSink::WorkbookNewSheet() 
    {
      AfxMessageBox("Hallo");
    }
    

    Wie man sehen kann nutze ich zum mappen der Messages die Funktion "DISP_FUNCTION_ID", diese wird benötigt um die Messages anhand von den DISPIDs eindeutig zu identifizieren. (WorkbookNewSheet besitzt demzufolge die DISPID 1573)

    Leider, funktioniert es nicht 😞
    Und ich bin langsam am verzweifeln. Egal welches Event ich aufnehme, mein Code fängt sie einfach nicht ab. Sonst funktioniert wie gesagt alles wunderbar.

    Hat hier jemand ein bissl mehr Erfahrung als ich und kann mir weiterhelfen.?

    Mfg Schwabi


Anmelden zum Antworten