Autor: Peter Haserodt  --- Aus Excel VBA - Gruppe: Tutorials

Zugriff auf andere Anwendungen (2) - Excel und Word im Zusammenspiel

Autor: Peter Haserodt - Erstellt: --      - Letzte Revision: --Gruppenthema: 2 Folgen 1 2 Sie sind in Folge:2
Ein Ausflug in das Verständis
(Schritt 1 dieses Tutorials wird vorrausgesetzt)

Wenn ich in Excel im Direktfenster
?Workbooks.Count

schreibe und auslöse, ist es für mich selbstverständlich, dass ich hier ein Resultat bekomme, nämlich die Anzahl der geöffneten Arbeitsmappen von Excel.
Tatsächlich ist dies aber nur bedingt richtig.
Ich bekomme nur alle geöffneten Mappen der Excel Instanz ausgegeben, in welcher ich diesen Code geschrieben habe - respektive des eigenen Applicationobjektes.
(Man kann dies sehr leicht nachvollziehen, indem man Excel ein weiteres mal öffnet und dort das gleiche durchführt, am besten dort noch ein paar Mappen hinzufügt, um es deutlicher zu sehen)

Ich beziehe mich bei solchen Codes automatisch (per Default) auf die Application, in welcher ich den Code schreibe.
Eigentlich hieße es: Application.Workbooks.Count aber ich kann das Application weglassen, da es der Default ist.

Wenn Sie nun in der einen Excelinstanz ein Workbook mit dem Namen test.xls haben, können Sie dort z.B. im Direktfenster ?Workbooks("test.xls").sheets.count schreiben und bekommen ein Ergebnis.

Schreiben Sie dies in der anderen Excelinstanz, erhalten Sie eine Fehlermeldung. (Ausser Sie haben dort auch eine Mappe mit diesem Namen)

Die Ursache dafür ist leicht erklärt: Die Mappe ist "Mitglied" oder besser Kind der Application und ich kann primär nur aus der Application auf diese zugreifen.

Beide Instanzen stellen mir Workbooks.Count zur Verfügung (mit möglicherweise unterschiedlichen Ergebnissen), da dies mir vom Excel.Application Objekt zur Verfügung gestellt wird, aber nur in einer Instanz kann ich auf die dort geöffnete Arbeitsmappe zugreifen.

Schließen Sie nun die zweite Excelinstanz, wir brauchen diese nicht mehr.

Bevor wir aber weitergehen, noch ein kleiner Test:
Nehmen Sie sich ein allgemeines Modul und fügen Sie folgenden Code ein:
Option Explicit
Dim oExcel As Application
 
Sub test()
 Set oExcel = Application
 MsgBox oExcel.Workbooks.Count
 Set oExcel = Nothing
End Sub
Wir haben eine Variable auf unser Applicaton Objekt angesetzt. Dadurch dass wir diese als Application dimensioniert haben, erhalten wir sogar die Intellisense. Ändern Sie dies in:
Dim oExcel As Object
so funktioniert das ganze immer noch, nur die Intellisense nicht.
Aber beides mal haben wir eine Objekt Variable, die wir mit Set auf das Application Object gesetzt haben und zwar hier wieder per Default auf das aktuelle Excel.Application Objekt.

Zwei verschiedene Anwendungen:

Langsam tasten wir uns heran:

Bitte beachten Sie, dass wir im Folgenden immer zwischen der VBA Umgebung von Excel und der VBA Umgebung von Word hin-und her wechseln.
Schauen Sie also immer, wo Sie gerade sind!


Öffnen Sie nun Word mit einem leeren Dokument und erzeugen Sie in der VBA Umgebung von Word in einem allgemeinen Modul folgenden Code:
Option Explicit
 
Sub TestSchreiben()
 Selection.TypeText "Hallo"
End Sub
Sie sehen, dass Wort Hallo wird in das aktive Dokument geschrieben.

Wir wechseln nun nach Excel und machen dasselbe dort.
Hier produziert der Code einen Fehler.

Dies ist leicht zu erklären, Excel kennt den Befehl Selection.TypeText nicht.
(Wollte ich zum Beispiel die Aktive Zelle mit dem Wort Hallo füllen, muss ich bekannterweise schreiben:
ActiveCell.value = "Hallo" )

Jede Anwendung hat ihre eigenen Methoden und Eigenschaften!

Wenn ich Word steuern will, muss ich die mir von Word zur Verfügung gestellten Methoden, Eigenschaften (und gegebenenfalls auch Ereignisse) , nutzen.
(Dies gilt für Aktionen, die ich in Word durchführe - was ich damit meine, werden wir noch sehen)

 Peter Haserodt
  • Formelhilfe
  • Makroentwicklung
  • VBA-Programmierung
  • + + + + + + + + +
Excel und Word im Zusammenspiel:

Öffenen Sie nun die Mappe mit dem Modul mdlWord aus Schritt 1 (oder erzeugen eine neue Mappe und fügen das Modul ein).
Im Folgenden wird immer auf das aktive Tabellenblatt von Excel zugegriffen, bzw. dort etwas hineingeschrieben.


Schreiben Sie in das Tabellenblatt in die Zellen B2 bis B5 ein paar Zahlen.
Fügen Sie dann folgende Prozedur in das Modul ein:

 
Public Sub SummeInsDoc()
 If Not Word_Connect Then Exit Sub
 On Error GoTo Fehler
 With oWord_App
  .Documents.Add
  .Selection.Text = "Meine Excelsumme ist: " & _
  WorksheetFunction.Sum(Range("B2:B5"))
  Range("D2").Value = .Selection.Text
 End With
 Aufraeumen:
 Word_Disconnect
 Exit Sub
 Fehler:
 MsgBox Err.Description
 Resume Aufraeumen
End Sub

Dieses Beispiel sollte die ganze Macht des Zusammenspiels zeigen.

Schauen wir uns die Zeilen:
.Selection.Text = "Meine Excelsumme ist: " & _
WorksheetFunction.Sum(Range("B2:B5"))
Range("D2").Value = .Selection.Text
genauer an (der Rest ist aus Schritt 1 bekannt).
Selection.Text ist eine Methode von Word, welche die aktuelle Selektion der Anwendung überschreibt oder eine Eigenschaft, die mir den Text der aktuellen Selektion zurückgibt.
(Also Anwendung -> Aktives Document -> aktive Selektion)
WorksheetFunction.Sum ist eine bekannte Methode von Excel.

Da wir uns aber in Excel befinden, muss ich es definitiv sagen, wenn ich in Word etwas tun will.
Dafür haben wir unsere Objektvariable oWord_App. Durch das hinzufügen eines Documents setze ich dies gleichzeitig als aktives Dokument der Word.Application, die ich anspreche und die aktive Selection ist die des aktiven Dokumentes.
(Natürlich kann ich auch auf andere Dokument zugreifen, welche öffnen etc... aber dies ist dann wieder nur Technik)

Durch die Anwendung des With ... End With Konstruktes spare ich mir, jedes mal vor die Wordaktionen das oWordApp zu schreiben aber es ist wichtig zu verstehen, dass natürlich genau darauf zugegriffen wird.

Der erste Teil der Zeile ist also klar, ich schreibe etwas in das aktive Dokument - aber was?
Zum ermitteln des Was benutzen wir diesmal eine Excelmethode.
Hier haben wir nichts davor geschrieben (wobei natürlich auch Application.WorksheetFunction ... )
Wir befinden uns in Excel und Excel stellt uns seine Methoden sofort zur Verfügung.

Die nächste Zeile ist dann leicht erklärt:
Diesmal schreiben wir in Excel und das mit einer Excel-Eigenen Methode, nämlich in eine Zelle etwas zu schreiben. Aber was wir schreiben, holen wir uns aus Word!

Zwischenstop und Aufgabe:

Bevor Sie nun zur Lösung weiter nach unten scrollen, möchte ich ihnen die Möglichkeit geben, dies selbst zu entwickeln.
Aufgabe ist es, Excel nun aus Word heraus zu steuern.

Im Einzelnen:
Aus Word heraus soll Excel geöffnet werden, wenn nicht vorhanden, ansonsten auf ein vorhandenes Excel zugegriffen werden.
Dann soll eine leere Arbeitsmappe erzeugt werden.
In das 1. Tabellenblatt dieser Mappe sollen in die Zellen B2 bis B5 Zahlen geschrieben werden.
Danach soll die Summe in B6 stehen, entweder schon ausgerechnet, wer es besonders machen will als Summenfunktion.
Dies sähe dann als Beispiel so aus:
Tabelle1
 ABC
1   
2 100 
3 500 
4 200 
5 10 
6 810 
7   
Formeln der Tabelle
B6 : =SUMME(B2:B5)
 
Weiterhin soll dann die in Zelle B6 ermittelte Summe in das aktive Dokument von Word geschrieben werden. Ich denke, mit dem bisher erlernten, kann man die Aufgabe lösen.
Hinweis:
Sie benötigen keinen Verweis auf Excel in ihrer Wordumgebung, um dies zu lösen.

Viel Spass!
Im übernächsten Rahmen sehen Sie dann meinen Vorschlagscode für Word.

Alles schon fertig?
Na super.
Dann folgt nun mein Vorschlagscode:



' **************************************************************
'  Modul:  mdlExcel  Typ = Allgemeines Modul
' **************************************************************

Option Explicit
Dim oExcel_App As Object, bExcelVorhanden As Boolean
 
Private Function Excel_Connect() As Boolean
 Excel_Connect = True
 On Error GoTo OpenError
 Set oExcel_App = GetObject(Class:="Excel.Application") ' Gucken ob Excel offen ist
 bExcelVorhanden = True
 On Error GoTo 0 ' In Zukunft wieder in den Debugger laufen
 ' Hier bei Bedarf prüfen ob Excel sichtbar ist
 Exit Function
 OpenError:      ' Excel war nicht offen, also dann bitte öffnen
 On Error GoTo CreateError
 Set oExcel_App = CreateObject(Class:="Excel.Application")
 oExcel_App.Visible = True ' Dies gegebenenfalls rausnehmen wenn man unsichtbar arbeiten will
 bExcelVorhanden = False
 Resume Next
 Exit Function
 CreateError:
 'Excel ist nicht vorhanden
 MsgBox "Kein Excel vorhanden"
 Excel_Connect = False
End Function
 
Private Sub Excel_Disconnect()
 'gegebenenfalls die Objektvariablen wieder freigeben
 'Wir wollen ja keinen Verweis auf Excel zurücklassen
 On Error Resume Next
 Set oExcel_App = Nothing
End Sub

 
Public Sub Aufgabe()
 If Not Excel_Connect Then Exit Sub 'Raus wenns brennt
 On Error GoTo Fehler
 oExcel_App.workbooks.Add
 With oExcel_App.activeworkbook.worksheets(1)
  .Cells(2, 2) = 100
  .Cells(3, 2) = 500
  .Cells(4, 2) = 200
  .Cells(5, 2) = 10
  .Cells(6, 2).Formula = "=Sum(B2:B5)"
  Selection.Text = .Cells(6, 2).Value
 End With
 Aufraeumen:
 Excel_Disconnect ' Nicht vergessen ;-) !!!!!!!!!!!!!!!!!!!!!!!!!
 Exit Sub
 Fehler:
 MsgBox Err.Description
 Resume Aufraeumen
End Sub



Code eingefügt mit: Word Code Jeanie

Das war doch einfach, oder?

Weitgehend war es nur ein kopieren unseres Modules.

Im nächsten Schritt werden wir uns mit Tipps, Fallstricken und nochmals Objekten beschäftigen.
Bis bald also

Dieses Thema hat weitere Beiträge

Zugriff auf andere Anwendungen (1) - Grundlagen und Irrtümer
Zugriff auf andere Anwendungen (2) - Excel und Word im Zusammenspiel

Weitere Artikel der Gruppe: Tutorials Aus Excel VBA
Nach oben