Autor: Peter Haserodt --- Aus Excel VBA - Gruppe:
TutorialsZugriff auf andere Anwendungen (1) - Grundlagen und Irrtümer
Autor: Peter Haserodt - Erstellt: -- - Letzte Revision: --Gruppenthema: 2 Folgen 1 2 Sie sind in Folge:1
Zugriff auf andere (Office-) Anwendungen am Beispiel von Word
Über nichts wird mehr Unsinn publiziert, als über dieses Thema.
Als erstes mal weg mit zwei Irrtümern:
Irrtum 1:
Um auf Word zugreifen zu können, muss ich unter Extras Verweise einen Verweis auf die Word Objektbibliothek setzen (Microsoft Word x.0 Object Library, wobei x für die Versionsnummer steht, z.b. 10 bei WordXP ).
Dies ist schlichtweg falsch, wie wir sehen werden.
Dass man dies trotzdem oft macht, hat seine durchaus vernünftigen Gründe, die wir später näher beleuchten.
Irrtum 2:
Ich muss eine Objektvariable in der Art setzen wie:
Dim oWord as Word.Application
Dies ist ein Irrtum und meines Erachtens sogar Unsinn
Eine solche Deklaration führt in der Regel oft zu Problemen bei nur geringfügigen Versionsänderungen bei der Word Anwendung.
Zwar kann man dies in der Testphase tun, um die Intellisense zur Verfügung zu haben und später dann dies ändern aber auch dies ist nicht empfehlenswert, allein schon wegen der Vergesslichkeit.
Ich will hier nicht über Dinge wie early binding und late binding mich auslassen, es sei nur soviel gesagt, dass diese Variante zu early binding gehört, während bei den Zugriffen unbedingt late binding benutzt werden soll, wie wir es auch tun werden. (Im Netzt gibt es genügend Informationen zu diesen beiden Begriffen)
Aber treten wir zuerst für Irrtum 1den Beweis an.
Nehmen Sie sich eine neue Arbeitsmappe und dann ein allgemeines Modul und fügen Sie den nachfolgenden Code ein.
' **************************************************************
' Modul: mdlWord Typ = Allgemeines Modul
' **************************************************************
Option Explicit
Dim oWord_App As Object, oDoc As Object, bWordVorhanden As Boolean
Private Function Word_Connect() As Boolean
Word_Connect = True
On Error GoTo OpenError
Set oWord_App = GetObject(Class:="Word.Application") ' Gucken ob Word offen ist
bWordVorhanden = True
On Error GoTo 0 ' In Zukunft wieder in den Debugger laufen
' Hier bei Bedarf prüfen ob Word sichtbar ist
Exit Function
OpenError: ' Word war nicht offen, also dann bitte öffnen
On Error GoTo CreateError
Set oWord_App = CreateObject(Class:="Word.Application")
oWord_App.Visible = True ' Dies gegebenenfalls rausnehmen wenn man unsichtbar arbeiten will
bWordVorhanden = False
Resume Next
Exit Function
CreateError:
'Word ist nicht vorhanden
MsgBox "Kein Word vorhanden"
Word_Connect = False
End Function
Private Sub Word_Disconnect()
'gegebenenfalls die Objektvariablen wieder freigeben
'Wir wollen ja keinen Verweis auf Word zurücklassen
On Error Resume Next
Set oDoc = Nothing
Set oWord_App = Nothing
End Sub
Public Sub TestOhneVerweis()
If Not Word_Connect Then Exit Sub 'Raus wenns brennt
On Error GoTo Fehler
With oWord_App
.Documents.Add
.Selection.Text = "He, dies funzt ja wirklich" & vbCrLf & vbCrLf & _
"Jo is denn scho Weihnachten"
End With
Aufraeumen:
'' #########################################
'' Optionale Möglichkeit Word zu beenden, wenn wir es gestartet haben
''Hier muss man aber aufpassen, dass man vorher in Word aufgeräumt hat
'' Also Dokumente geschlossen etc...
' If Not bWordVorhanden Then oWord_App.Quit
''############################################
Word_Disconnect ' Nicht vergessen ;-) !!!!!!!!!!!!!!!!!!!!!!!!!
Exit Sub
Fehler:
MsgBox Err.Description
Resume Aufraeumen
End Sub
Starten Sie nun die Sub TestOhneVerweis
Wenn alles gut geht (und natürlich Word auf ihrem Rechner vorhanden ist), sollten Sie den Erfolg sehen.
Obwohl wir nix in Extras Verweise gemacht haben, haben wir auf Word zugegriffen.
Quod erat demonstrandum
Die Deklarationen im Kopfteil des Modules und die Function Word_Connect sowie die Sub Word_Disconnect,
werde ich in den weiteren Beispielen als gegeben vorraussetzen.
Die Kopfdeklarationen, die Function Word_Connect und die Sub Word_Disconnect
Mit Dim oWord_App as Object im Kopfteil stellen wir Modulweit eine Objektvariable zur Verfügung, dito oDoc (welches wir im Moment nicht benötigen).
Wie wir die benennen bleibt uns überlassen aber man sollte schon sprechende Namen vergeben.
bWordVorhanden ist eine bool'sche Variable, die wir benutzen, um Information über den Ursprungszustand (war Word schon offen oder haben wir es geöffnet) zur Verfügung zu haben.
Function Word_Connect
Diese ist das Herzstück.
In ihr setzen wir unsere Objektvariable oWord_App auf die Anwendung (Application) Word an.
Tatsächlich ist dieser Vorgang denkbar einfach.
Mit GetObject versuchen wir auf ein eventuell geöffnetes Word zuzugreifen.
Ist Word nicht offen, prodzuziert dieser Code einen Fehler. Diesen Fehler fangen wir vorher ab mit dem On Error.
Laufen wir also in den Fehler, dann wird zu OpenError gesprungen und hier versuchen wir nun eine Wordinstanz zu öffnen. (CreateObject).
Gelingt auch dies nicht, wird eine Fehlermeldung ausgegeben.
Haben wir eine Verbindung bekommen, dann setzen wir die Function auf True ansonsten auf False, um beim Aufruf dieser Function zu wissen ob es geklappt hat.
Ist alles in Ordnung haben wir nun unsere Objektvariable als Verbindung zu Word, besser als Verweis auf eine Instanz von Word und zwar das Application Objekt von Word und können nun damit arbeiten.
(Ich werde darauf noch näher in Schritt 2 dieses Tutorials eingehen)
Function Word_Disconnect
Diese ist genauso wichtig.
Ich habe eine Instanz von Word an meine Objektvariable oWord_App "gebunden".
Diese Verbindung muss ich wieder lösen.
Wenn ich also abgearbeitet habe, "entsette" ich meine Objektvariable.
Dies ganze in ein On Error Resume Next gepackt aus Faulheit (anstatt zu prüfen ob überhaupt was gesetzt wurde) und überhaupt und ...
Die Sub TestOhneVerweis
Als erstes setzen wir die Verbindung und verlassen bei Nichterfolg sofort die Prozedur.
Nun kommen einfach ein paar Word Befehle, nämlich ein Dokument zu öffnen und was reinzuschreiben.
Das ganze natürlich immer in Verbindung mit unseren Objektvariablen oWord_App.
Danach räumen wir noch auf.
Eigentlich ganz simple oder?
Der Nachteil des fehlenden Verweises auf die Objektbibliothek und wie ich damit umgehen kann.
Wie eingangs beschrieben, kann es durchaus sinnvoll sein (oder ist es auch meistens), unter Extras Verweise einen Verweis auf die Ojektbibliothek von Word zu setzen.
Aber wir wollen dies noch
nicht tun, sondern uns den Hintergrund dazu betrachten:
Bei unserem Beispiel wird ein Text geschrieben und er ist danach markiert. Gerne möchte ich aber den Cursor am Ende des Textes haben.
Ändern Sie in der Testsub den Teil von With ... End With wie folgt ab:
With oWord_App
.Documents.Add
.Selection.Text = "He, dies funzt ja wirklich" & vbCrLf & vbCrLf & _
"Jo is denn scho Weihnachten"
.Selection.Collapse Direction:=wdCollapseEnd
End With
Der hinzugefügte Befehl mit wdCollapseEnd sollte dies erreichen.
Wenn Sie die Sub nun starten werden Sie einen Fehler erhalten, dass die Variable wdCollapseEnd nicht deklariert ist. ( Wichtig natürlich oben Option Explicit)
Durch den fehlenden Verweis ist die Wordkonstante wdCollapseEnd natürlich unbekannt.
Aber wir können dies erstmal anders lösen:
Wenn ich im Objektkatalog von Word nachschaue, kann ich herausfinden, dass diese Konstante den Wert 0 hat.
Ich ändere meinen Code also dahingehend:
.Selection.Collapse Direction:=0
Und schon funktioniert es.
Und nun mit Verweis
Wir ändern den Code wieder in:
.Selection.Collapse Direction:=wdCollapseEnd
und gehen nun auf das Menü Extras - Verweise und suchen uns dort
Microsoft Word X.0 Object Library
und setzen dort einen Haken und dann OK.
Schon haben wir keine Probleme mehr mit der Konstanten!
Verweis oder kein Verweis, dass ist hier die Frage
Bevor ich darauf eingehe: Dies hat nichts damit zu tun, wie wir unsere Objektvariable setzen und wie wir auf die Anwendung zugreifen. Auch hat dies nichts mit den Methoden der Anwendung zu tun!
Der Vorteil des Verweises ist natürlich die Möglichkeit, auf die Konstanten der anderen Anwendung zugreifen zu können. Wenn zum Beispiel MS einfällt, den Wert für wdCollapseEnd in einer anderen Version auf 100 zu setzen, brauche ich mir keinen Kopf darüber zu machen.
Ein Nachteil kann sein, dass wenn der Anwender kein Word hat, das ganze hustet.
Ein weiterer Nachteil sind Probleme mit der Abwärtskompatibilität. Aber hier sollte man sowieso immer auf der niedrigsten Version entwickeln.
Ich persönlich habe noch keinerlei Nachteile des Verweises entdecken können.
(Da ich grundsätzlich bei Verweisen auf Officebibliotheken mit der niedrigst anzunehmenden Version arbeite
Tatsächlich kann es aber Probleme geben, wenn Mappen von höheren Versionen wieder auf niedrigere Versionen zurückimportiert werden)
Will ich abwärtskompatibel arbeiten, sollte ich auf den Verweis verzichten.
Vielen Dank an Thomas Ramel, der auf diesen fehlenden Hinweis aufmerksam gemacht hat! )
Wenn einer die Anwendung auf die ich einen Verweis setze nicht hat, dann ist es halt Pech (und in der Regel ist das Programm dann auch nicht für denjenigen geeignet). Wenn ich aber in diesem Fall auf eine andere Anwendung ausweichen will, muss ich mir da was anderes überlegen.
(Ich habe einige VB Programme draußen mit Verweisen z.B. auf die Excel Bibliothek und von E97 bis E2003 sind bis Dato noch keine Probleme aufgetaucht)
(Wobei ich hier darauf achte, mit der niedrigst anzunehmenden Version beim Kunden zu arbeiten)
Hinweis für VB'ler:
Gerade in VB setzt man gerne diese Verweise.
Worauf man dann aber unbedingt aufpassen muss, ist die Objektbibliothek nicht mit auszuliefern !!!
(z.B. beim Weitergabe Assistenten abhaken)
Ein Fehler, der mir früher auch öfters unterlaufen ist.
Ende des ersten Teils
Wenn es ihnen gefallen- und vor allem geholfen hat, dann kann ich Sie sicherlich dann wieder beim nächsten Schritt begrüßen.
Zu Schritt 2 >>
Weitere Artikel der Gruppe: Tutorials Aus Excel VBA
Nach oben