In diesem Tutorial werden zwei Themen behandelt, die nicht mehr in das Buch aufgenommen wurden:
Diese Themen haben bereits mit Visual Basic 5.0 an Bedeutung verloren, aus unterschiedlichen Gründen. Der Datenaustausch per DDE wird in vielen Fällen durch den direkten Zugriff auf die Komponenten einer Anwendung ersetzt. Das sicherlich beste Beispiel ist Microsoft Word, wo es ab Version 6.0 sehr viel einfacher ist, direkt auf die einzelnen Komponenten zuzugreifen als über DDE. Interessant ist, daß der Explorer bis Windows 95 nicht direkt über Komponenten angesprochen werden kann, hier kann DDE nach wie vor der direktere Weg sein. Das OLE-Steuerelement wird bei Visual Basic selten benötigt, da es ganz einfach selten eine Notwendigkeit gibt, Dokumentobjekte in ein Formular einzubetten. Da sowohl DDE als auch dasOLE-Steuerelement den einen oder anderen Lesern nach wie vor interessieren können, werden beide Themen auf diese Weise zur Verfügung gestellt. Bitte beachten Sie, daß die Beispiele nicht mit Visual Basic 6.0 geprüft wurden, sie sollten aber in nahezu allen Fällen problemlos funktionieren.
Für den Fall, daß sich zwei Anwendungen miteinander unterhalten möchten, stellt Windows den Dynamic Data Exchange (DDE) zur Verfügung. Es sei allerdings vorangestellt, daß DDE als Kommunikationsform immer mehr aus der Mode kommt und durch den direkten Zugriff auf die Komponenten einer Anwendung (Stichwort: OLE-Automation) abgelöst wird (dies gilt besonders für das Versenden von internen Kommandos über die LinkExecute-Methode). Allerdings ist DDE für einfache Dinge noch bestens geeignet, zumal über das NetDDE ein relativ ausgereifter Mechanismus für den Datenaustausch im Netzwerk zur Verfügung, während diese Option über DCOM nur mit der Enterprise-Edition genutzt werden kann.
DDE ist ein Protokoll, dessen Implementation auf der API-Ebene sehr aufwendig ist. Visual Basic bietet dagegen einen relativ problemlosen Zugriff auf den Datenaustausch per DDE. Vielleicht sind Ihnen bei einem Steuerelement schon einmal die Eigenschaften LinkTopic, LinkMode und LinkItem aufgefallen? Genau diese Eigenschaften sind für den Aufbau einer DDE-Verbindung zuständig.
Was ist DDE?
Dynamic Data Exchange (DDE) ist ein in manchen Fällen sehr praktischer und innerhalb eines Visual Basic-Programms leicht zu handhabender Mechanismus, den einen Datenaustausch zwischen zwei Programmen ermöglicht. Da DDE von Anfang ein fester Bestandteil von Windows war, hat sich auch an der DDE-Unterstützung seit Visual Basic Version 1.0 nichts geändert. An einer DDE-Kommunikation sind stets zwei Programme beteiligt, die als Quellanwendung (engl. "source"), dort kommen die Daten her, und als Zielanwendung (engl. "destination"), dort wandern die Daten hin, bezeichnet werden. Es sei bereits darauf hingewiesen, daß ein Visual Basic-Programm gleichzeitig mit mehreren Programmen eine DDE-Verbindung (engl. "DDE link") aufrecht erhalten und dabei gleichzeitig die Rolle einer Quell- als auch einer Zielanwendung spielen kann.
Die Schwierigkeit beim Verständnis von DDE liegt ein wenig darin, die Bedeutung der einzelnen Eigenschaften auseinander zu halten. So leitet sich die Bedeutung von Eigenschaften wie LinkItem und LinkTopic nicht unbedingt aus ihrem Namen ab. Klar ist dagegen, daß alle Eigenschaften, die die Vorsilbe "Link" besitzen, etwas mit DDE zu tun haben. Sobald Sie aber zwei oder drei Beispiele ausprobiert haben, sollte es für Sie kein Problem mehr sein, ein Visual Basic-Programm "DDE fähig" zu machen.
Eigenschaft |
Bedeutung |
LinkItem |
Legt den Namen des Steuerelements fest, das die DDE-Daten auf dem Quellformular zur Verfügung stellt. |
LinkMode |
Legt fest, in welchem Modus die DDE-Konversation (automatisch oder manuell) ausgeführt wird. Diese Eigenschaft hat bei dem Quellformular und bei den Steuerelementen in der Zielanwendung eine unterschiedliche Bedeutung. Bei dem Formular muß diese Eigenschaft bereits zur Entwurfszeit den Wert 1 (Source) erhalten, damit das Formular an einer DDE-Konversation teilnehmen kann. Bei dem Steuerelement legt LinkMode fest, auf welche Weise die DDE-Konversation stattfindet. |
LinkTimeOut |
Gibt eine Zeitdauer in Zehntelsekunden an, die ein Steuerelement auf die Antwort der DDE-Quelle wartet. Die Standardeinstellung ist 50 (5 Sekunden), wird der Wert 1 eingetragen, wartet das Steuerelement den Maximalwert von 65.535 Sekunden bzw. 1 Stunde 49 Minuten. |
LinkTopic |
Legt bei der Quellanwendung den Namen des Programms und das Thema der Konversation fest. Letzterer muß mit dem Wert der LinkTopic-Eigenschaft des Quellformulars identisch sein. Beide Angaben werden durch einen Schrägstrich (z.B. Wetter|frmWetter) voneinander getrennt. |
Tabelle: Eigenschaften, die bei DDE eine Rolle spielen
Methode |
Bedeutung |
LinkExecute |
Sendet einen Kommandostring von der Zielanwendung an die Quellanwendung. Dieser muß innerhalb der LinkExeceute-Ereignisprozedur des Quellformulars interpretiert werden und kann daher eine beliebige Bedeutung haben. |
LinkPoke |
Sendet den Inhalt des Steuerelements der Zielanwendung an das über die LinkItem-Eigenschaft zugeordnete Steuerelement in der Quellanwendung und aktualisiert damit dessen Inhalt. Die DDE-Übertragung findet hier in der umgekehrten Richtung statt. |
LinkRequest |
Wird in der Zielanwendung durchgeführt und fordert im manuellen Modus (LinkMode=2 oder LinkMode=3) die aktuellen Daten des zugeordneten Steuerelements in der Quellanwendung an. |
LinkSend |
Wird von einem Bildfeld in der Quellanwendung ausgeführt, um das über die LinkItem-Eigenschaft verbundene Bildfeld in der Ziielanwendung zu aktualisieren. Diese Methode muß auch bei LinkMode=1 aufgerufen werden, da ein automatisches Aktualisieren eines Bildfeldes die Programmausführung stark verlangsamen würde. |
Tabelle: Methoden, die bei DDE eine Rolle spielen
Ereignis |
Bedeutung |
LinkClose |
Wird bei dem Steuerelement in der Zielanwendung und dem Formular der Quellanwendung ausgeführt, wenn die DDE-Konversation beendet wird. |
LinkError |
Wird ausgelöst, wenn während der DDE-Konversation ein Fehler auftrat, der nicht über einen Laufzeitfehler abgefangen wird. |
LinkExecute |
Wird bei einem Formular der Zielanwendung ausgeführt, wenn diese von der Zielanwendung über die LinkExecute-Methode einen (beliebigen) Kommandostring erhält. Auf diese Weise kann die Quellanwendung an die Zielanwendung Kommandos schicken und damit "fernsteuern". |
LinkOpen |
Wird bei dem Steuerelement in der Zielanwendung und dem Formular der Quellanwendung ausgeführt, wenn die DDE-Konversation startet. Über den Cancel-Parameter kann die Zielanwendung die DDE-Übertragung ablehnen. |
LinkNotify |
Wird bei einem Steuerelement der Zielanwendung ausgelöst, wenn sich die Daten in der Quellanwendung geändert haben. Auf diese Weise wird das Steuerelement davon unterrichtet, daß es sich neue Daten bei dem Steuerelement der Quellanwendung abholen kann. |
Tabelle: Ereignisse, die bei DDE eine Rolle spielen
In einem Visual Basic-Programm können nur Bezeichnungsfelder, Bildfelder und Textfelder an einer DDE-Konversation teilnehmen. Da sich diese auf einem Formular befinden müssen, ist auf der Seite der Quellanwendung auch das Formular beteiligt. Bei einer DDE-Konversation beginnt stets die Zielanwendung, die Daten erhalten möchte, mit einer Anfrage bei der Quellanwendung, ob diese bereit ist, Daten zu schicken. Dazu muß die Zielanwendung über die Eigenschaften LinkTopic und LinkItem drei Dinge angeben:
Auf der Seite der Quellanwendung muß lediglich über die LinkMode-Eigenschaft des Formulars sichergestellt werden, daß diese automatisch (oder manuell) auf eine DDE-Anfrage reagieren kann.
Beispiel
Die folgenden Anweisungen bereiten das Bezeichnungsfeld lblTemperatur für eine DDE-Konversation vor:
lblTemperatur.LinkTopic = "Wetter|frmWetterTopic"
lblTemperatur.LinkItem = "lblTemperatur_Quelle"
lblTemperatur.LinkMode = 0
Dies ist ein Auszug aus dem nächsten Beispielprogramm, bei dem zwischen dem Bezeichnungsfeld auf einem Formular und dem Bezeichnungfeld einer anderen Anwendung eine DDE-Konversation stattfindet. Die LinkTopic-Eigenschaft besteht immer aus zwei (!) Komponenten, die durch einen senkrechten Strich (ANSI-Code 124) getrennt werden müssen:
Anwendung | Thema
Bei Anwendung handelt es sich um den Namen der Quellanwendung, d.h. entweder um den Namen der Exe-Datei (ohne Dateiweiterung) oder den Projektnamen, falls die Quellanwendung noch in der Entwicklungsumgebung ausgeführt wird. Das "Thema" der DDE-Konversation ist ganz einfach die LinkTopic-Eigenschaft des Formulars. Standardmäßig trägt Visual Basic hier den Standardnamen des Formulars (z.B. Form1) ein. Es ist jedoch sinnvoll, hier einen anderen, eindeutigen Namen einzutragen. Die Bedeutung der LinkItem-Eigenschaft ist schnell erklärt, sie steht ganz einfach für den Namen jenes Steuerelements, von dem die Daten stammen, im obigen Beispiel lblTemperatur_Quelle (der Zusatz "_Quelle" soll lediglich die Rolle des Bezeichnungsfeld unterstreichen). Noch einfacher läßt sich die LinkMode-Eigenschaft erklären. Sie startet oder stoppt eine DDE-Übertragung. Besitzt sie den Wert 0, findet keine Übertragung statt, besitzt sie den Wert 1, verläuft die DDE-Konversation vollautomatisch.
Übung 1 und 2
In der folgenden Übung soll das Prinzip des Datenaustausches via DDE zwischen zwei Visual Basic-Anwendungen demonstriert werden. Während das erste Visual Basic-Programm, das die Rolle der Quellanwendung spielt, laufend "Meßwerte" mit Hilfe eines Zufallszahlengenerators produziert, stellt das zweite Visual Basic-Programm diese Werte, die per DDE-Link automatisch übertragen werden, dar.
Die Zielanwendung ist ein Visual Basic-Programm, das die von der Quellanwendung produzierten Daten darstellt. Es besteht aus einem Formular mit drei Bezeichnungsfeldern (das Gitternetz wird erst in der Erweiterung benötigt), in denen die Meßwerte dargestellt werden.
Wie funktioniert’s?
Bei der Quellanwendung handelt es sich um ein kleines Visual Basic-Programm, das aus einem Formular mit einer Schaltfläche, drei Bezeichnungsfeldern für die Darstellung der Meßwerte und einem Zeitgeber für die Steuerung des Zufallszahlengenerators besteht. Fürdie erfolgreiche DDE-Konversation müssen in der Quellanwendung lediglich zwei Einstellungen getroffen werden:
Bei den drei an der DDE-Konversation beteiligten Steuerelemente sind keine speziellen Einstellungen notwendig. Nach dem Anklicken der Start-Schaltfläche wird der Zufallszahlengenerator angestoßen, der laufend Meßwertreihen mit drei Meßwerten produziert. Diese drei Meßwerte werden von der Zielanwendung per DDE abgeholt. Dies geschieht entweder vollautomatisch oder auf Anfrage.
Auf Seiten der Zielanwendung kommt es lediglich darauf an, bei den drei Bezeichnungsfeldern einzustellen, wo sie sich die Daten abholen sollen. Dies geschieht im allgemeinen innerhalb der Form_Load-Prozedur:
lblTemperatur.LinkTopic = "Wetter|frmWetterTopic"
lblTemperatur.LinkItem = "lblTemperatur_Quelle"
lblTemperatur.LinkMode = 0
lblLuftfeuchtigkeit.LinkTopic = "Wetter|frmWetterTopic"
lblLuftfeuchtigkeit.LinkItem = "lblLuftfeuchtigkeit_Quelle"
lblLuftfeuchtigkeit.LinkMode = 0
lblOzonwert.LinkTopic = "Wetter|frmWetterTopic"
lblOzonwert.LinkItem = "lblOzonwert_Quelle"
lblOzonwert.LinkMode = 0
Durch Setzen der LinkMode-Eigenschaft auf 0 wird erreicht, daß die DDE-Konversation noch nicht beginnt. Dies wird erst beim Anklicken der Start-Schaltfläche durchgeführt:
lblTemperatur.LinkMode = 1
lblLuftfeuchtigkeit.LinkMode = 1
lblOzonwert.LinkMode = 1
Das Setzen der LinkMode-Eigenschaft auf 1 startet die DDE-Konversation und bewirkt, daß die aktuellen Werte aus der Quellanwendung automatisch in den an der DDE-Konversation beteiligten Steuerelementen der Zielanwendung dargestellt werden. Es ist weder ein Anfordern der Daten, noch eine explizite Zuweisung an die Caption-Eigenschaft erforderlich. Sobald in der Quellanwendung neue Daten anstehen, werden diese bei LinkMode=1 automatisch an das über die LinkItem-Eigenschaft festgelegte Steuerelement übertragen. Daher auch der Begriff "automatische Übertragung".
Übertragen der DDE-Daten nur auf Anfrage
Bislang kam dem Gitternetz auf der Zielanwendung noch keine Rolle zu. Es ist dazu da, die einzelnen Meßreihen, die von der Quellanwendung übertragen wurden, darzustellen. Doch wie soll das genau geschehen? Da die Daten automatisch ankommen und dabei kein Ereignis auslösen, wissen wir natürlich nicht, wann eine neue Meßreihe im Gitternetz ausgegeben werden soll. Zwar wäre es denkbar, über einen Zeitgeber regelmäßig den Zustand der drei Bezeichnungsfelder abzufragen, doch gibt es eine sehr viel elegantere Lösung. Anstelle des automatischen DDE-Betriebs verwenden wir den manuellen Modus (LinkMode=2 oder LinkMode=3). In diesem Modus werden die neuen Daten der Quellanwendung nicht automatisch an die Zielanwendung übertragen. Sie müssen vielmehr über eine LinkRequest-Methode gezielt angefordert werden. Allerdings wird bei DDE zwischen zwei manuellen Modi unterschieden:
Modus |
Bedeutung |
LinkMode=2 |
Manueller Modus. In diesem Modus muß die Zielanwendung auf Verdacht eine LinkRequest-Methode ausführen. |
LinkMode=3 |
Benachrichtigungsmodus. In diesem Modus wird in den Steuerelementen der Zielanwendung ein LinkNotify-Ereignis ausgelöst, wann immer sich die Daten in der Quellanwendung geändert haben. Anschließend müssen die aktuellen Daten über eine LinkRequest-Methode abgeholt werden. |
Tabelle: Die Bedeutung der beiden manuellen Übertragungsmodi bei der Zielanwendung
Damit ist die weitere Vorgehensweise auf Seiten der Zielanwendung klar (bei der Quellanwendung sind keine Änderungen erforderlich). Als erstes wird beim Anklicken der Start-Schaltfläche die LinkMode-Eigenschaft der drei Steuerelemente nicht auf 1, sondern auf 3 gesetzt:
lblTemperatur.LinkMode = 3
lblLuftfeuchtigkeit.LinkMode = 3
lblOzonwert.LinkMode = 3
Ändert sich ein Meßwert in der Quellanwendung, hat dies keine automatisch Aktualisierung bei der Zielanwendung zur Folge, es wird lediglich bei dem Steuerelement, dessen LinkItem-Eigenschaft den Namen des Steuerelements der Quellanwendung enthält, ein LinkNotify-Ereignis ausgelöst. Doch auch das alleine genügt noch nicht, denn die Daten treffen erst dann ein, wenn sie, in der Regel im Rahmen des LinkNotify-Ereignisses, über eine LinkRequest-Methode gezielt abgerufen werden:
Sub lblTemperatur_LinkNotify()
lblTemperatur.LinkRequest
grdMesswerte.Col = 1
grdMesswerte.Text = lblTemperatur.Caption
lblLuftfeuchtigkeit.LinkRequest
grdMesswerte.Col = 2
grdMesswerte.Text = lblLuftfeuchtigkeit.Caption
lblOzonwert.LinkRequest
grdMesswerte.Col = 3
grdMesswerte.Text = lblOzonwert.Caption
grdMesswerte.Col = 0
grdMesswerte.Text = grdMesswerte.Row
grdMesswerte.Row = grdMesswerte.Row + 1
If grdMesswerte.Row = 100 Then
grdMesswerte.Row = 1
cmdProtokoll.Value = True
End If
' Alle 14 Zeilen soll die Darstellung wieder oben beginnen
If grdMesswerte.Row Mod 14 = 13 Then
grdMesswerte.TopRow = grdMesswerte.Row
End If
End Sub
Zuerst wird der neue Meßwert über eine LinkRequest-Methode abgeholt, dann wird er in die entsprechende Spalte des Gitternetzes übertragen. Daß alle drei LinkRequest-Methoden in einer LinkNotify-Prozedur aufgerufen werden liegt daran, daß Visual Basic die LinkNotify-Prozeduren der übrigen beiden Steuerelemente offenbar nicht aufruft, wenn mehrere Änderungen gleichzeitig stattfinden. Damit die Ausgabe nicht ständig in einem nicht sichtbaren Bereich des Gitternetzes durchgeführt, wird die TopRow-Eigenschaft alle 13 Meßwerte auf den aktuellen Wert der Row-Eigenschaft gesetzt, so daß die aktuelle Reihe in der obersten sichtbaren Reihe des Gitternetzes dargestellt wird. Bei 100 Meßwerten bricht die Ausgabe in der Tabelle ab und kann durch Erneutes Anklicken der Start-Schaltfläche cmdProtokoll erneut gestartet werden:
Sub cmdProtokoll_Click()
Static Modus
If Modus = False Then
Modus = True
cmdProtokoll.Caption = "&Anhalten"
lblTemperatur.LinkMode = 1
lblLuftfeuchtigkeit.LinkMode = 1
lblOzonwert.LinkMode = 1
Else
Modus = False
cmdProtokoll.Caption = "&Protokoll"
lblTemperatur.LinkMode = 0
lblLuftfeuchtigkeit.LinkMode = 0
lblOzonwert.LinkMode = 0
End If
End Sub
Fehler bei DDE-Verbindungen
Eine DDE-Verbindung ist zwar relativ leicht zu implementieren, aber recht anfällig für Fehler. In diesem Fall bricht die DDE-Verbindung ab und muß vom Programm neu initiiert werden, was die Programmlogik nicht gerade erleichtert. Sobald Sie die Fehlermeldung "Kein fremdes Anwendungsprogramm hat auf die DDE-Initiative geantwortet erhalten", wurde die DDE-Anfrage der Zielanwendung nicht beantwortet. Dies kann daran liegen, daß die Quellanwendung nicht gestartet wurde, es kann aber auch daran liegen, daß die Werte der LinkTopic-Eigenschaft nicht übereinstimmen und Sie auf Seiten der Quellanwendung z.B. den falschen Applikationsnamen eingetragen haben oder die LinkTopic-Eigenschaft des Formulars in der Quellanwendung nicht entsprechend der Vorgabe in der Zielanwendung geändert haben (oder umgekehrt).
Hinweis
Zu den häufigsten Anfängerfehlern beim DDE-Zugriff gehört es, die LinkMode-Eigenschaft des an der DDE-Konversation beteiligten Zielformulars nicht auf 1 oder deren LinkTopic-Eigenschaft nicht den Formularnamen anzupassen.
Da DDE-Fehler durch Umstände verursacht werden können, auf die die Zielanwendung im allgemeinen keinen Einfluß hat (z.B. weil die Quellanwendung vom Benutzer versehentlich beendet wurde), sollten alle Prozeduren, in denen die LinkMode-Eigenschaft einen Wert ungleich Null erhält, und damit die DDE-Verbindung aktiviert wird, eine On Error Goto-Anweisung enthalten.
Das LinkError-Ereignis
Während einige DDE-Fehlersituationen, wie zum Beispiel eine nicht übereinstimmende LinkTopic-Eigenschaft einen Laufzeitfehler (in der Regel Nr. 282) erzeugen und damit über eine On Error Goto-Anweisung abgefangen werden können, gibt es eine Reihe von DDE-Fehlern, die in den "Tiefen von Windows" verursacht werden und damit keinen Laufzeitfehler versuchen. Tritt ein solcher Fehler auf, wird statt dessen ein LinkError-Ereignis ausgelöst. Über den Parameter LinkErr kann dieser Fehler abgefragt werden.
Fehler-nummer |
Beschreibung |
1 |
Die andere Anwendung hat Daten im falschen Format angefordert. |
2 |
Eine andere Anwendung hat Daten angefordert, ohne zuerst eine DDE-Kommunikation einzuleiten. |
3 |
Eine andere Anwendung hat versucht, eine DDE-Konversation durchzuführen, ohne zuerst eine DDE-Kommunikation einzuleiten. |
4 |
Ein andere Anwendung hat versucht, das Element für eine nicht existierende DDE-Kommunikation zu ändern. |
5 |
Eine andere Anwendung hat ein sogenanntes "Daten-Poking" versucht, ohne zuerst eine DDE-Kommunikation einzuleiten. |
6 |
Die andere Anwendung hat die Durchführung der DDE-Konversation versucht, nachdem in der Quellanwendung die Eigenschaft LinkMode auf 0 (Keine) gesetzt wurde. |
7 |
Zu viele DDE-Verbindungen. |
8 |
Eine Zeichenfolge war zu lang, um in einer DDE-Konversation übertragen zu werden; sie wurde abgeschnitten. |
9 |
Die Zielanwendung hat in einer DDE-Kommunikation ein ungültiges Element aus einem Steuerelementefeld angegeben. |
10 |
Eine andere Anwendung hat eine unerwartete DDE-Meldung gesandt. |
11 |
Ungenügender Speicherplatz für DDE. |
12 |
Die Quellanwendung hat in einer DDE-Kommunikation versucht, Ziel-Funktionen durchzuführen. |
Tabelle: Die wichtigsten DDE-Fehler und ihre LinkError-Fehlernummern
Starten der DDE-Quellanwendung
Möchte eine Zielanwendung von der Quellanwendung Daten anfordern und wurde die Quellanwendung noch nicht gestartet, ist entweder ein Laufzeitfehler die Folge oder es passiert gar nichts. Was liegt in diesem Fall näher, als die Quellanwendung einfach über eine Shell-Funktion zu starten? Nicht viel, nur daß vor geprüft werden sollte, ob die Quellanwendung nicht bereits gestartet wurde (und das Nicht Zustandekommen der DDE-Konversation in diesem Fall eine andere Ursache hatte). Dies kann auf zwei Weisen geschehen. Entweder prüft die Quellanwendung anhand der PrevInstance-Eigenschaft des App-Objekts selber, ob sie bereits gestartet wurde und entlädt sich selber, falls dies der Fall sein sollte:
Private Sub Form_Load ()
' Bin ich schon aktiv?
If App.PrevInstance = True then
' Ja, und Tschuess...
Unload Me
End If
End Sub
Ist der Titel einer Anwendung bekannt, kann über die FindWindow-API-Funktion festgestellt werden, ob die Anwendung aktiv ist. Der Titel einer Anwendung ist im allgemeinen in der Titelzeile des Hauptfensters enthalten (bei der Visual Basic-Entwicklungsumgebung muß zwischen dem Ausführen- und dem Design-Modus unterschieden werden, da diese Begriffe ebenfalls im Titel auftauchen).
Syntax
FindWindow ermittelt die Bezugsnummer eines Fensters einer aktiven Anwendung.
Declare Function FindWindow Lib "User" (ByVal lPClassName As Any, ByVal lpWindowName As Any) As Integer
Hinweis
Um festzustellen, ob eine Anwendung bereits läuft, können Sie PrevInstance-Eigenschaft des App-Objekts abfragen. Besitzt diese einen Wert, wurde das Programm bereits gestartet.
Die LinkExecute-Methode
Die LinkExecute-Methode bietet einen einfachen Mechanismus, über den zwei Anwendungen Kommandos austauschen können. Der Aufruf dieser Methode bewirkt, daß der Zielanwendung eine beliebige Zeichenkette zugesendet wird.
Syntax
LinkExecute Zeichenfolge
Da das Übertragen der über Zeichenfolge festgelegten Zeichenkette auf dem Formular der Zielanwendung ein LinkExecute-Ereignis zur Folge hat, muß das übertragene Kommando in dieser Ereignisprozedur ausgewertet werden.
Syntax
Private Sub Form_LinkExecute(Cmdstr As String, Cancel As Integer)
Bei cmdStr handelt es sich um die übertragene Zeichenkette. Durch Setzen von Cancel auf False, wird das Kommando akzeptiert, durch Setzen auf True (bzw. einen Wert ungleich Null) entsprechend zurückgewiesen (dies ist die Voreinstellung). In diesem Fall wird bei der Quellanwendung ein Laufzeitfehler ausgelöst.
Über die LinkExecute-Methode können einigen älteren Anwendungen, wie z.B. Access 2.0 zum Ausdrucken eines Reports, Kommandos geschickt werden. Für die gegenseitige Steuerung von Visual Basic-Anwendungen ist sie dagegen praktisch bedeutungslos, da es mit OLE-Automation eine sehr viel leistungsfähigere und vor allem flexiblere Alternative gibt.
DDE-Verbindungen zur Entwurfszeit einrichten
Bedingt durch den Umstand, daß eine DDE-Verknüpfung in die Zwischenablage kopiert und somit in ein anderes Programm eingefügt werden kann, kann eine DDE-Verbindung bereits zur Entwurfszeit eingerichtet werden. Visual Basic trägt die entsprechenden Werte für die Eigenschaften LinkTopic, LinkItem und LinkMode automatisch in die betroffenen Steuerelemente ein. Am Beispiel von Excel soll das Einrichten einer DDE-Verknüpfung zur Entwurfszeit demonstriert werden:
Schritt 1
Starten Sie Visual Basic und anschließend Excel.
Schritt 2
Tragen Sie in eine Zelle der aktiven Excel-Tabelle den Wert 1234 ein, betätigen Sie die
[Eingabe]-Taste (wichtig) und kopieren Sie die Zelle, z.B. über die Tastenkombination [Strg][C], in die Zwischenablage.Schritt 3
Ordnen Sie auf einem Formular ein Bezeichnungsfeld an, selektieren Sie das Bezeichnungsfeld und öffnen Sie das
Bearbeiten-Menü. Wählen Sie in dem Menü das Kommando Verknüpfen und einfügen. Der Wert der Excel-Zelle muß nun in dem Bezeichnungsfeld erscheinen. Außerdem wurden die Eigenschaften LinkItem, LinkMode und LinkTopic auf die entsprechenden Werte gesetzt.Welche Werte wurden für LinkItem, LinkMode und LinkTopic eingetragen? Die LinkItem-Eigenschaft des Bezeichnungsfeldes besitzt den Wert Z2S2. Dies ist der Name der Excel-Zelle, mit der eine DDE-Verknüpfung aufgebaut wurde. Die LinkTopic-Eigenschaft besitzt dagegen den Wert Excel|[Mappe1]Tabelle1 und entspricht damit dem bereits bekannten Schema
Anwendung | Thema
Während für Anwendung Excel eingesetzt wurde, steht [Mappe1]Tabelle1 für das Thema der DDE-Konversation. Diese Schreibweise müssen Sie auch dann verwenden, wenn Sie eine DDE-Konversation mit Excel während der Programmausführung aufbauen möchten.Auch der LinkMode-Eigenschaft wurde ein Wert verpaßt. Er beträgt 1, was bedeutet, daß eine automatische DDE-Verbindung aufgebaut wurde.
Schritt 4
Starten Sie das Visual Basic (ohne es zu speichern). Sobald Sie in der verknüpften Excel-Zelle eine Änderung durchführen (
[Eingabe]-Taste nicht vergessen), wird der neue Wert in dem Bezeichnungsfeld automatisch durchgeführt.Noch eindrucksvoller wirkt eine DDE-Verknüpfung mit Excel, die zur Entwurfszeit aufgebaut wird, wenn Sie anstelle eines simplen Zelleninhaltes ein ganzes Diagramm einfügen. Geben Sie dazu in eine Excel-Tabelle vier oder fünf Werte ein und machen Sie daraus ein Diagramm. Kopieren Sie das Diagramm über
[Strg][C] in die Zwischenablage. Ordnen Sie auf einem Formular nun ein Bildfeld an (ein Bezeichnungs- oder Textfeld kann natürlich kein Diagramm aufnehmen) und wählen Sie aus dem Bearbeiten-Menü erneut das Kommando Verknüpfen und Einfügen. Das Excel-Diagramm wird nun in dem Bildfeld dargestellt.Wie sieht es mit der automatischen Aktualisierung des Bildfeldes während der Programmausführung aus? Kein Problem, sobald Sie z.B. die 3D-Ansicht des Diagramms verändern, wird die neue Ansicht automatisch in dem Bildfeld berücksichtigt.
Hinweis
Soll ein Visual Basic-Steuerelement, mit dem eine DDE-Verknüpfung zu einer Anwendung, wie z.B. Excel besteht, nicht automatisch aktualisiert werden, muß die LinkMode-Eigenschaft den Wert 0 erhalten.
Auch der umgekehrte Weg, nämlich ein Visual Basic-Programm aus dem zur Entwurfszeit Daten in eine Excel-Tabelle kopiert werden, ist möglich. Ordnen Sie auf einem Formular ein Text- oder Bezeichnugnsfeld an und kopieren Sie es in die Zwischenablage. Wechseln Sie nun in die Excel-Tabelle und wählen Sie dort aus dem
Bearbeiten-Menü das Inhalte Einfügen-Kommando. In dem Dialogfeld sollte nun unter anderem der Eintrag Text angeboten werden. Wenn Sie diesen Eintrag selektieren, können Sie zwischen der Option "Einfügen und Verknüpfen" wählen (dies entspricht dem Kommando Verknüpfen und Einfügen aus Visual Basic bzw. Excel-Versionen vor Version 5.0). Der Inhalt des Text- bzw. Bezeichnungsfeldes wird nun in der aktuellen Zelle angezeigt. Ändern Sie diesen Inhalt auf dem Visual Basic-Formular, paßt sich die Excel-Zelle automatisch an. Im Bearbeitungsfeld von Excel ist für die Zelle die FormelProjekt1|Form1|Text1
zu sehen. Auf diese Art beschreibt Excel eine DDE-Verbindung. Der Ausdruck Projekt1|Form1 steht für Anwendung, der Ausdruck Text1 für das Thema der Konversation. Beide Ausdrücke ergeben, wissen Sie es bereits?, die Topic-Eigenschaft der DDE-Konversation.
Visual Basic-Programme "DDE fähig" machen
Übung
Die Fähigkeit, DDE-Verknüpfungen über die Zwischenablage einfügen zu können, muß in einem Visual Basic-Programm erst einmal implementiert werden. Es ist sehr lehrreich, sich diesen Mechanismus einmal etwas genauer anzuschauen, da Sie bei diesem Beispiel sehr viel über das prinzipielle Zusammenspiel eines Visual Basic-Programms mit anderen Anwendungen per DDE lernen. Als Anschauungsbeispiel soll unser Mini-Editor dienen, der im folgenden um ein Verknüpfen und Einfügen-Kommando erweitert werden soll. Auch das Kopieren-Kommando soll dahingehend erweitert werden, daß beim Kopieren eines Textes oder einer Grafik in die Zwischenablage ein DDE-Link mitkopiert wird, so daß andere Anwendungen, wie Word oder Excel, eine Live-Verbindung zu dem Editor herstellen können.
Prinzipiell wäre es kein Problem, anstelle eines Verknüpfen und Einfügen-Kommandos ein Inhalte einfügen-Kommando nachzubilden, doch ist der Aufwand, das Dialogfeld, in dem die in der Zwischenablage enthaltenen Objekte ausgewählt werden können, nachzubauen für dieses kleine Beispiel zu groß. Falls Sie dennoch Lust dazu verspüren, lassen Sie sich auf keinen Fall davon abhalten. Dazu ein kleiner Tip, wenn Sie das OLE-Steuerelement auf dem Formular anordnen, können Sie über InsertObjDlg- und PasteSpecialDlg-Methode des OLE-Steuerelements) das von allen Windows-Standardanwendungen verwendete Dialogfeld "Inhalte einfügen" aufrufen.
Im folgenden soll der Mini-Editor um ein Verknüpfen und Einfügen-Kommando erweitert werden. Da der Mini-Editor wirklich sehr einfach aufgebaut ist, können Sie wahlweise auf das Editor-Gerüst auf Kapitel 24 des Visual Basic 6.0-Kompendiums zurückgreifen oder im folgenden einen kleinen Editor noch einmal von Grund auf zusammenbauen.
Schritt 1
Erweitern des Menüs. Fügen Sie in das Bearbeiten-Menü ein Kommando mit dem Namen Verknüpfen und Einfügen ein.
Schritt 2
Selektives Aktivieren der einzelnen Menüeinträge. Natürlich soll das Einfügen-Kommando im Bearbeiten-Menü nur dann zur Auswahl stehen, wenn es etwas aus der Zwischenablage einzufügen gibt und dieses "etwas" in einem Format vorliegt, das vom aktiven Steuerelement angezeigt werden kann. Das gleiche gilt für die übrigen Kommandos. In die Ereignisprozedur mnuBearbeiten, die bei jedem Öffnen des Bearbeiten-Menüs aufgerufen wird, wird daher eine entsprechende Logik eingebaut:
Die Prozedur mnuBearbeiten_Click
Sub mnuBearbeiten_Click()
' Verknüfen-, Einfügen-, Ausschneiden- und Kopieren-Menü erst einmal deaktivieren
mnuVerknüpfen.Enabled = False
mnuEinfügen.Enabled = False
mnuAusschneiden.Enabled = False
mnuKopieren.Enabled = False
' Ist Text in der Zwischenablage enthalten
If Clipboard.GetFormat(vbCFText) = True And TypeOf Screen.ActiveControl Is TextBox Then
mnuEinfügen.Enabled = True
End If
' Enthält die Zwischenablage etwa Grafik?
If Clipboard.GetFormat(vbCFBitmap) = True Or Clipboard.GetFormat(vbCFMetafile) = True Then
' Ist das Bildfeld aktiv, sonst ergibt Einfügen keinen Sinn?
If TypeOf Screen.ActiveControl Is PictureBox Then
mnuEinfügen.Enabled = True
End If
End If
' Wurde Text im Textfeld selektiert?
If txtTextfeld.SelLength > 0 Then
mnuAusschneiden.Enabled = True
mnuKopieren.Enabled = True
End If
' Befindet sich ein DDE-Link in der Zwischenablage?
If Clipboard.GetFormat(vbCFLink) = True Then
If TypeOf Screen.ActiveControl Is PictureBox Then
If Clipboard.GetFormat(vbCFBitmap) Or _
Clipboard.GetFormat(vbCFMetafile) Then
mnuVerknüpfen.Enabled = True
End If
ElseIf TypeOf Screen.ActiveControl Is TextBox Then
If Clipboard.GetFormat(vbCFText) Then
mnuVerknüpfen.Enabled = True
End If
End If
End If
End Sub
Die Prozedur mnuBearbeiten_Click ist zwar relativ aufwendig, besteht zum Glück aber nur aus einer Aneianderreihung von Abfragen. Im Grunde soll nur dem Fall vorgebeugt werden, daß der Benutzer z.B. das
Einfügen-Kommando wählt, sich aber in der Zwischenablage nichts zum Einfügen befindet. Beachten Sie, daß man sich leider nicht mal eben alle Formate der Zwischenablage ausgeben lassen kann, sondern diese für jedes in Frage kommende Format über die GetFormat-Methode abfragen muß (Sie können sich allerdings mit geringem Aufwand ein kleines Klassenmodul definieren, daß z.B. die Verfügbarkeit aller in Frage kommenden Formate als True/False-Eigenschaften zur Verfügung stellt). Die AnweisungIf Clipboard.GetFormat(vbCFText) Then
fragt daher nur ab, ob sich in der Zwischenablage ein Textelement befindet. Die übrigen Formate Grafik und DDE müssen separat abgefragt werden, wobei bei der Grafik noch einmal zwischen den einzelnen Formaten (in der Regel nur Bitmap und Metafile) unterschieden werden muß. Das ist ein Grund, warum die Abfrage relativ aufgebläht zu sein scheint.
In Punkto DDE-Kommunikation passiert zu diesem Zeitpunkt noch nichts. Dem Benutzer soll über die angebotenen Menüs lediglich signalisiert werden, welche Inhalte in der Zwischenablage zur Verfügung stehen und welche nicht.
Schritt 3
Implementieren des
Verküpfen und Einfügen-Kommandos. Dieses Kommando wird nur angeboten, wenn sich in der Zwischenablage ein DDE-Link befindet. Doch wie muß man sich dieses DDE-Link vorstellen? Ganz einfach, es handelt sich um einen Textstring im allgemeinen FormatAnwendung|Thema!Element
wobei Anwendung für den Namen der Quellanwendung, Thema für den Dokumentnamen und Element für das betroffene Datenelement steht. Falls Sie einen Text aus Word in die Zwischenablage kopieren, finden Sie dort folgendes DDE-Link vor:
WinWord|Dokument1!DDE_LINK1
Die Aufgabe der Prozedur mnuVerknüpfen_Click besteht folglich darin, den Inhalt der Zwischenablage zu zerlegen und die Bestandteile den Anweisungen LinkTopic und LinkItem des Text- oder Bildfeldes zuzuweisen, mit dem die DDE-Verknüpfung aufgebaut werden soll. Das Ziel soll es bekanntlich sein, daß eine Änderung der Originaldaten, also in jener Anwendung, die den Text oder die Grafik in die Zwischenablage kopiert hat, sofort in dem Text- oder Bildfeld des Visual Basic-Programms angezeigt wird.
Die Prozedur mnuVerknüpfen
Sub mnuVerknüpfen_Click()
Dim ClipDDEInhalt As String, ItemPosition As Integer
Dim TopicText As String, ItemText As String
' Verknüpfungsinformation aus der Zwischenablage holen
ClipDDEInhalt = Clipboard.GetText(vbCFLink)
' Verknüpfungsinformation in Bestandteile zerlegen
ItemPosition = InStr(ClipDDEInhalt, "!")
TopicText = Left(ClipDDEInhalt, ItemPosition - 1)
ItemText = Mid(ClipDDEInhalt, ItemPosition + 1)
' DDE-Verbindung mit dem aktuellen Steuerelement herstellen
Screen.ActiveControl.LinkMode = NONE
Screen.ActiveControl.LinkTopic = TopicText
Screen.ActiveControl.LinkItem = ItemText
Screen.ActiveControl.LinkMode = AUTOMATIC
End Sub
Durch Setzen der Eigenschaft LinkMode auf 1 (Automatisch), wird die DDE-Verknüpfung sofort hergestellt.
Schritt 4
Hat es funktioniert? Probieren Sie das neue
Verknüpfen und Einfügen-Kommando doch gleich einmal aus. Starten Sie dazu Word (oder ein anderes DDE-fähiges Programm) und kopieren Sie etwas in die Zwischenablage. Starten Sie nun den erweiterten Mini-Editor und fügen Sie den Inhalt der Zwischenablage über das Verknüpfen und Einfügen-Kommando in das Textfeld ein. Jede Änderung im Word-Dokument sollte dank der bestehenden DDE-Verbindung sofort im Textfeld reflektiert werden.Hat es noch nicht funktioniert? Dann haben Sie wahrscheinlich die LinkMode-Eigenschaft des Formulars des Texteditors noch nicht auf den Wert 1 gesetzt. Außerdem sollten Sie in der Unload-Ereignisprozedur der guten Ordnung halber die DDE-Verknüpfung durch Setzen von LinkMode auf Null wieder beenden.
Schritt 5
Erweitern des
Kopieren-Kommandos. Damit auch der umgekehrte Weg funktioniert und der Mini-Editor ein DDE-Link, zusammen mit den Daten, in die Zwischenablage kopieren kann, muß die Ereignisprozedur mnuKopieren erweitert werden.Die Prozedur mnuKopieren_Click
Sub mnuKopieren_Click()
Dim AppName As String
' DDE-Verknüpfungsinformation zusammensetzen
AppName = App.EXEName & "|" & Me.LinkTopic
AppName = AppName & "!" & Screen.ActiveControl.Tag
' Und in die Zwischenablage kopieren
Clipboard.SetText AppName, vbCFLink
If TypeOf Screen.ActiveControl Is TextBox Then
Clipboard.SetText Screen.ActiveControl.Text, vbCFText
ElseIf TypeOf Screen.ActiveControl Is Picture Then
Clipboard.SetData Screen.ActiveControl.Picture
End If
mnuClipFormat.Caption = Chr(8)
End Sub
Auch hier kommt wieder das allgemeine Format eines DDE-Links zur Anwendung (erinnern Sie sich noch?). Es besteht aus dem Programmnamen (AppExename-Eigenschaft des App-Objekts), der LinkTopic-Eigenschaft des Formulasr und dem Namen des Steuerelements, mit dem die DDE-Verknüpfung aufgebaut werden soll. Daß man das aktive Steuerelements stets über die Eigenschaft ActiveControl des Screen-Objekts erhält, wissen Sie bereits. Doch wie kommen wir an dessen Namen heran? Ganz einfach, über die Name-Eigenschaft, die seit Visual Basic 4 auch während der Programmausführung abgefragt werden kann.
Die folgenden drei Anweisungen bauen die Link-Information zusammen und übertragen sie in die Zwischenablage:
AppName = App.EXEName & "|" & Me.LinkTopic
AppName = AppName & "!" & Screen.ActiveControl.Name
' Und in die Zwischenablage kopieren
Clipboard.SetText AppName, vbCFLink
Sobald sich die Link-Information in der Zwischenablage befindet, können Sie den ebenfalls in die Zwischenablage kopierten Text oder Grafik über das Inhalte einfügen-Kommandos eines Programms, wie Word oder Excel, als Verknüpfung einfügen.
DDE-Verbindungen mit Word
Eine DDE-Verbindung ist natürlich nicht nur auf Visual Basic-Anwendungen beschränkt. Im Gegenteil, am häufigsten dürfte es vorkommen, daß man per DDE einen Datenaustausch zwischen einem Visual Basic-Programm und Word herstellt. Auf diese Weise läßt sich zum Beispiel sehr einfach, innerhalb eines WordBasic-Makros ein Zugriff auf eine Datenbank durchführen, die von einem Visual Basic-Programm verwaltet wird.
Auf welche Weise eine DDE-Verbindung zur Entwurfszeit aufgebaut werden kann, wurde bereits in den letzten Absätzen beschrieben. Prinzipiell geht es immer darum, etwas aus einer DDE-fähigen Anwendung in die Zwischenablage zu kopieren und dieses "etwas" in der Entwurfszeit in ein Steuerelement, das über die Eigenschaften LinkItem, LinkTopic und LinkMode verfügen muß, einzufügen. Visual Basic sorgt dann selbständig dafür, daß die Link-Eigenschaften des Steuerelements die entsprechenden Werte erhalten.
Um eine DDE-Verbindung während der Programmausführung aufzubauen, müssen die Eigenschaften mit den gleichen Werten belegt werden. Es sei an dieser Stelle aber erwähnt, daß es spätestens mit Word 8.0 über Komponenten einen sehr viel leistungsfähigeren Mechanismus gibt.
WordBasic Befehl |
Syntax |
Bedeutung |
DDEInitiate |
Kanalnummer=DDEInitiate(Anwendung$, Objekt$) |
Öffnet eine DDE-Verbindung und gibt die Kanalnummer zurück. |
DDERequest$ |
Variable$=DDERequest$(Kanalnummer, Element$) |
Ruft ein Datenelement von dem DDE-Partner ab. |
DDEPoke |
DDEPoke Kanalnummer, Element$, Daten$ |
Sendet den Inhalt von Daten$ an den DDE-Partner Element$ |
DDEExecute |
DDEExecute Kanalnummer, Befehl$ |
Sendet das Kommando Befehl$ an den DDE-Partner |
DDETerminate |
DDETerminate Kanalnummer |
Beendet die DDE-Verbindung auf dem angegebenen Kanal |
DDETerminateAll |
DDETerminateAll |
Beendet alle DDE-Verbindungen |
Tabelle: Die WordBasic-Befehle für den Datenaustausch über DDE
Prinzipiell läuft die DDE-Kommunikation in einem WordBasic-Makro stets nach dem gleichen Schema ab. Als erstes holt man sich über DDEInitiate eine Kanalnummer, die für alle weiteren Zugriffe benötigt wird. Als Parameter werden bei DDEInitiate der Name der Anwendung (z.B. dem Formularnamen) und ein Thema (z.B. die LinkTopic-Eigenschaft des Formulars oder der Name einer Excel-Tabelle) übergeben. Anschließend werden mit DDERequest, DDEExecute und DDEPoke Daten und Anforderungen an die andere Applikation geschickt. Das zurückgesandte Objekt wird in der Regel über einen
Einfügen-Befehl in ein Textdokument eingefügt.Übung
In der folgenden Übung soll zwischen einem WordBasic-Makro und einem Visual Basic-Programm eine DDE-Verknüpfung aufgebaut werden. Das WordBasic-Makro nimmt einen Nachnamen entgegen und schickt diesen per DDE an das Visual Basic-Progamm. Dieses benutzt den Namen für eine Datenbankabfrage und gibt alle Adressen, in denen der Name enthalten ist, über ein Textfeld zurück.
Das WordBasic-Makro
A |
Sub MAIN |
B |
DDETerminateAll |
C |
Kanal = DDEInitiate("DDE02", "frmDDE02") |
D |
Suchname$ = InputBox$("Bitte Namen eingeben:", "Datenbankabfrage per DDE") |
E |
DDEExecute Kanal, Suchname$ |
F |
Ergebnis$ = DDERequest$(Kanal, "txtDatenbankabfrage") |
G |
Einfügen Ergebnis$ |
H |
DDETerminate Kanal |
I |
End Sub |
Die Erklärung für das WordMakro
Zeile |
Bedeutung |
A |
Hier beginnt das Makro. |
B |
Zunächst werden alle unter Umständen bestehenden DDE-Verbindungen beendet. |
C |
Mit dem Visual Basic-Programm DDE02 (Programmname) und dem Formular mit LinkTopic=frmDDE02 wird eine DDE-Verbindung aufgebaut. |
D |
Der Benutzer erhält die Gelegenheit, über ein Dialogfeld einen Suchnamen einzugeben. |
E |
Der Suchname wird an das Formular geschickt. Dort wird die Ereignisprozedur Form_LinkExecute aufgerufen. |
F |
Der Inhalt des Textfeldes txtDatenbankabfrage wird der Variablen Ergebnis$ zugewiesen. |
G |
Der Inhalt der Variablen Ergebnis$ wird in das Dokument eingefügt. |
H |
Die DDE-Verbindung wird beendet. |
I |
Hier endet das WordBasic-Makro. |
Die Umsetzung des WordBasic-Makros
Starten Sie Word und wählen Sie aus dem Extras-Menü das Kommando, geben Sie den Makronamen, z.B. DDETest, ein und klicken Sie auf die Schaltfläche Erstellen. Geben Sie nun die einzelnen Makrobefehle ein. Die Buchstaben werden nicht mit eingegeben, da diese, wie immer, nur der Erklärung des Programmlistings dienen und bei der Eingabe einen Fehler verursachen würden. Über die Makrosymbolleiste kann das Makro nun ausgeführt werden. Nach Eingabe eines Namens oder eines Buchstabens werden alle Adressen in das aktuelle Dokument übertragen, deren Nachname mit dem Suchbegriff übereinstimmt.
Das Visual Basic-Programm
Das Visual Basic-Programm besteht aus einem Formular mit einem Datensteuerelement und einem Textfeld. Während das Datensteuerelement den Datenbankzugriff abwickelt, ist das Textfeld für die Rückgabe der gefundenen Datensätze zuständig. Die gesamte Funktionalität des Visual Basic-Programms spielt sich innerhalb der LinkExecute-Prozedur ab.
Wichtig
Vergessen Sie nicht bei einem Formular, das auf DDE-Anfragen reagieren soll, bereits während der Entwurfszeit die LinkMode-Eigenschaft auf vbLinkAutomatic (1) zu setzen. Während der Programmausführung kann LinkMode bei einem Formular nicht gesetzt, sondern nur zurückgesetzt werden.
Die Prozedur Form_LinkExecute
Sub Form_LinkExecute(CmdStr As String, Cancel As Integer)
On Error GoTo Form_LinkExecute_Error
Dim Suchstring As String, Temp As String
Suchstring = CmdStr
' Wurde überhaupt etwas übergeben?
If Suchstring <> "" Then
Cancel = False
Else
' Nein, dann DDE-Anforderung zurückweisen
Cancel = True
End If
' Suchkriterium über SQL-Abfrage an Datensatzgruppe absetzen
Data1.RecordSource = "SELECT * FROM Adressen Where Nachname Like '" & Suchstring & Chr(39)
' Datensatzgruppe nach Abfrage neu aufbauen
Data1.Refresh
' Ist wenigsten ein Datensatz enthalten?
If Data1.Recordset.BOF = True Then
' Nein, dann Leerstring zuweisen
txtDatenbankabfrage.Text = ""
Else
' Ja, dann alle Datensätze durchgehen
Do While Not Data1.Recordset.EOF
' Vorname, Nachname, Straße und Wohnort zeilenweise in Textfeld übertragen
Temp = Temp & Data1.Recordset.Fields("Vorname") & Chr(9)
Temp = Temp & Data1.Recordset.Fields("Nachname") & Chr(9)
Temp = Temp & Data1.Recordset.Fields("Straße") & Chr(9)
Temp = Temp & Data1.Recordset.Fields("Wohnort") & Chr(13) & Chr(10)
Data1.Recordset.MoveNext
Loop
txtDatenbankabfrage.Text = Temp
End If
' Fertig, zurück zu Word
Exit Sub
Form_LinkExecute_Error:
MsgBox "Laufzeitfehler: " & Err.Number, vbExclamation, Err.Description
Stop
End Sub
Wie aus dem Listing schnell deutlich wird, enthält die Prozedur Link_Execute nichts "Word spezifisches". Sie wird vielmehr über die DDEExecute-Anweisung in dem WordBasic-Makro aufgerufen, die ihr gleichzeitig über den Parameter CmdStr mitteilt was zu tun ist. In diesem Fall enthält CmdStr aber kein Kommando, sondern lediglich den Suchbegriff, der in die SQL-Abfrage eingebaut wird. Beachten Sie, daß es keine direkte Möglichkeit gibt, einen Wert an das WordBasic-Makro zurückzugeben. Statt dessen werden die Datensätze als ein zusammenhängender Textstring in das Textfeld txtDatenbankabfrage übertragen, damit sich die DDERequest-Anweisung diesen dort abholen kann:
Ergebnis$ = DDERequest$(Kanal, "txtDatenbankabfrage")
Alternativ hätte man die Kommunikation auch über die DDEPoke-Anweisung abwickeln können. Zunächst sorgt die Anweisung
DDEPoke Kanal, "txtDatenbankabfrage", Suchname$
dafür, daß der Suchname in das Textfeld übertragen wird. Dies hat einen Aufruf der Change-Ereignisprozedur zur Folge, in der die Datenbankabfrage durchgeführt und das Ergebnis in dem Textfeld hinterlegt wird. Anschließend wird er von der DDERequest-Anweisung dort abgeholt. Hier gibt es allerdings ein Synchronisationsproblem zu lösen, da das WordBasic-Makro die Programmausführung fortsetzt, während das Visual Basic-Programm noch mit der Datenbankabfrage beschäftigt ist. Ohne Synchronisation kommt die DDERequest-Methode zu früh und findet im Textfeld noch den alten Inhalt vor.
Lesen einer Buchmarke von Visual Basic
Wie erhält man am schnellsten einen Textblock aus einem Word-Dokument? Zum Beispiel, in dem man diesen per DDE anfordert.
Beispiel
Das folgende Beispiel aktiviert Word und liest aus der Datei
Inhalt.doc den Wert der Textmarke "Testmarke" in ein Textfeld ein.Private Sub cmdTextholen_Click()
Dim RetVal As Long
RetVal = Shell("\Winword\WinWord \VBKURS\INHALTX.DOC", vbNormalFocus)
txtTextFeld.LinkMode = vbLinkNone
txtTextFeld.LinkTopic = "WinWord|C:\Vbkurs\Inhalt.doc"
txtTextFeld.LinkItem = "Testmarke"
txtTextFeld.LinkTimeout = 50
txtTextFeld.LinkMode = vbLinkManual
txtTextFeld.LinkRequest
End Sub
DDE-Verbindungen mit Excel
Dieses Thema sei nur der Vollständigkeit halber erwähnt, da es im allgemeinen vorteilhafter ist, auf Excel per OLE-Automation zuzugreifen (dies setzt Excel ab Version 5 voraus). Um zum Beispiel in einem Bezeichnungsfeld den Wert einer Excel-Zelle darstellen zu können, müssen dessen Link-Eigenschaften auf die entsprechende Werte gesetzt werden:
lblExcelWert.LinkTopic = "Excel|C:\Excel40\Test.xls"
lblExcelWert.LinkItem = "Z1S1"
lblExcelWert.LinkMode = 1
Diese drei Zuweisungen sorgen dafür, daß eine Änderung in der Zelle Z1S1 automatisch in dem Bezeichungsfeld reflektiert wird. Wird die DDE-Verbindung im manuellen Modus gestartet (was im allgemeinen sinnvoller ist), muß das Bezeichnungsfeld neue Werte über die LinkRequest-Methode anfordern.
Prüfen, ob eine DDE-Anwendung gestartet wird
Anders als beim Zugriff via OLE, sind Sie bei DDE selber dafür zuständig, Ihren DDE-Partner zu starten. Beim Zugriff auf eine Excel-Tabelle, muß also Excel zunächst über eine Shell-Funktion aufgerufen werden. Im allgemeinen geht man davon aus, daß der DDE-Partner bereits läuft und stellt sich durch Abfangen des Laufzeitfehlers auf den Fall ein, daß dem nicht so ist:
Sub DDE_Aufbauen()
On Error Goto DDE_Aufbauen_Error
' Anweisungen
Exit Sub
DDE_Aufbauen_Error:
If Err.Number = DDE_NO_APP Then
RetVal=Shell("Excel", vbMinimizedNoFocus)
Resume
End If
' Weitere Anweisungen
End Sub
DDE-Verbindungen mit Access
Auch mit Microsoft Access ist eine Verbindung per DDE möglich. So verfügt Access über eine Reihe von DDE-Kommandos, die über die LinkExecute-Methode z.B. dazu benutzt werden können, einen Report auszudrucken. Aber auch hier gilt, daß mit Access ab Version 7 OLE-Automation die bevorzugte Methode des Zugriffs sein dürfte.
Beispiel
Das folgende Beispiel bewegt Access per DDE dazu, einen bereits angefertigten Report zu drucken:
Sub cmdReportDrucken ()
txtDummy.LinkMode = 0
txtDummy.LinkTopic = "MSACCESS|SYSTEM"
txtDummy.LinkTimeOut = 1000
txtDummy.LinkMode = 2
txtDummy.LinkExecute "[OPENREPORT AkteX"]
txtDummy.LinkMode = 0
End Sub
In diesem Beispiel wird ein Textfeld dazu "zweckentfremdet" über LinkExecute ein DDE-Kommando an Access abzusetzen, daß dieses veranlaßt, den Report AkteX auszudrucken.
Programmgruppen einrichten per DDE
Es ist kein Geheimnis, daß der Windows-Programm-Manager aus Windows 3.1 (bzw. der Explorer bei Windows 95/98) per DDE erweitert werden kann. Wie sonst könnte es ein Setup-Programm fertig bringen, daß am Ende der Installation ohne Zutun des Benutzers Programmgruppen eingerichtet und in den Programmgruppen Symbole für die einzelnen Programmdateien angelegt werden? Mit Hilfe der DDE-Befehle des Programm-Managers lassen sich:
DDE-Kommando |
Parameter |
Bedeutung |
AddItem |
Kommandozeile, Titel, Symboldatei, SymbolIndex, Xpos, Ypos, Arbeitsverzeichnis, Tastenkombination, Ausführungsmodus |
Legt ein neues Element in der aktuellen Programmgruppe an. Bis auf die Kommandozeile sind alle Angaben optional. |
CreateGroup |
Gruppenname, Gruppenpfad |
Legt eine neue Programmgruppe an. |
DeleteGroup |
Gruppenname |
Entfernt eine Programmgruppe |
DeleteItem |
Elementname |
Entfernt ein Programmgruppenelement. |
ExitProgman |
SafeModus |
Beendet den Programm-Manager, wenn dieser von einem Programm aufgerufen wurde. Über SafeModus <> 0 wird festgelegt, daß die aktuellen Einstellungen gespeichert werden. |
Reload |
Gruppenname |
Entfernt eine Programmgruppe und lädt sie danach erneut. Dadurch werden Änderungen an der Programmgruppe angezeigt. Wird kein Gruppenname angegeben, werden alle Programmgruppen erneut geladen. |
ReplaceItem |
Elementname |
Entfernt ein Programmgruppenelement, speichert aber alle Einstellungen, so daß diese von dem nächsten Element übernommen werden. |
ShowGroup |
Gruppenname, Anzeigemodus |
Zeigt ein Gruppenfenster an. |
Tabelle: DDE-Kommandos für die Steuerung des Programm-Managers
Beispiel
Die Anwendung der DDE-Kommandos ist sehr geradlienig. Die folgenden Kommandos legen eine neue Programmgruppe mit dem Namen "Neue Gruppe" und dort ein Symbol für das Programm TestApp.Exe an:
[CreateGroup(Neue Gruppe)]
[ShowGroup(Neue Gruppe, 1)]
[AddItem(Testapp.exe, Test-Anwendung, ,1,32 ,32,C:\TESTAPP,0, 1)]"
Der Titel des Programmelements lautet "Test-Anwendung". Ein eigenes Programmsymbol besitzt es nur dann, wenn
Testapp.exe ein solches enthält. Ansonsten wird ein Standardsymol des Programm-Managers verwendet. Über den Parameter SymbolIndex kann ein Programmsymbol ausgewählt werden, wenn eine Exe-Datei mehrere Programmsymbole enthält. Die Koordinaten 32, 32 geben die Position des Elements in der Programmgruppe an. Bei C:\Testapp handelt es sich um das Arbeitsverzeichnis der Applikation. Schließlich gibt es noch die Parameter 0 (keine Tastenkombination) und 1 (starten als normales Fenster). Bliebe noch zu erwähnen, daß diese Kommandos über die LinkExecute-Methode eines Text- oder Bezeichnungsfeldes an den Programm-Manager geschickt werden.Hinweis
Da es nicht unbedingt gewährleistet ist, daß auf einem Windows-PC der Programm-Manager als Shell vereinbart wurde, sollten Sie vor der Ausführung von DDE-Kommandos durch Lesen des Eintrags "Shell=" in der Datei
System.ini feststellen, ob der Programm-Manager in Gestalt der Datei Progman.exe oder Explorer.exe (bei Windows 95/98) überhaupt zur Verfügung steht.Beispiel
Das folgende Beispiel überträgt die Namen aller Programmgruppen in ein Textfeld, wobei die einzelnen Gruppennamen automatisch durch die Zeichenfolge vbCr und vbLf voneinander getrennt werden:
txtGruppennamen.LinkTopic = "progman|progman"
txtGruppennamen.LinkItem = "Groups"
txtGruppennamen.LinkMode = 2
txtGruppennamen.LinkRequest
Wie bei jeder "normalen" DDE-Konversation müssen als erstes die Eigenschaften LinkTopic und LinkItem gesetzt werden. Die LinkTopic-Eigenschaft besitzt stets den Wert "progman|progman", die LinkItem-Eigenschaft wird nur für das Auflisten aller Gruppennamen benutzt, da die übrigen DDE-Kommandos über die LinkExecute-Methode an den Programm-Manager geschickt werden.
Wird bei der LinkItem-Eigenschaft anstelle von "Groups" der Name einer Gruppe angegeben, erhalten Sie Informationen über die Programmgruppe. Diese Informationen besitzen für eine Programmgruppe bzw. für ein Programmgruppenelement das folgende allgemeine Format:
"Gruppenname", Pfad der Gruppendatei, Anzeigemodus des Gruppenfensters, SymbolIndex
Die einzelnen Elemente werden durch Kommata getrennt. Dazu ein Beispiel für die Programmgruppe Microsoft Office aus Windows 95/98:
"Microsoft Office",C:\WIN95\STARTM~1\PROGRA~1\MICROS~1,9,1
Wie zu erkennen ist, werden für die langen Verzeichnisnamen die 8+3-Aliase verwendet. Bei einem Programmgruppenelement werden zusätzliche Informationen eingetragen:
"Titel", "Kommandozeile", Arbeitsverzeichnis, Ausführungspfad, Xpos, Ypos, Tastenkombination für Shortcut, Ausführungsmodus
Auch dazu ein Beispiel, diesmal für Word:
"Microsoft Word", "C:\WINWORD\WINWORD.EXE", C:\WINWORD, C:\WINWORD\WINWORD.EXE, 32, 32, 0, 0, 0
Beispiel
Das nächste Beispiel zeigt, wie sich gezielt die Programm-Manager-Informationen über eine Programmgruppe bzw. ein Programmgruppenelement abfragen lassen. Nach Anklicken der Schaltfläche Los geht’s werden alle Programmgruppennamen in einem Textfeld angezeigt. Durch Doppelklick auf einen der Namen werden die Informationen aller Elemente der Programmgruppe in dem Textfeld aufgelistet. Dabei gilt es aber ein kleines Programm zu lösen. Ein Textfeld ist nämlich kein Listenfeld, das Anklicken einer Zeile gibt noch lange nicht die Nummer der Zeile zurück. Oder anders herum, normalerweise gibt es keine einfache Möglichkeit, die Zeilennummer der Zeile zu bestimmen, in der sich die Textmarke momentan befindet. Es geht aber doch wenn Sie, wie es in Kapitel 15 des Visual Basic-Kompendiums gezeigt wurde, dem Textfeld über die SendMessage-API-Funktion eine entsprechende Nachricht zukommen lassen.
Der Allgemein-Teil
Option Explicit
Const WM_USER = 1024
Const EM_LINEFROMCHAR = WM_USER + 25
Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Long) As Long
Die Funktion GruppenNamenLesen
Function GruppenNameLesen(ZeilenNr As Integer) As String
Dim StartString As String
Dim StartPos As Integer, Länge As Integer, OldPos As Integer
Länge = Len(txtGruppennamen.Text)
Do
OldPos = StartPos
StartPos = InStr(StartPos + 1, txtGruppennamen.Text, Chr(10))
ZeilenNr = ZeilenNr - 1
Loop Until ZeilenNr = 0
GruppenNameLesen = Mid(txtGruppennamen.Text, OldPos + 1, StartPos - OldPos - 2)
End Function
Die Ereignisprozedur cmdGruppeAnlegen_Click()
Sub cmdGruppeAnlegen_Click()
Dim GruppenName As String, GruppenPfad As String
GruppenName = txtGruppenname.Text
If GruppenName = "" Then
txtGruppenname.SetFocus
Exit Sub
End If
GruppenPfad = "C:\"
txtGruppennamen.LinkExecute "[CreateGroup(" & GruppenName & Chr(44) & GruppenPfad & ")]"
End Sub
Die Ereignisprozedur cmdGruppeLöschen_Click()
Private Sub cmdGruppeLöschen_Click()
Dim Zeilennummer As Integer
Dim GruppenName As String
Zeilennummer = SendMessage(txtGruppennamen.hwnd, EM_LINEFROMCHAR, -1, 0&) + 1
GruppenName = GruppenNameLesen(Zeilennummer)
txtGruppennamen.LinkExecute "[DeleteGroup(" & GruppenName & ")]"
End Sub
Die Ereignisprozedur Sub cmdStart_Click()
Private Sub cmdStart_Click()
txtGruppennamen.LinkItem = "Groups"
txtGruppennamen.LinkRequest
End Sub
Die Ereignisprozedur Form_Load
Sub Form_Load()
txtGruppennamen.LinkTopic = "Progman|progman"
txtGruppennamen.LinkMode = 2
End Sub
Unter Windows ist ein Objekt "etwas", das in ein Dokument eingefügt werden kann, und dessen Inhalt sich aufgrund einer aktiven Verbindung zur Ursprungsapplikation automatisch aktualisieren kann. Bei dem "Etwas" kann es sich zum Beispiel um eine Excel-Tabelle, ein Word-Dokument oder einen Soundclip handeln. Um herauszubekommen, welche Objekte auf Ihrem System zur Verfügung stehen, gibt es eine einfache Übung. Starten Sie ein "Dokumentprogramm", wie zum Beispiel Word, Write oder Excel und wählen Sie aus dem Einfügen-Menü den Eintrag Kommando. Es erscheint ein Dialogfeld, das alle einfügbaren Objektypen enthält.
Das Formular als OLE-Container
Auch mit Visual Basic lassen sich Anwendungen erstellen, in denen Sie sowohl während der Entwurfs- als auch während der Laufzeit OLE-Objekte einfügen können. Da jedes Formular die Rolle eines OLE-Container spielt (ähnlich wie z.B. ein WordPad-Dokument), können Sie OLE-Objekte direkt auf einem Formular ablegen. Darüber hinaus können Sie OLE-Objekte, auch das ist eine Neuerung, die bereits mit Visual Basic 4 eingeführt wurde, in die Werkzeugsammlung aufnehmen. Ist in dem Dialogfeld, das nach Ausführung des Menükommandos
Projekt|Komponenten erscheint, die Option "Einfügbare Objekte" angekreuzt, werden neben den Zusatzsteuerelementen auch alle (registrierten) OLE-Objekte aufgeführt.Merksatz
Die Werkzeugsammlung läßt sich auf Wunsch auch um auf einem Formular einfügbare OLE-Objekte erweitern.
Einen praktischen Nutzen für ein direkt eingefügtes Objekt zu finden ist allerdings schwierig. So verfügt ein solches Objekt nur über einen minimalen Satz an Eigenschaften, Methoden und Ereignissen. Im allgemeinen wird man daher ein OLE-Objekt nicht direkt auf dem Formular, sondern über das OLE-Steuerelement einfügen. Doch Moment, ein Argument für das direkte Einfügen haben wir doch noch.
Möchten Sie ihre Bekannten (Chef, Freund, Freundin, Mutter, Schwiegermutter etc.) einmal beeindrucken in dem Sie ihnen vorführen, wie blitzschnell Sie mit Visual Basic programmieren können? Kein Problem, das "einfachste Malprogramm der Welt" kommt ohne jeden Programmbefehl aus. Nehmen Sie einfach ein leeres Formular, wählen Sie das Menülommando
Extras|Zusatzsteuerelemente und selektieren Sie im Dialogfeld das Objekt Paintbrush (die Option "Einfügbare Objekte" muß dazu aktiviert sein). Dadurch wird ein Paintbrush-Objekt direkt auf das Formular übertragen. Wenn Sie das Programm starten und das Objektfeld mit der Maus doppelt anklicken, wird Paint (unter Windows 95/98) gestartet und Sie können ein kleines Bild malen, wobei die Menüs von Paint automatisch im Menü des Formulars angezeigt werden (lediglich die Werkzeugleisten stehen nicht nur Verfügung). Nach dem Verlassen von Paint wird die Grafik in dem Objektfeld auf dem Formular angezeigt. Ist OLE nicht toll?OLE-Objekte über das OLE-Steuerelement einfügen
Auch wenn es seit Visual Basic 4 möglich ist, OLE-Objekte direkt auf einem Formular abzulegen, hat dieses Verfahren nur einen begrenzten praktischen Wert. Um das OLE-Objekt möglichst vielseitig einsetzen zu können, wird es nicht in das Formular, sondern in das OLE-Steuerelement eingefügt, welches einen komfortablen Rahmen für die Ansteuerung des Objekts zur Verfügung stellt.
Über das OLE-Steuerelement ist nicht nur das Einfügen, sondern auch die Verknüpfung eines OLE-Objekts möglich. In diesem Fall wird auf Wunsch auch eine automatisch Aktualisierung durchgeführt, wenn sich das Ursprungsobjekt ändert.
Welche Vorteile bringt das OLE-Steuerelement?
Natürlich ist der Umgang mit OLE-Objekten kein reiner Selbstzweck. Nur, weil Microsoft sagt OLE ist wichtig, muß man seine Programme nicht unbedingt mit OLE-Features ausstatten. Dies trifft insbesondere auf das Einfügen von Objekten zu. Visual Basic-Anwendungen, bei denen dieses Feature wirklich benötigt wird, sind heute noch relativ selten. Benötigt wird das Einfügen von Objekten immer dann, wenn man dem Benutzer eine dokumentzentrierte Oberfläche bieten möchte, die das Bearbeiten beliebiger Objekte gestattet. Stellen Sie sich das OLE-Steuerelement als ein Sichtfenster vor, in dem beliebige Objekte nicht nur erscheinen, sondern auch bearbeitet werden können. Visual Basic-Programme werden durch das OLE-Steuerelement nicht automatisch leistungsfähiger oder gar schneller. Die Möglichkeit, Objekte in einem Programm sichten und bearbeiten zu können, ist ein Feature, das in einigen Fällen echte Vorteile bringt und in Zukunft eine stetig zunehmende Bedeutung gewinnen wird. Die folgenden Anwendungsvorschläge sollen davon einen kleinen Vorgeschmack geben:
Das OLE-Steuerelement
Das OLE-Steuerelement ist dazu da, OLE-Objekte sowohl während der Entwurfs- als auch während der Ausführungszeit aufzunehmen. Eingefügte Objekte können bearbeitet werden, über OLE-Automation ist ferner ein Zugriff auf die Eigenschaften und Methoden des Objekts möglich. Auch wenn das OLE-Steuerelement über eine unter Umständen etwas verwirrende Vielzahl von Eigenschaften verfügt, ist es doch einfach zu programmieren. Wie bei allen Steuerelementen mit vielen Eigenschaften, sollten Sie sich zunächst auf die Kerneigenschaften beschränken und mir ihrer Hilfe das Steuerelement Schritt für Schritt besser kennenlernen. Zu den wohl wichtigsten Eigenschaften des OLE-Steuerelements gehört, daß es gebunden ist und daher direkt mit einem (OLE-) Feld einer Datenbank verbunden werden lassen. Sie können daher OLE-Objekte in einer Datenbank abspeichern und über das OLE-Steuerelement verwalten. Von der einfachen, und bereits kurz angesprochenen, Diaverwaltung für PowerPoint bis hin zu einem kompletten Dokumentverwaltungssystem lassen sich damit Anwendungen realisieren.
Wichtig
Beim OLE-Steuerelement handelt es sich um ein gebundenes Steuerelement, d.h. es die eingefügten Objekte können direkt in einer Datenbank abgelegt werden.
Das OLE-Prinzip
Bei OLE dreht sich alles um Objekte, die über einen Inhalt, Verben (mehr dazu gleich), Eigenschaften und Methoden, sowie eine Ursprungsapplikation verfügen. Letztere ist besonders wichtig, denn sie ist für das Bearbeiten des Objekts zuständig. Wenn Sie eine Excel-Tabelle in das OLE-Steuerelement einfügen, ist Excel, das auf dem PC installiert sein muß, die Ursprungsapplikation. Möchten Sie das Objekt bearbeiten, klicken Sie es doppelt an. Dies hat zur Folge, daß Excel gestartet wird. Das Besondere an OLE ist nun, daß Excel im allgemeinen nicht wie gewöhnlich als eigenständiges Programm gestartet wird, sondern im Kontext des Visual Basic-Formulrs, auf der das Objekt eingefügt wurde, erscheint. Sie sehen kein eigenes Excel-Fenster, die Menüs und Werkzeugleisten von Excel erscheinen vielmehr auf dem Formular. Diese Besonderheit, die manchmal auch als "Vorortaktivierung" oder "visual editing" bezeichnet wird, wird in den kommenden Jahren dafür sorgen, daß die Anwendung immer mehr in den Hintergrund tritt. Der Benutzer öffnet, wie heute schon bei Windows 95/98, auf den Desktop ein leeres Dokument und fügt nacheinander die benötigten Objekte ein. Da das Bearbeiten der Objekte vollständig im Rahmen des Dokuments stattfinden kann, wird ein separates Tabellenkalkulationsprogramm zwar noch benötigt (alleine aus lizenzrechtlichen Gründen), es tritt aber nicht mehr als eigenständige Anwendung in Erscheinung. In nicht allzu ferner Zukunft wird man nicht mehr eine Anwendung, wie Excel installieren müssen, dessen Grundfunktionalität wird in Form von OLE-Objekten in das Betriebssystem integriert sein. Statt dessen kauft man einzelne Objekte hinzu, um daß Betriebsystem um spezielle Fähigkeiten zu erweitern. Das Schöne daran ist, diese Objekte können in Visual Basic programmiert werden.
Hinweis
Damit ein Objekt eingefügt werden kann, muß es in der Registrierung registriert worden sein. Dies geschieht normalerweise automatisch bei der Installation der Ursprungsapplikation. Sollten die Registrierungsinformationen aus irgeneinem Grund nicht mehr vorliegen, lassen sich die entsprechenden Objekte nicht mehr einfügen. In diesem Fall hilft oft eine Neuinstallation der Ursprungsapplikation.
Kurzes OLE-Repitorium
Auch wenn OLE inzwischen ein fester Bestandteil fast aller Standard-Windows-Anwendungen ist, kann eine kurze Wiederholung zu diesem Thema nicht schaden. OLE kann man logischerweise nur dann programmieren, wenn man über die Anwendung Bescheid weiß. OLE-Unterstützung bedeutet konkret, daß eine Anwendung folgende Leistungsmerkmale bietet:
Alle diese Dinge können Sie z.B. mit dem Windows-Hilfsprogramm WordPad ausprobieren. Nach dem Start von WordPad können Sie über das
Objekt-Kommando im Einfügen-Menü beliebige Objekte (die allerdings zuvor registriert worden sein müssen) in das aktuelle Dokument einfügen. Das Verknüpfen (also der "linking"-Part des Object Linking and Embedding) steht über das Kommando Inhalte einfügen im Bearbeiten-Menü nur dann zur Verfügung, wenn zuvor ein Objekt in die Zwischenablage kopiert wurde.Um das in Visual Basic "nachprogrammieren" zu können, was bei den Standardanwendungen bereits fest eingebaut ist, wird das OLE-Steuerelement benötigt.
Die Eigenschaften des OLE-Steuerelements
Das OLE-Steuerelement verfügt über insgesamt 58 Eigenschaften, die Sie allerdings bei weitem nicht alle kennen müssen um mit diesem Steuerelement arbeiten zu können. Die Tabelle gibt eine Übersicht über die wichtigsten Eigenschaften.
Eigenschaft |
Bedeutung |
Action |
Steuert das OLE-Steuerelement während der Programmausführung, z.B. für das Einfügen eines Objekts oder die Anzeige eines Einfügen-Dialogfeldes. Diese Eigenschaft steht allerdings nur noch aus Kompatibilitätsgründen zu Visual Basic 3.0 zur Verfügung, denn ab Visual Basic 4 gibt es für jede der in Frage kommenden Einstellungen eine eigene Methode. |
AppIsRunning |
Gibt an, ob die Ursprungsanwendung des Objekts aktiv ist. Durch Setzen dieser Eigenschaft auf True, kann die Anwendung gestartet werden. |
AutoActivate |
Legt fest, auf welche Weise ein eingefügtes Objekt aktiviert werden kann (Standardeinstellung: 2 - Ursprungsapplikation wird durch Doppelklick aktiviert). |
AutoVerbMenu |
Ist dieser Wert True (Standardeinstellung), erscheint beim Anklicken des Objekts mit der rechten Maustaste ein Menü mit den zur Verfügung stehenden Verben. |
Class |
Ermittelt oder setzt den Klassennamen des eingefügten Objekts (manchmal auch als "programmatic id" bezeichnet). Für eine Excel-Tabelle lautet der Klassenname z.B. Excel.Sheet.5, für ein ClipArt-Bild MS_ClipArt_Gallery. |
DataField |
Legt den Namen eines Feldes in einer Tabelle fest, mit dem der Inhalt des OLE-Steuerelements verbunden ist. |
DataSource |
Legt den Namen eines Datensteuerelements fest, mit dem das OLE-Steuerelement verbunden wird. |
DisplayType |
Legt fest oder ermittelt, ob das Objekt in voller Größe (vbOLEDisplayContent, Standardeinstellung) oder als Symbol (vbOLEDisplayIcon) angezeigt wird. |
Format |
Setzt oder ermittelt das Datenformat, wenn Daten an die Ursprungsapplikation gesendet werden. |
HostName |
Setzt oder ermittelt den Namen der für die Host-Anwendung verwendet wird, die das Objekt enthält. |
lpOleObject |
Liefert die interne Adresse des eingefügten Objekts. Wird für den seltenen Fall benötigt, daß aus einem Visual Basic-Programm heraus eine OLE-API-Funktion aufgerufen werden soll. |
MiscFlags |
Erlaubt das Festlegen zweier nicht zusammenhängender Eigenschaften: 1-Objekt wird beim Laden im Speicher gehalten, 2-Vorortaktivierung ist nicht möglich. 3-Beide Einstellungen werden verwendet. |
Object |
Ermöglicht einen Zugriff über OLE-Automation auf die Eigenschaften und Methoden des eingefügten Objekts. |
ObjectAcceptFormats |
Gibt eine Liste von Formaten zurück, die durch das Objekt unterstützt werden. |
ObjectAcceptFormatsCount |
Gibt die Anzahl an Formaten zurück, die das Objekt unterstützt. |
ObjectGetFormats |
Gibt die Liste von Formaten zurück, die das Objekt zur Verfügung stellen kann. |
ObjectGetFormatsCount |
Gibt die Anzahl von Formaten zurück, die das Objekt zur Verfügung stellen kann. |
ObjectVerbFlags |
Legt den Zustand jedes einzelnen Verbs (z.B. abgeblendet oder mit Häckchen versehen) des Verbmenüs zurück. |
ObjectVerbs |
Gibt die Liste von Verben zurück, die das Objekt unterstützt (bei vielen Objekten sind es nur Bearbeiten und Öffnen). |
ObjectVerbsCount |
Gibt die Anzahl an Verben zurück, die das Objekt unterstützt. |
OLEDropAllowed |
Setzt oder ermittelt, ob in dem OLE-Steuerelement Objekte durch eine Ziehen- und Loslassen-Operation abgelegt werden können. |
OLEType |
Gibt ab, ob ein eingefügtes Objekt eingefügt (0-vbOLEEmbeded) oder verknüpft wurde (1-vbOLELinked). Ist kein Objekt enthalten, besitzt diese Eigenschaft den Wert 3 (vbOLENone). |
OLETypeAllowed |
Setzt oder ermittelt, welcher Typ des Einfügens möglich in dem OLE-Steuerelement möglich ist (0-vbOLELinked, 1-vbOLEEmbedded oder 2-vbOLEEither, dh. beides). |
PasteOK |
Gibt an, ob der Inhalt der Zwischenablage in das OLE-Steuerelement eingefügt werden kann. |
Picture |
Erlaubt während der Programmausführung einen Zugriff auf das in dem OLE-Steuerelement enthaltene Bild (Nur-Lese-Eigenschaft).Damit läßt sich zum Beispiel ein Excel-Diagramm sehr einfach in einer Bmp-Datei abspeichern, bei Excel-Tabellen werden aber nur die Inhalte der Tabellen angezeigt. |
SizeMode |
Legt fest oder ermittelt, auf welche Weise die Größe des Objekts an die Größe des OLE-Steuerelements angepaßt wird (1-vbOLESizeClip, Standardeinstellung, Objekt wird in seiner Normalgröße angezeigt, paßt es nicht mehr in das OLE-Steuerelement, wird es abgeschnitten). |
SourceDoc |
Ermittelt oder setzt den kompletten Pfadnamen eines verknüpften Objekts. |
SourceItem |
Ermittelt oder setzt die für eine Verknüpfung benötigte LinkItem-Eigenschaft (siehe DDE). |
UpdateOptions |
Ermittelt oder setzt auf welche Weise ein verknüpftes Objekt aktualisiert wird. Die Standardeinstellung ist automatische Aktualisierung (1-vbOLEAutomatic). |
Verb |
Legt ein von dem eingefügten Objekt unterstütztes Verb fest, das nach Ausführen der Action-Methode ausgeführt wird. Diese Eigenschaft steht aus Kompatibilitätsgründen zu Visual Basic 3.0 zur Verfügung. Ab Visual Basic 4 werden Verben entweder direkt über ihre Methode oder über die DoVerb-Methode ausgeführt. |
Tabelle: Wichtige Eigenschaften des OLE-Steuerelements
Die Rolle des Verbs
Verben
spielen im Zusammenhang mit eingefügten Objekten eine wichtige Rolle. Bei Verben handelt es sich um jene Kommandos, die im Kontextmenü des Objekts erscheinen, wenn Sie das Objekt (bei AutoVerbMenu=True) mit der rechten Maustaste anklicken. Jedes Objekt besitzt seinen eigenen Satz an Verben (in der Regel handelt es sich aber nur um die Kommandos Öffnen und Bearbeiten). Verben legen damit fest, welche Aktionen mit dem Objekt sowohl während der Entwurfs- als auch während der Ausführungszeit möglich sind.Die DoVerb-Methode
Um ein OLE-Objekt bearbeiten zu können, muß über die DoVerb-Methode das passende Verb ausgeführt werden.
Syntax
OLE-Steuerelement.DoVerb [(Verb)]
Über den (optionalen) Parameter Verb wird das auszuführende Verb festgelegt. Wird kein Verb angegeben, gelangt das Default-Verb (Index 0) zur Ausführung über das jedes OLE-Objekt verfügt. Anstelle des Verbnamens kann auch ein Index in dem Feld angegeben werden, das durch die ObjectVerbs-Eigenschaft repräsentiert wird.
Tip
Soll ein in das OLE-Steuerelement eingefügte Objekt mit dem Aktivieren einem Formular sichtbar werden, sollte das Formular_Activate-Ereignisprozedur und nicht Form_Load eine Anweisung, wie z.B.
oleTest.DoVerb vbOLEOpen
enthalten, da in diesem Fall das eingefügte Objekt (bzw. bei Angabe von vbOLEOpen der OLE-Server) bereits sichtbar ist, während das Formular noch geladen wird.
Die Standardverben, die (fast) jedes Objekt unterstützt, sind in der Tabelle aufgeführt.
Hinweis
Verwechseln Sie den Umstand, daß ein Objekt über Verben verfügt nicht mit dem Umstand, daß ein Objekt unter Umständen auch über OLE-Automation programmiert werden kann. Beides sind vollkommen verschiedene Dinge.
Konstante |
Wert |
Bedeutung |
vbOLEPrimary |
0 |
Dieses Verb steht für das Standardverb des Objekts, d.h. der Aufruf oleTest.DoVerb 0 führt stets das Standardverb aus. |
vbOLEShow |
-1 |
Bearbeiten. Unterstützt die Ursprungsapplikation des Objekts die Vorortaktivierung (was bei den meisten modernen Windows-Anwendungen der Fall ist), werden die Menüs in den Menüs der Container-Anwendung angezeigt. |
vbOLEOpen |
-2 |
Öffnen. Das Objekt wird in einem eigenen Fenster zum Bearbeiten geöffnet. |
vbOLEHide |
-3 |
Bei eingebetteten Objekten wird die Ursprungsapplikation nicht angezeigt. |
vbOLEUIActivate |
-4 |
Öffnet das Objekt und zeigt alle mit der Ursprungsapplikation zusammenhängenden Werkzeugleisten an, sofern die Ursprungsapplikation die Vorortaktivierung unterstützt. |
vbOLEInPlaceActivate |
-5 |
Indem das Objekt den Fokus erhält (oder mit der Maus einfach angeklickt wird), wird das Objekt, sofern es diese Möglichkeit unterstützt, zum Bearbeiten geöffnet. |
vbOLEDiscardUndoState |
-6 |
Nach dem Öffnen des Objekts zum Bearbeiten werden Änderungen für eine mögliche Undo-Funktion nicht gespeichert. |
Tabelle: Die Standardverben, die ein Objekt normalerweise unterstützt.
Aktivieren eines OLE-Objekts
Ein in ein OLE-Steuerelement eingefügtes Objekt kann auf verschiedene Weisen aktiviert werden. Zum Beispiel per Doppelklick immer dann, wenn es den Eingabefokus erhält. Wie ein OLE-Objekt aktiviert werden kann, wird durch die AutoActivate-Eigenschaft bestimmt.
Einstellung von AutoActivate |
Wert |
Bedeutung |
vbOLEActivateManual |
0 |
Das Objekt kann nur über die DoVerb-Methode oder die rechte Maustaste (sofern AutoVerbMenu=True) aktiviert werden. |
vbOLEActivateGetFocus |
1 |
Das Objekt wird aktiviert, wenn es den Fokus erhält, sofern die Ursprungsapplikation diese Form der Aktivierung unterstützt. |
vbOLEActivateDoubleclick |
2 |
Das Objekt wird per Doppelklick oder durch Betätigen der [Eingabe]-Taste, wenn das OLE-Steuerelement den Fokus besitzt, aktiviert. In diesem Fall tritt kein DblClick-Ereignis auf. Dies ist die Standardeinstellung. |
vbOLEActivateAuto |
3 |
Es wird die über die Ursprungsapplikation passende Aktivierungsmethode (Aktivierung bei Fokuserhalt oder Doppelklick) verwendet. |
Tabelle: Die in Frage kommenden Einstellungen für die AutoActivate-Eigenschaft
Die Methoden des OLE-Steuerelements
Durch seine Methoden wird das OLE-Steuerelement "lebendig". Alle jene Dinge, wie z.B. das Einfügen eines Objekts oder das Einrichten einer Verknüpfung, lassen sich über die dafür zuständige Methode während der Programmausführung durchführen.
Methode |
Bedeutung |
CreateEmbed |
Erzeugt ein eingefügtes ("eingebettetes") Objekt. Der Objekttyp wird beim Aufruf der Methode übergeben. Die Eigenschaft OleTypeAllowed muß die Werte 1 oder 2 besitzen. Da sich die Daten des OLE-Objekts beim Einfügen innerhalb der Container-Anwendung befinden, wird beim Abspeichern des OLE-Objekts das gesamte Objekt gespeichert. |
CreateLink |
Stellt mit einem OLE-Objekt, das sich innerhalb einer Datei befindet, eine Verknüpfung her. Der Name dieser Datei wird beim Aufruf übergeben. Die OleTypeAllowed-Eigenschaft muß den Wert 0 oder 2 besitzen. Beim Abspeichern der Container-Anwendung oder des OLE-Objekts wird lediglich die Verknüpfungsinformation gespeichert. |
Copy |
Kopiert das eingefügte oder verknüpfte OLE-Objekt in die Zwischenablage. Dies schließt auch alle Verknüpfungsinformationen ein. |
Paste |
Fügt ein OLE-Objekt aus der Zwischenablage in das OLE-Steuerelement ein. Mit dem OLE-Objekt kann nur dann gearbeitet werden, wenn die PasteOK-Eigenschaft den Wert True besitzt, das heißt, wenn die Zwischenablage ein gültiges OLE-Objekt enthält. |
Update |
Bewirkt, daß die aktuellen Daten aus der Applikation verwendet werden, um das OLE-Objekt zu aktualisieren. |
DoVerb |
Öffnet ein OLE-Objekt um es bearbeiten zu können. Die DoVerb-Methode ersetzt die Verb-Eigenschaft, die festlegt, was nach dem Setzen von Action auf den Wert 7 passieren soll. |
Close |
Schließt ein eingefügtes OLE-Objekt und beendet die Verbindung mit seiner Applikation. Auf ein verknüpftes Objekt hat diese Aktion dagegen keinen Einfluß. |
Delete |
Löscht das OLE-Objekt im OLE-Steuerelement und gibt den von ihm belegten Speicher wieder frei. |
SaveToFile |
Speichert das OLE-Objekt in einer Datei ab, deren Dateinummer beim Aufruf übergeben wird. Die Dateinummer wird, wie bei gewöhnlichen Dateioperationen, durch die Open-Anweisung (im Binary-Modus) geliefert. |
ReadFromFile |
Lädt ein OLE-Objekt aus einer Datei , deren Namen auf die gleiche Weise bestimmt wird, wie bei der SaveToFile-Methode. |
InsertObjDlg |
Öffnet das Standarddialogfeld zum Einfügen eines OLE-Objekts. Über die OleTypeAllowed-Eigenschaft wird festgelegt, welche Art der Verknüpfung erlaubt ist. |
PasteSpecialDlg |
Öffnet das Standarddialogfeld zum Einfügen eines OLE-Objekts aus der Zwischenablage. Über die OleTypeAllowed-Eigenschaft wird festgelegt, welche Art der Verknüpfung erlaubt ist. Besitzt die Zwischenablage ein ungültiges Format, erscheint eine entsprechende Fehlermeldung. |
FetchVerbs |
Aktualisiert die Liste von Verben, die durch das OLE-Objekt unterstützt werden. Diese Aktion wird beim Öffnen eines Menüs (AutoVerbMenu=True) durch Anklicken des Objekts mit der rechten Maustaste automatisch ausgeführt. |
SaveToOle1File |
Speichert ein OLE-Objekt im (ur-) alten OLE1-Format ab. |
Tabelle: Die Methoden des OLE-Steuerelements
Die Ereignisse des OLE-Steuerelements
Anders als man es zunächst vermuten würde, verfügt das OLE-Steuerelement mit dem Updated- und dem ObjektMove-Ereignis nur über zwei zusätzliche Ereignisse. Das Updated-Ereignis wird immer dann ausgelöst, wenn sich die Daten des OLE-Objekts geändert haben. Es wird um Beispiel benutzt um zu entscheiden, ob ein OLE-Objekt abgespeichert werden muß.
Syntax
OLESteuerelement_Updated (Code As Integer)
Der Prozedurparameter Code liefert zusätzliche Informationen über den Grund der Änderung:
0 |
Die Daten des Objekts haben sich geändert (vbOLEChanged) |
1 |
Die Daten des Objekts wurden durch die Applikation, durch die das Objekt erstellt wurde, abgespeichert (vbOLESaved). |
2 |
Die Datei, die die verknüpften Daten enthält, wurde durch die Applikation, von der das Objekt erstellt wurde, geschlossen (vbOLEClosed). |
3 |
Die Datei, die die verknüpften Daten enthält, wurde durch die Applikation, von der das Objekt erstellt wurde, umbenannt (vbOLERenamed). |
Das ObjectMove-Ereignis wird ausgelöst, sobald sich die Größe eines Objekts im OLE-Steuerelement ändert, oder dieses verschoben wird. Auf diese Weise erhält das OLE-Steuerelement Gelegenheit, sich über die SizeMode-Eigenschaft an die neue Größe anzupassen.
Syntax
Sub Objekt_ObjectMove(Left As Single, Top As Single, Width As Single, Height As Single)
Anders als beim Resize-Ereignis erfahren Sie hier die neue Größe und Position des OLE-Steuerelements (einschließlich) Umrandung. Da intern eine Umrechnung von Pixel in Twips stattfindet, müssen die Angaben nicht exakt mit der tatsächlichen Größe in Twips übereinstimmen.
Das OLE-Steuerelement in der Praxis
Anwendungen für das OLE-Steuerelement gibt es viele. Wann immer, Sie auf einem Formular ein Objekt einer anderen Applikation zur Bearbeitung anbieten möchten, wird das OLE-Steuerelement benötigt. Die folgenden Übungen sind in erster Linie dazu da, das OLE-Steuerelement und seine wichtigten Eigenschaften kennenzulernen. Das OLE-Steuerelement stellt über seine Eigenschaften und Methoden nur das zur Verfügung, was jede Windows-Anwendung über zwei Standarddialogfelder zu bieten hat:
Beachten Sie, daß die Auswahl eines OLE-Objektes wahlweise über zwei Standarddialogfelder, die von Windows bereitgestellt werden, im Zusammenspiel mit dem OLE-Steuerelement durchgeführt wird, oder vollkommen programmgesteuert durch den Aufruf der Methoden CreateEmbed, CreateLink und Paste geschehen kann.
Das Einfügen eines Objekts
Dies ist die leichteste Übung. Als erstes muß das OLE-Steuerelement (es heißt innerhalb dieser Übung stets oleTest) natürlich wissen, welche Art von Objekt eingefügt werden soll. Diese Information wird ihm über den Klassennamen mitgeteilt, der als Parameter der CreateEmbed-Methode übergeben wird:
oleTest.CreateEmbed "", "ExcelWorksheet"
Wenn das Objekt nicht bereits in einer Datei vorliegen sollte, muß für den Dateinamen ein Leerstring übergeben werden. Orientieren Sie sich bei der Schreibweise des Klassennamens an jenen Namen, die die Class-Eigenschaft im Eigenschaftsfenster des OLE-Steuerelements auflistet.
Das Festlegen des Klassennamens kann natürlich auch mit der Unterstützung des dafür zuständigen Standarddialogfeldes geschehen:
oleTest.InsertObjDlg
Diesmal muß der Klassenname vom Benutzer ausgewählt werden. Es ist eine gute Programmierpraxis, über die OLEType-Eigenschaft zu prüfen, ob auch tatsächlich ein Objekt geladen wurde. Sollte der Benutzer das Dialogfeld zum Beispiel über die
[Esc]-Taste abbrechen, wäre beim Aktivieren des OLE-Objekts ein Laufzeitfehler die Folge:oleTest.InsertObjDlg
If oleTest.OLEType = vbOLENone Then
MsgBox "Es wurde kein Objekt ausgewählt!", vbExclamation, "Hinweis"
Exit Sub
End If
Damit das Beispiel funktionieren kann, muß ein eventuell bereits geladenes Objekt zuvor über die Delete-Methode gelöscht werden. Beachten Sie, daß wenn der Benutzer das OLE-Objekt über das Standarddialogfeld auswählt, Visual Basic bereits automatisch den Klassennamen verwendet, so daß ein Aufruf der CreateEmbed-Methode nicht notwendig ist.
Aktivieren des OLE-Objekts
Um mit dem OLE-Objekt arbeiten zu können, muß es aktiviert werden. Dies geschieht entweder durch Anklicken mit der Maus (d.h. sobald das OLE-Steuerelement den Fokus erhält) oder über die DoVerb-Methode, welche die Nummer oder den Namen des ausführenden Verbs erhalten muß:
oleTest.DoVerb 0
Dieser Aufruf aktiviert das Standardverb, bei dem es sich in den allermeisten Fällen um das Bearbeiten-Verb handelt.
Bearbeiten des OLE-Objektes
Da ein Formular automatisch die sog. Vorortaktivierung unterstützt, können Objekte innerhalb des Formulars überarbeitet werden. Verfügt das Formular über ein Menü, werden die Menüs der Ursprungsapplikation automatisch in den Menüs des Formulars dargestellt, wenn die NegotiateMenus-Eigenschaft des Formular den Wert True besitzt.
Merksatz
Damit die Menüs der Ursprungsapplikation in der Menüleiste des Formulars angezeigt werden können, muß das Formular über mindestens einen Menüeintrag (dieser kann auch unsichtbar sein) verfügen.
Auch welche Weise sich die Menüs der Ursprungsapplikation mit den Menüs dem Formular kombinieren, wird über die Eigenschaft NegotiatePosition festgelegt, die im Menüentwurfsfenster eingestellt werden muß. Zur Auswahl stehen die Einstellungen None (Standardeinstellung), Left, Middle und Right.
Leider sind nicht alle OLE-Server gleich, so daß der Umgang der Unterstützung varrieren kann. Dies wird vor allem daran deutlich, ob Werkzeugleisten angezeigt werden. Dies ist z.B. bei Word der Fall, nicht aber bei Paint oder Excel.
Schließen des OLE-Objekts
Normalerweise wird ein OLE-Objekt deaktiviert, wenn das OLE-Steuerelement den Eingabefokus verliert. Über die Close-Methode kann dies auch programmgesteuert geschehen:
oleTest.Close
Objekt aus einer Datei einfügen
Dieser Vorgang unterscheidet sich vom Einfügen eines neuen Objekts lediglich dadurch, daß zusätzlich zum Klassennamen beim Aufruf der CreateEmbed-Methode auch ein Dateiname angegeben wird:
KlassenName = "ExcelWorksheet"
DateiName = "C:\Excel\First.xls"
oleTest.CreateEmbed DateiName, KlassenName
Speichern und Laden von OLE-Objekten
Alle Änderungen, die der Benutzer an einem eingefügten OLE-Objekt durchführt, sind verloren, sobald die Visual Basic-Anwendung beendet wird. Um den Objektzustand zu erhalten, muß das OLE-Objekt vor dem Verlassen der Anwendung gespeichert werden. Dafür bietet das OLE-Steuerelement die SaveToFile-Methode, der lediglich die Dateinummer einer über die Open-Anweisung geöffneten (Binär-) Datei übergeben werden muß:
Sub mSpeichern_Click()
On Error GoTo mSpeichernError
Dim Dateinummer As Integer
If oleTest.OLEType = vbOLENone Then
MsgBox "Kein Objekt selektiert!", vbExclamation, "Wichtiger Hinweis"
Exit Sub
End If
Dateinummer = FreeFile
Open "OLETEST.OLE" For Binary As Dateinummer
oleTest.SaveToFile DateiNummer
Close Dateinummer
Exit Sub
mSpeichernError:
MsgBox Err.Description & "(" & Err.Number & ")" , vbExclamation, "Fehler beim Speichern"
Resume Next
End Sub
Beim Abspeichern kommt es lediglich darauf an, die Dateinummer einer im Binary-Modus geöffneten Datei zuzuweisen. Anschließend kann das aktuelle Objekt über die Anweisung
oleTest.SaveToFile DateiNummer
in der Datei gespeichert, wobei der Dateiname keine Rolle spielt (die Erweiterung
.OLE wurde rein willkürlich gewählt).Ähnlich verhält es sich beim Laden eines OLE-Objekts:
Open "OLETEST.OLE" For Binary As Dateinummer
oleTest.ReadFromFile DateiNummer
Close Dateinummer
Üblicherweise wird das Laden eines OLE-Objekts bereits in Form_Load durchgeführt, damit das OLE-Steuerelement von Anfang an mit dem aktuellen Objekt arbeitet. Beachten Sie aber, daß dadurch die Ladezeit des Programms ungünstig beeinflußt wird.
Abfangen von Laufzeitfehlern
Es ist absolut notwendig, beim Arbeiten mit dem OLE-Steuerelement Laufzeitfehler abzufangen. Wie ein Blick in die von Visual Basic unter dem Stichwort "auffangbare Fehler" (engl. "trappable errors") offenbar, gibt es eine Reihe von Fehlercodes für das Arbeiten mit dem OLE-Steuerelement. Gerade am Anfang lernen Sie durch die Fehlermeldungen eine Menge über das OLE-Prinzip.
Hinweis
Beim Umgang mit OLE-Objekten ist es üblich, Laufzeitfehler nicht über eine On Error Goto-Anweisung, sondern direkt durch Abfragen der Number-Eigenschaft des Err-Objekts abzufragen. Die wohl häufigste Fehlerursache ist ein nicht gestarteter OLE-Server:
Set Application = GetObject(, AppName & ".Application")
If Err.Number = 429 Then
Err.Clear
Set Application = CreateObject(AppName & ".Application")
If Err.Number = 429 Then
OLEAppStart = False
Exit Sub
End If
End If
In dieser Sequenz wird eine Objektvariable initialisiert und anschließend geprüft, ob der OLE-Server gestartet wurde. Sollte dies nicht der Fall sein (die Fehlernummer 429 bezieht sich allgemein auf einen OLE-Automatisierungsfehler), wird über die CreateObject-Funktion ein zweiter Versuch gestartet. Schlägt auch dieser fehl, wird die Prozedur mit einem Fehlercode verlassen. Eine Fehlerroutine wird in diesem Fall nicht benötigt.
Objekt aus der Zwischenablage einfügen
Wie Sie bereits wissen, kann das einzufügende Objekt auch aus der Zwischenablage stammen. Das Einfügen eines Objekts aus der Zwischenablage wird über die Paste-Methode realisiert:
If oleTest.PasteOK = True Then
oleTest.Paste
End If
Um einen Laufzeitfehler zu vermeiden, sollte durch Abfragen der PasteOK-Eigenschaft sichergestellt werden, daß die Zwischenablage ein gültiges OLE-Objekt enthält. Den Klassennamen des eingefügten Objekts können Sie anschließend über die Class-Eigenschaft abfragen.
Objekt aus der Zwischenablage verknüpfen
Dieses Verfahren entspricht dem Einfügen eines Objekts aus der Zwischenablage, nur daß hier durch Setzen der Eigenschaft OLETypeAllowed auf 0 das gleichzeitige Einfügen verhindert wird:
If oleTest.PasteOK = True Then
oleTest.TypeAllowed = vbOLELinked
oleTest.Paste
End If
Voraussetzung ist natürlich, daß die Zwischenablage ein Objekt mit Verknüpfungsinformationen enthält. Dieser Fall läßt sich innerhalb des Programms allerdings nicht prüfen, denn die Abfrage der PasteOK-Eigenschaft prüft nur, ob sich generell ein OLE-Objekt in der Zwischenablage befindet.
Objekt aus einer Datei verknüpfen
Im letzten Beispiel stammte das zu verknüpfende Objekt aus der Zwischenablage. Sehr viel häufiger dürfte es vorkommen, daß sich das Objekt in einer Datei befindet. In diesem Fall muß der Dateiname beim Aufruf der CreateLink-Methode angegeben werden:
Dim Dateiname As String, Klassenname As String
KlassenName = "ExcelWorksheet"
Dateiname = "C:\Excel\First.xls"
oleTest.CreateLink Dateiname, Klassenname
Wie beim reinen Einfügen muß auch beim Verknüpfen über die CreateLink-Methode ein Klassenname übergeben werden. Dabei gelten die gleichen Regeln wie beim Einfügen.
Auch für das Einfügen einer Verknüpfung aus der Zwischenablage gibt es ein Standarddialogfeld. Es trägt den Titel Inhalte einfügen und wird durch Aufruf der PasteSpecialDlg-Methode aktiviert:
In diesem Dialogfeld können Sie einstellen, ob das in der Zwischenablage befindliche Objekt als Objekt (engl. "embedding") oder als Verknüpfung (engl. "linking") eingefügt werden soll. Nachdem die Verknüpfung eingefügt wurde, wird bei einer Änderung im Original diese auch in dem OLE-Steuerelement durchgeführt (Sie müssen das Formular allerdings aktivieren und einen kurzen Augenblick warten). Soll das Objekt lediglich als Symbol dargestellt werden, muß das entsprechende Kontrollkästchen aktiviert werden. Befindet sich das zu verknüpfende Objekt in einer Datei, muß deren Dateiname entweder vom Benutzer aus dem Dialogfeld ausgewählt oder innerhalb des Programms über die SourceDoc-Eigenschaft festgelegt werden.
Festlegen eines Teilbereichs
Dieser Schritt ist vollkommen optional. Soll nämlich die Verknüpfung nur mit einem Teil des Objekts durchgeführt werden, muß dieser Teilbereich über die SourceItem-Eigenschaft (das erinnert natürlich an DDE) spezifiziert werden:
oleTest.SourceItem = "Z1S1:Z3:S4"
Der Wert, welcher der SourceItem-Eigenschaft zugewiesen wird, richtet sich natürlich nach dem Objektyp und muß vom jeweiligen OLE-Server verstanden werden können. Im obigen Beispiel wird ein Bereich aus einer Excel-Tabelle ausgewählt (von der ersten Zelle in der ersten Zeile bis zur vierten Zelle in der dritten Spalte). Beachten Sie, daß bei Verwendung der SourceItem-Eigenschaft die OLETypeAllowed-Eigenschaft entweder den Wert 0 (Verknüpfung) oder den Wert 2 (Beides) besitzen muß. Beachten Sie ferner, daß Visual Basic automatisch den Wert der SourceItem-Eigenschaft an die SourceDoc-Eigenschaft hängt.
Ziehen und Ablegen mit dem OLE-Steuerelement
Über die OLEDropAllowed-Eigenschaft des OLE-Steuerelements steht OLE-Drag&Drop zur Verfügung. Während der Entwurfszeit können Sie unabhängig vom Wert dieser Eigenschaft eine Datei, wie z.B. eine Excel-Tabelle, in das OLE-Steuerelement ziehen. Während der Programmausführung muß die OLEDropAllowed-Eigenschaft den Wert True besitzen, damit das OLE-Steuerelement zum "drop target" wird. Über die OLETypeAllowed-Eigenschaft läßt sich einstellen, welche Art der Verknüpfung (Linked, Embedded oder Either) erfolgen soll.