Schnittstelle VBA - C++



  • Hallo Freunde,

    ich wollte mal ein Thema diskutieren, an dem ich schon länger dran bin.

    Ich habe ein relativ großes Programm mit VBA. Nun möchte ich eine Routine, die mir zu lange dauert, gerne auslagern. Um ein Maximum an Geschwindigkeit zu bekommen, würde ich dieses gerne in C++ rechnen lassen. Tests mits VB, C# und C++ im Vergleich haben ergeben, dass C++ die schnellste Sprache ist.

    Die Frage ist jetzt, wie ich dies am Besten anstelle. Meine erste Idee war eine .dll zu schreiben, die aus VBA aufgerufen wird. Allerdings würde ich gerne mit dem GCC Complier 64 bit compilieren. Wie man mit diesem eine DLL erstellt, habe ich nigends gefunden...

    Die Zweite Frage ist, ob man eine EXE generiert, die aus VBA aufgerufen wird. Aber wie kann man dann die Variablen (mehrere Matrizen) übergeben und wie bekommen ich die Ausgabe (Matrix) zurück?

    Ich hatte die Idee dies über eine Ein- und Ausgabe über CSV-Dateien zu machen, sehe dies aber eher als unschöne Notlösung.

    Vielleicht habt Ihr ja noch Ideen und Anregungen...

    Danke schonmal!

    Bitte keine Vorträge, dass VBA langsam und Mist ist, daraum geht es nicht.



  • ootobbyoo schrieb:

    Meine erste Idee war eine .dll zu schreiben, die aus VBA aufgerufen wird.

    Dazu sollte es im Web genügend Beispiele geben. Früher zu Zeiten von VB6 war das weit verbreitet. Da hab ich es auch zuletzt gemacht.

    ootobbyoo schrieb:

    64 bit compilieren

    Ob 32 oder 64 Bit hängt vom aufrufenden Programm ab, die DLL muss dazu passen.

    ootobbyoo schrieb:

    Allerdings würde ich gerne mit dem GCC Complier

    Keine Ahnung.



  • Hi,

    ist nicht schwer. In C++ einfach mit __declspec(dllexport) und extern "C" (braucht man, glaube ich) die benötigten Funktionen in eine DLL auslagern, das ist der erste Teil.

    In Excel dann in der VBA-Datei:

    Declare Function nameDerFunktion Lib "C:\Dingsbums.dll" (ByVal parameter1 As String, ByVal parameter2 As String, ByVal parameter3 As String, ByVal parameter4 As String) As Double
    

    Dann kannst Du in einer Excel-Zelle schreiben:
    =nameDerFunktion("Hallo"; "Banane"; "Gurke"; "Aubergine")

    und erhältst das Ergebnis.



  • Hier hatten wir kürzlich einen Thread dazu

    http://www.c-plusplus.net/forum/313976-full

    Da hatten wir den Builder und VC++, zum GCC unter Windows kann ich nichts sagen.



  • erstmal danke für die Antworten

    Eisflamme schrieb:

    Hi,

    ist nicht schwer. In C++ einfach mit __declspec(dllexport) und extern "C" (braucht man, glaube ich) die benötigten Funktionen in eine DLL auslagern, das ist der erste Teil.

    In Excel dann in der VBA-Datei:

    Declare Function nameDerFunktion Lib "C:\Dingsbums.dll" (ByVal parameter1 As String, ByVal parameter2 As String, ByVal parameter3 As String, ByVal parameter4 As String) As Double
    

    Dann kannst Du in einer Excel-Zelle schreiben:
    =nameDerFunktion("Hallo"; "Banane"; "Gurke"; "Aubergine")

    und erhältst das Ergebnis.

    ist es dann auch möglich die Variablen in Form eines Arrays zu übergeben???

    Compiliere immer mit diesem GCC: http://tdm-gcc.tdragon.net/download



  • ootobbyoo schrieb:

    ist es dann auch möglich die Variablen in Form eines Arrays zu übergeben???

    Ja, siehe hier, letzter Beitrag
    http://www.ms-office-forum.net/forum/showthread.php?t=103664



  • Ok, vielen Dank für die vielen Anregungen. Ich werde dann mal versuchen etwas umzusetzen und mich ggf. wieder melden...



  • also meine Test-Funktion sieht folgendermaßen aus:

    extern  "C" __declspec(dllexport) double _stdcall square(double & x);
    
    double _stdcall square(double & x)
    {
    	return x*x;
    }
    

    dann braucht man wohl noch ein def-File:

    LIBRARY "square"
    EXPORTS
    square
    

    dann muss man das ganze noch verlinken. hab ich nach dieser anleitung gemacht:
    http://www.forexfactory.com/showthread.php?p=5250053#post5250053

    In VBA dann:

    Declare Function square _
    Lib "E:\C++\dll_datei\Release\square.dll" (ByRef x As Double) As Double
    

    leider läuft es dann in VBA nicht. Die Function taucht zwar auf, aber es erscheint "#WERT!" in der Zelle... Hab ich nen Fehler gemacht?



  • ALSO,

    erstmal kann man mit mit Excel 32 bit keine 64 bit dll aufrufen. Der GCC kann aber mit dem Befehl "-m32" auch auf 32 bit comilieren.

    Dann muss der Name der Function in VBA und der Name der Function in C++ gleich sein!!! Und dann war wohl noch an der Syntax was falsch.

    Hab auf jeden Fall eine Lösung gefunden, die dann so aussieht:

    function.cpp:

    extern "C" __declspec(dllexport) double __stdcall square(double x)
    {
        return x*x;
    }
    

    deffile.def:

    LIBRARY "square"
    EXPORTS
    square
    

    Compiler & Linker:

    g++ -m32
    

    und in VBA dann

    Option Explicit
    
    Declare Function square Lib "E:\C++\dll_datei\Release\dll_datei.dll" (ByVal d As Double) As Double
    
    Sub x()
       Dim zw As Double
       zw = square(10)
       MsgBox zw
    End Sub
    

    Und jetzt das ganze mit Arrays...



  • ok, wie in der geposteten Anleitung klappt es:

    extern "C" __declspec(dllexport) double* __stdcall square(double zw[10])
    {
    	zw[5] = 5;
    	return zw;
    }
    

    gleiches def-File wie vorher

    und in VBA:

    Declare Function square Lib "E:\C++\dll_datei_array\Release\dll_datei_array.dll" (ByVal zw As Long) As Long
    
    Sub test()
        Dim zw(10) As Double
        Call square(VarPtr(zw(0)))
        MsgBox zw(5)
    End Sub
    

    VIELEN DANK!!!


Log in to reply