Über DDE an Excel Befehle senden (mit C++)
-
Hallo !
Ich bin dabei mich mit DDE in C++ etwas zu beschäftigen. Ich weiss, dass das eine altmodische und superkomplizierte Sache ist, aber trotzdem WILL ich das schaffen !
Ich hoffe es kennt sich jemand von euch etwas damit aus.
Also, aufgrund eines Artikels hier im Forum habe ich einen Link gefunden, der auf ein DDE Beispiel auf der Microsoft-Seite gezeigt hat. Das Beispiel habe ich ausprobiert, und . . . es hat nicht geklappt.Jetzt habe ich mir das Beispiel auseinanderklmüsert, und ich schaffe es tatsächlich, dass mir aus meiner Konsolenanwendung Zeichen in die Exceltabelle geschrieben werden.
Jetzt würde ich es aber auch gerne schaffen, dass Befehle aus meiner Anwendung an Excel ausgeführt werden. Zum Beispiel so etwas wie eine Bestimmte Zelle auswählen, und die dann farbig machen.
Naja, hier ist erst mal das Programm, was ich mir zusammengestückelt habe.
Bitte keine Kommentare zu den Kommentaren, denn die sind ja nur für mich
:Ich habe die Stelle, um die es geht noch mal im Quelltext genauer beschrieben (ganz unten).
#include "StdAfx.h" #include <windows.h> #include <ddeml.h> #include <stdio.h> HDDEDATA CALLBACK DdeCallback( UINT uType, // Transaction type. UINT uFmt, // Clipboard data format. HCONV hconv, // Handle to the conversation. HSZ hsz1, // Handle to a string. HSZ hsz2, // Handle to a string. HDDEDATA hdata, // Handle to a global memory object. DWORD dwData1, // Transaction-specific data. DWORD dwData2) // Transaction-specific data. { return 0; } // Die Funktion DDEExecute wird aufgerufen, nachdem eine Anwendung alles // ausgeführt hat, was sie benötigt, um über DDE Daten mit einer anderen // Anwendung auszutauschen. // Das heißt DDE muss initialisiert sein, und die Client Anwendung muss // mit einem Server in Verbindung stehen (ein DDE Kanal muss aufgebaut sein) // Das braucht man, weil man zum endgültigen Datenaustausch Parameter aus der // Initialisierung, und die Kanalnummer braucht, damit die Daten überhaupt // wissen, wo sie hin müssen. // Der Funktion wir als erster Parameter die Clientaplikationsinstanznummer // übergeben. Als zweiten Parameter die DDE-Kanal Nummer, und als dritten // Parameter das Kommando, was in der Serveraplikation ausgeführt werden soll. void DDEExecute(DWORD idInst, HCONV hConv, char* szCommand) { HDDEDATA hData = DdeCreateDataHandle(idInst, (LPBYTE)szCommand, lstrlen(szCommand)+1, 0, NULL, CF_TEXT, 0); if (hData==NULL) { printf("Command failed: %s\n", szCommand); } else { printf("Daten muessten eigentlich unterwegs sein !\n"); DdeClientTransaction((LPBYTE)hData, 0xFFFFFFFF, hConv, 0L, 0, XTYP_EXECUTE, TIMEOUT_ASYNC, NULL); } } int main() { // szApp und szToppic brauche ich, um die Verbindng zu einem DDE Server // herzustellen, der gestartet ist. Mit szApp wird der Server // beschrieben. In diesem Fall ist das Excel. Und das Topic ist // eine Exceltabelle char szApp[] = "EXCEL"; char szTopic[] = "C:\\Test.xls"; char szCommand[] = "HALLO"; UINT iReturn; DWORD idInst=0; // Hier wird DDE initialisiert. Ohne diese Initialisierung läuft nichts! // Wenn alles gut geht, dann gibt die Funktion DMLERR_NO_ERROR (0) // an iReturn zurück. // Es wird mit dieser Funktion dem Betriebssystem mitgeteilt, das // diese Anwendung beabsichtigt mit anderen Anwendungen Daten // auszutauschen. iReturn = DdeInitialize(&idInst, (PFNCALLBACK)DdeCallback, APPCLASS_STANDARD | APPCMD_CLIENTONLY, 0 ); if (iReturn==DMLERR_NO_ERROR) { printf("Die Aplikationsinstanznummer von DdeInitialize; 0x%04x\n", idInst); printf("DDE Initialisierung gelungen: 0x%04x\n", iReturn); Sleep(1500); } // Hier wird jetzt der DDE Server - eine Excel Tabelle - gestartet, // dem man Daten senden, oder von dem man Daten holen möchte HINSTANCE hRet = ShellExecute(0, "open", "C:\\Test.xls", 0, 0, SW_HIDE); if ((int)hRet > 32) { printf("DDE Server gestartet: 0x%04x\n", hRet); Sleep(1500); } // Wenn DDE initialisiert ,und ein DDE Server gestartet wurde, // geht es jetzt darum, das sich die Clientanwendung (diese hier) // mit dem gewünschten Server verbindet. Dazu wird der Name des Servers // (in diesem Fall szApp) und das Topic der Verbindung (in diesem Fall // szTopic) bekannt gegeben, und darauf gewartet, dass sich der entsprechende // Server meldet, so dass die Verbindung aufgebaut werden kann. // In diesem Fall wird sich der Server ja hoffentlich melden, denn er // wurde mit der vorigen Funktion ja gestartet. HSZ hszApp, hszTopic; // Hier werden DDE-String Variabeln erstellt, die // als Rückgabewert für die DdeCreateStringHandle- // Funktion benötigt werden. // Für spezielle DDE-Funktionen werden nämlich // spezielle DDE-Strings benötigt. HCONV hConv; // Hier wird ein Handle auf eine DDE Verbindung erstellt, // der als Rückgabewert der Funktion DdeConnect gebraucht // wird. Beide Typen (HSZ und HCONV) sind spezielle Win32 // Datentypen. // Hier werden die HSZ-Variabeln mit der DdeCreateStringHandle-Funktion // erstellt. hszApp = DdeCreateStringHandle(idInst, szApp, 0); hszTopic = DdeCreateStringHandle(idInst, szTopic, 0); // Hier wird die Clientanwendung mit der gewünschten Serveranwendung // verbunden, und die Verbindung in dem HCONV-Handle abgespeichert. hConv = DdeConnect(idInst, hszApp, hszTopic, NULL); // Die DDE-String-Handles haben ihre Schuldigkeit mit der Client-Server- // Verbindung getan, und werden nun wieder zerstört, um Speicher zu sparen // (glaube ich). DdeFreeStringHandle(idInst, hszApp); DdeFreeStringHandle(idInst, hszTopic); // Wenn bis hierhin alles geklappt hat, dann ist der HCONV-Handle !=0, // und es wird eine entsprechende Meldung ausgegeben. if (hConv != NULL) { printf("DDE Verbindung zwischen Client und Server hat geklappt.\n"); Sleep(1500); } // Jetzt kann es eigentlich mit dem Datenaustausch losgehen ! // Es wird DDEExecute augerufen: Beschreibung siehe oben bei der // Implementierung // AN DIESER STELLE IST DAS PROBLEM: WENN ICH EINEN NORMALEN STRING // ÜBERGEBE, DANN WIRD DER AUCH IN DIE AKTIVE ZELLE IN EXCEL GESCHRIEBEN: // WENN ICH ABER VERSUCHE EINEN BEFEHL ZU ÜBERGEBEN; DER SO AUSSIEHT: // char szCommand[] = "[ActiveCell.FormulaR1C1 = \"Q\"]"; // ODER SO: // char szCommand[] = "[Range(\"A6\").Select]"; // DANN TUT SICH GAR NIX. // DER EINZIGE BEFEHL, DER KLAPPT IST DIESER HIER: // char szCommand[] = "[APP.MINIMIZE()]"; DDEExecute(idInst, hConv, szCommand); return 0; }Lange Rede kurzer Sinn: Weiß einer von euch, wie ich Befehle zu Excel rüberschicke, damit die auch ausgeführt werden ?
Habe übrigens Excel 2000.
Vielen Dank schon mal
Maik
-
Dieser Thread wurde von Moderator/in kingruedi aus dem Forum Rund um die Programmierung in das Forum WinAPI verschoben.
Im Zweifelsfall bitte auch folgende Hinweise beachten:
C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?Dieses Posting wurde automatisch erzeugt.
-
Dieser Beitrag wurde gelöscht!