Galileo Computing < openbook >
Galileo Computing - Bücher zur Programmierung und Softwareentwicklung
Galileo Computing - Bücher zur Programmierung und Softwareentwicklung

...powered by haas.homelinux.net...

Einstieg in VB.NET von René Martin
- Für Programmiereinsteiger -
Einstieg in VB.NET
gp Kapitel 4 Zugriff auf andere Programme: Excel
  gp 4.1 Austausch mit Excel
  gp 4.2 Das Excel-Objektmodell
    gp 4.2.1 Das Objekt Application
    gp 4.2.2 Zugriff auf Excel-Arbeitsmappen
    gp 4.2.3 Zugriff auf Tabellenblätter
  gp 4.3 Zugriff von außen auf Excel


Galileo Computing

4.2 Das Excel-Objektmodell  downtop


Galileo Computing

4.2.1 Das Objekt Application  downtop

Um die folgenden Codezeilen nachzuvollziehen, benötigen Sie Excel in der Version 97, 2000 oder 2002. Öffnen Sie dort eine beliebige Datei und wechseln Sie über Extras Makro Visual Basic-Editor in die Programmierumgebung von VBA. Erstellen Sie ein neues Modul (Menü Einfügen Modul). Jetzt kann es mit einer neuer Prozedur losgehen:

Abbildung

Abbildung 4.1   Die Programmierumgebung von Excel

Sub ExcelTest

End Sub

Oberstes Objekt von Excel ist das Objekt Application. Damit ist das Programm, das heißt Excel selbst, gemeint. Es hat eine Reihe von Eigenschaften und Methoden:

Application.Name

liefert den Namen des Programms, also »Microsoft Excel«.

Application.Path

liefert den Pfad der Programmdatei »Excel.exe«.

Application.Caption

gibt den Text der Titelzeile zurück. Dieser kann, da es sich um eine Eigenschaft handelt, geändert werden, beispielsweise in

Application.Caption = "Lotus 1-2-3"

Um sich das Ergebnis anzusehen, kann man ein Meldungsfenster verwenden. Achtung: Der Befehl lautet in VBA »MsgBox«, also beispielsweise

MsgBox (Application.Name)
Abbildung

Abbildung 4.2   Das erste Programm meldet den Namen der Applikation.


Galileo Computing

4.2.2 Zugriff auf Excel-Arbeitsmappen  downtop

Eine Excel-Datei, das heißt eine Arbeitsmappe, ist unterteilt in Arbeitsblätter. Diese wiederum sind untergliedert in Zellen, die in Zeilen und Spalten angeordnet sind.

Die aktuelle Excel-Datei ist

Application.ActiveWorkbook

Die Anzahl der (offenen) Excel-Dateien beträgt

Application.Workbooks.Count

Man kann einen Zähler alle Dateien durchlaufen lassen oder direkt alle Objekte ansprechen:

Sub Alle_Dateien1()
   Dim i As Integer
   Dim strDatName As String

   For i = 1 To Workbooks.Count
      strDatName = strDatName & vbCr & Workbooks(i).Name
   Next

   MsgBox (strDatName)
End Sub

oder auch mit einem direkten Objektzugriff arbeiten:

Sub Alle_Dateien2()
   Dim xlsDatei As Workbook
   Dim strDatName As String

   For Each xlsDatei In Workbooks
      strDatName = strDatName & vbCr & _
      xlsDatei.Name
   Next

   MsgBox(strDatName)
End Sub
Abbildung

Abbildung 4.3   Alle offenen Dateien

Somit kann überprüft werden, ob eine Datei schon geöffnet ist oder nicht. Falls ja, wird sie nach vorne geholt, falls nein, wird sie geöffnet:

Sub DateiÖffnen()
Dim xlsDatei As Workbook
Dim strDatName As String

On Error Resume Next

For Each xlsDatei In Workbooks
   If xlsDatei.Name = "Rechnung.xls" Then
      xlsDatei.Activate
      Exit Sub
   End If
Next

Workbooks.Open Filename:= __
   "C:\Eigene Dateien\Uebungsdateien" & _
   "\Excel\Rechnung.xls"
End Sub

Eine Datei wird, wie oben ersichtlich, mit der Methode Open geöffnet, mit Close geschlossen und mit Save oder SaveAs gespeichert. Die Eigenschaft Saved prüft, ob eine Arbeitsmappe seit der letzten Änderung gespeichert wurde. Falls ja, wird der Wert True zurückgegeben.


Galileo Computing

4.2.3 Zugriff auf Tabellenblätter  toptop

Jede Excel-Datei hat ein oder mehrere Tabellenblätter. Auch diese können durchlaufen werden. Dabei ist das Objekt von Workbook entweder »Sheet« oder »WorkSheet«. »Sheet« ist dabei allgemeiner, da Tabellenblätter auch Diagramme beinhalten können. Deklariert wird es allerdings vom Objekttyp »Worksheet«.

Sub TabellenBlätterDurchlaufen()
   Dim xlsTabBlatt As Worksheet
   Dim strBlattName As String

   On Error Resume Next

   For Each xlsTabBlatt In Sheets
      strBlattName = strBlattName & vbCr & _
      xlsTabBlatt.Name
   Next

   MsgBox (strBlattName)
End Sub
Abbildung

Abbildung 4.4   Alle Tabellenblätter einer Datei werden angezeigt.

Ein Blatt wird mit der Methode Activate aktiviert. Ist es verborgen, so kann dies mit der Eigenschaft Visible überprüft werden. Gelöscht wird ein Blatt mit der Methode Delete, hinzugefügt mit Add. Die Eigenschaft Name übergibt den Namen. Im folgenden Programm wird der Benutzer nach dem Namen eines Tabellenblatts gefragt. Dabei ist die InputBox in VBA ein einfaches Fenster, in welches der Benutzer etwas eintragen kann. Existiert das eingegebene Tabellenblatt, so wird es angesprungen, existiert es nicht, erhält der Benutzer einen Hinweis.

Sub Tabellenblättersuche()
   Dim xlsTabBlatt As Worksheet
   Dim strBlattName As String

   On Error Resume Next

   strBlattName = _
   InputBox("Wie lautet der Name des " & _
   "gesuchten Blatts?", "Blattsuche")

   For Each xlsTabBlatt In Sheets
      If LCase(strBlattName) = _
      LCase(xlsTabBlatt.Name) Then
         xlsTabBlatt.Activate
         Exit Sub
      End If
   Next

MsgBox("Das gesuchte Blatt " & strBlattName & _
" wurde leider nicht gefunden.")
End Sub

Die VBA-Funktion LCase dreht die Schreibweise in Kleinbuchstaben. Damit wird nicht nach Groß- und Kleinschreibung unterschieden. Will man auch Textteile suchen können, dann muss die If-Verzweigung modifiziert werden:

   If InStr(LCase(xlsTabBlatt.Name), _
      LCase(strBlattName)) > 0 Then
[...]

Die wohl häufigste Zugriffsart ist sicherlich der Zellzugriff. Dabei kann der Cursor auf eine Zelle gesetzt, und diese (ActiveCell) dann modifiziert werden. Eleganter ist dagegen ein indirekter Verweis mit Hilfe von Objektvariablen. Hierfür steht eine ganze Reihe von Möglichkeiten zur Verfügung.

Angenommen, Sie möchten auf die Zelle B41 des Tabellenblatts »Hitchcock« der Datei »Filme.xls« zugreifen. Ist diese Datei offen, dann kann sie angesprungen werden. Danach wird das Tabellenblatt aktiviert und schließlich die Zelle. Der Zugriff darauf erfolgt mit dem Objekt »Range« oder dem Objekt »Cells«:

Sub AufB41Zugreifen()
   Application.Workbooks("Filme.xls").Activate
   ActiveWorkbook.Sheets("Hitchcock").Activate
   ActiveSheet.Range("B41").Activate
End Sub
Abbildung

Abbildung 4.5   Der Cursor wird verschoben

Nun sitzt der Cursor auf der Zelle B41. Den Inhalt dieser Zelle könnte man mit

MsgBox (ActiveCell.Value)

auslesen.

Eleganter ist es dagegen mit einem direkten Objektzugriff:

   MsgBox (Application.Workbooks("Filme.xls"). _
      Sheets("Hitchcock").Range("B41").Value)

Solch eine riesige Befehlszeile ist weder übersichtlich noch praktisch zum Fehlerabfangen. Deshalb empfiehlt sich das Aufsplitten und Aufteilen an Objektvariablen. Beispielsweise so:

Sub AufB41Zugreifen3()
   Dim xlsDatei As Workbook
   Dim xlsTabelle As Worksheet
   Dim xlsZelle As Range

   Set xlsDatei = Application.Workbooks("Filme.xls")
   Set xlsTabelle = xlsDatei.Sheets("Hitchcock")
   Set xlsZelle = xlsTabelle.Range("B41")
   ' Alternativ:
   Set xlsZelle = xlsTabelle.Cells(41,2)

   MsgBox (xlsZelle.Value)
End Sub
Abbildung

Abbildung 4.6   Der Inhalt der Zelle B41 wird ausgelesen.

Zellinhalte können abgefragt werden (wie oben) oder auch gesetzt werden. Der Befehl

xlsZelle.Value = "Psycho II"

schreibt den Wert »Psycho II« in die Zelle. Statt des Objekts »Range« kann auch »Cells« als Sammlung verwendet werden:

Set xlsZelle = xlsTabelle.Cells(41, 2)

Dabei wird zuerst die Zeile (Rows) und dann die Spalte (Columns) angegeben. Der Zugriff über Cells eignet sich sehr gut, wenn mit Variablen gearbeitet wird.

Mit dem Objekt Range kann nicht nur auf eine Zelle zugegriffen werden:

ActiveSheet.Range("A4").Activate

sondern auch auf einen Bereich:

ActiveSheet.Range("A4:D7").Activate

Ebenso wählt

ActiveSheet.Range("A1:D7").Select

diesen Bereich aus. Mit Activate kann zusätzlich eine Zelle innerhalb des markierten Bereichs selektiert werden:

ActiveSheet.Range("A1:F7").Select
ActiveSheet.Range("C3").Activate

Auf den ersten Blick umständlicher funktioniert das Auswählen über den Bereich:

   ActiveSheet.Range(ActiveSheet.Cells(1, 1), _
      ActiveSheet.Cells(3, 3)).Activate

Der Vorteil hierbei ist allerdings, dass die Eckkoordinaten getrennt berechnet werden können:

   x1 = 1
   x2 = 3
   y1 = 1
   y2 = 3
ActiveSheet.Range(ActiveSheet.Cells(x1, y1), _
   ActiveSheet.Cells(x2, y2)).Activate

Ähnlich wie die Range-Methode einen Bereich auswählt (oder bearbeitet), kann mit dem Objekt beziehungsweise der Methode Worksheets ein Arbeitsblatt aktiviert werden. Soll beispielsweise der Zellbereich »A1:C3« des Blatts »Tabelle3« fett formatiert werden, so kann dies folgendermaßen eingegeben werden:

   Worksheets("Tabelle3").Activate
   x1 = 1
   x2 = 3
   y1 = 1
   y2 = 3

   With ActiveSheet.Range _
   (ActiveSheet.Cells(x1, y1), _
      ActiveSheet.Cells(x2, y2))
      .Select
      .Font.Bold = True
   End With

Mit einem ähnlichen Objekt wie »Cells« kann man sich bewegen. Sitzt der Cursor auf der Zelle B9, so wird er auf die Zelle B10 mit dem Befehl

ActiveCell.Offset(1, 0).Activate

gesetzt. Von B9 wird er auf B8 mit

ActiveCell.Offset(-1, 0).Activate

bewegt, auf C9 mit:

ActiveCell.Offset(0, 1).Activate

Soll dagegen nur ein Wert überprüft oder gesetzt werden, so genügt:

MsgBox(ActiveCell.Offset(1, 0).Value)

Der Cursor bleibt auf der alten Zelle und zeigt den Wert der darunter liegenden Zelle an. Wird nun ein bestimmter Bereich durchlaufen, so hilft hierbei das Objekt CurrentRegion. Es hat die beiden Eigenschaften Rows und Columns, die beide wiederum die Eigenschaft Count besitzen. Darüber kann die Anzahl der Zeilen oder Spalten aus einem ausgefüllten Bereich ermittelt werden.

Beispiel: In einer Tabelle sind drei Spalten ausgefüllt. In der ersten, die mit »Nummer« überschrieben ist, stehen fortlaufende Nummern. In der zweiten Spalte stehen die Bezeichnungen, die sich hinter den Nummern verbergen, in der dritten die (fiktiven) Preise (für die Videos):

Der Benutzer wird nach einer Nummer gefragt. Er trägt sie in eine Inputbox ein und erhält den Namen des Films:

Sub FilmAnzeigen1()
   Dim intNr As Integer
   Dim intZähler As Integer
   On Error GoTo ende
   ActiveWorkbook.Sheets("Hitchcock").Activate
   ActiveSheet.Range("A1").Select
   intZähler = 0

   intNr = InputBox("Bitte eine Nummer.")

   With ActiveCell
      For intZähler = 1 To _
         .CurrentRegion.Rows.Count
        
         If ActiveCell.Offset(intZähler, _
         0).Value = intNr Then
            MsgBox("Der Film mit der Nummer " & _
            intNr & " lautet: " & _
            vbCr & Chr(187) & _
            ActiveCell.Offset(intZähler, _
            1).Value & _
            Chr(171) & vbCr & " und kostet " & _
            Format (ActiveCell.Offset _
               (intZähler, 2).Value, "0.00") & _
                " Euro")
            Exit Sub
         End If
      
      Next intZähler
   End With
   MsgBox("Schade, aber die Nummer " & intNr & _
      " wurde nicht gefunden!")
   Exit Sub
ende:
   MsgBox("Es trat ein Fehler auf: " & _
      Err.Description, vbCritical, "Fehler!")
End Sub
Abbildung

Abbildung 4.7   Die Nummer wird eingegeben, der Film wird gesucht und gefunden.

Die Vorgehensweise: Der Benutzer wird nach einer Nummer gefragt. Im Tabellenblatt »Hitchcock« wird die Zelle A1 aktiviert. Eine For ... Next-Schleife durchläuft die Tabelle von A1 bis zu der letzten gefüllten Zelle, die über die Eigenschaft ActiveCell.CurrentRegion.Rows.Count ermittelt wird. Jede der Zellen wird mit dem Inhalt der Inputbox-Variablen verglichen (intNr). Sind sie gleich, hüpft der Zeiger eine Spalte nach rechts und zeigt den Inhalt dieser Zelle an. Wird die Schleife ohne Erfolg durchlaufen, dann wird die Meldung unterhalb der Schleife angezeigt.

Das Ganze funktioniert allerdings eleganter, ohne dass die Position des Markierungszeigers verändert wird:

Sub FilmAnzeigen2()
   Dim xlApp As Application
   Dim xlMappe As Workbook
   Dim xlTabelle As Worksheet
   Dim xlZelle As Range

   Dim intNr As Integer
   Dim intZähler As Integer
   On Error GoTo ende

   Set xlApp = Application
   Set xlMappe = xlApp.ActiveWorkbook
   Set xlTabelle = xlMappe.Sheets("Hitchcock")
   Set xlZelle = xlTabelle.Range("A1")

   intZähler = 0
   intNr = InputBox("Bitte eine Nummer.")

   With xlZelle
      For intZähler = 1 To _
         .CurrentRegion.Rows.Count
        
         If ActiveCell.Offset(intZähler, _
            0).Value = intNr Then
           MsgBox "Der Film mit der Nummer " & _
       intNr & " lautet: " & vbCr & Chr(187) & _
       xlZelle.Offset(intZähler, 1).Value & _
       Chr(171) & vbCr & " und kostet " & _
       Format.Offset _
       (intZähler, _2).Value, "0.00")
            Exit Sub
         End If
      
      Next intZähler
   End With

   MsgBox "Schade, aber die Nummer " & intNr & _
      " wurde nicht gefunden!"
   Exit Sub

ende:
   MsgBox "Es trat ein Fehler auf: " & _
    Err.Description, vbCritical, "Fehler!"
End Sub

Nun soll ein zweites Symbol in der Filmliste dafür sorgen, dass der Benutzer einen neuen Artikel eintragen kann. An ihn wird automatisch die nächsthöhere Nummer vergeben und der Artikel wird unten an die Liste angefügt. Die Liste könnte mit einer Do ... Loop-Until-Schleife durchlaufen werden (wie in »Filmanzeigen1«) oder indem die Anzahl der vorhandenen Zellen bestimmt wird. Letzteres ist eleganter:

Sub NeuerFilm()
   Dim xlApp As Application
   Dim xlMappe As Workbook
   Dim xlTabelle As Worksheet
   Dim xlZelle As Range

   Dim intZeilen As Integer
   Dim strNeuTitel As String
   Dim curNeuPreis As Currency
   On Error Resume Next

   Set xlApp = Application
   Set xlMappe = xlApp.ActiveWorkbook
   Set xlTabelle = xlMappe.Sheets("Almodóvar")
   Set xlZelle = xlTabelle.Range("A1")

   intZeilen = xlZelle.Rows.Count

   strNeuTitel = _
      InputBox("Wie lautet der Name des " & _
      "neuen Films?")
   curNeuPreis = InputBox("Was kostet " & _
      strNeuTitel & "?")

   With xlZelle
      .Offset(intZeilen, 0).Value = _
      100 + intZeilen
       .Offset(intZeilen, 1).Value = strNeuTitel
       .Offset(intZeilen, 2).Value = curNeuPreis
   End With
End Sub
Abbildung

Abbildung 4.8   Die beste Möglichkeit, auf Zellen zuzugreifen, ist das Verwenden von Objektvariablen.

Damit sind die wichtigsten Excel-Befehle erklärt, mit denen man per VBA auf Daten innerhalb von Zellen zugreifen kann.

  

VB.NET

Einstieg in ASP.NET

Einstieg in C#

Visual C#

VB.NET und Datenbanken

Einstieg in XML