Autor: Peter Haserodt --- Aus Excel VBA - Gruppe:
TutorialsZugriff 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)
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 |
| A | B | C | 1 | | | | 2 | | 100 | | 3 | | 500 | | 4 | | 200 | | 5 | | 10 | | 6 | | 810 | | 7 | | | | |
|
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
Weitere Artikel der Gruppe: Tutorials Aus Excel VBA
Nach oben