Beispiel Telefonverzeichnis ◦ Zusammenfassung ◦ ?

a) Aufgabe

Die Arbeitsmappe LTelefonverzeichnis.xls enthält eine Anwendung, die ein kleines Objektmodell aus einer benutzerdefinierten Objektklasse und einer Auflistung implementiert. Das Bild unten zeigt die Benutzerschnittstelle. Die Namen und Telefonnummern, die man im oberen Eingabebereich eingibt, werden beim Klicken der Hinzufügen-Schaltfläche in internen Objekten gespeichert und die Objekte einer Auflistung hinzugefügt. Es wird eine Telefonliste aufgebaut. Ein Klick auf die Liste-Schaltfläche gibt alle gespeicherten Datenpaare in sortierter Reihenfolge im unteren Ausgabebereich aus. Ausserdem kann man einen Namen im 'Name'-Eingabefeld eingeben und über die Suchen-Schaltfläche die Telefonnummer suchen lassen.

Die Anwendung sei spezifiziert und die Benutzerschnittstelle entworfen. Sie soll nun implementiert werden (vgl. Fallbeispiel Bibliothek, siehe auch Übungsaufgabe "Telefonverzeichnis").

b) Entwurf des Objektmodells

Das folgende Bild skizziert die Objekte der laufenden Anwendung und die Objektvariablen, welche die Objektverweise speichern:

Das Programm benötigt also die folgenden Komponenten:

- mehrere 'Eintrag'-Objekte, die jeweils den Namen und die Telefonnummer einer Person zusammenfassen
- ein 'Auflistung'-Objekt, das die Einträge zu einem Verzeichnis zusammenfasst
- eine Objektvariable 'Verzeichnis', über die man auf das Auflistung-Objekt zugreifen kann
- eine Objektvariable 'Eintrag', über die man auf ein Eintrag-Objekt zugreifen kann
- einen Algorithmus, der die Einträge im Verzeichnis alphabetisch sortiert.

c) Implementation des Verzeichnisses

Für die Implementation des 'Auflistung'-Objekts findet man bereits einen geeigneten Objekttyp in VBA - die Collection-Klasse. Ein Collection-Objekt ist eine geordnete Folge von Elementen, auf die als Einheit Bezug genommen werden kann. Geordnet heisst, dass jedes Element, ausser dem ersten und dem letzten, einen Vorgänger und einen Nachfolger hat. Das bedeutet nicht, dass die Elemente sortiert sind. Die Objekttypen der Elemente können beliebig sein, sie dürfen sogar innerhalb einer Collection variieren. Man beachte, dass die Collection-Klasse zu VBA und nicht zum Excel-Objektmodell gehört. Sie steht damit nicht nur in Excel zur Verfügung, sondern in jedem Anwendungspaket, das VBA enthält.

Collection-Objekte besitzen im Wesentlichen die gleichen Eigenschaften und Methoden wie die Auflistungen im Objektmodell von Excel. In benutzerdefinierten Objektmodellen werden denn auch Collection-Objekte benutzt, um Auflistungen zu implementieren. Wir werden deshalb oft auch Collection-Objekte als Auflistungen bezeichnen.

Jede Collection besitzt eine Count-Eigenschaft, sowie eine Add-, eine Item- und eine Remove-Methode. Im Gegensatz zu einer Auflistung des Objektmodells von Excel erstellt die Add-Methode einer Collection kein neues Objekt, sondern fügt nur ein zuvor erstelltes der Collection hinzu. Jedes hinzugefügte Element erhält einen Index, so dass man mit der Item-Methode darauf zugreifen kann. Die Nummerierung der Indizes läuft von 1 bis Count. Die Remove-Methode entfernt ein Element wieder aus der Auflistung.

Collection-Objekte werden wie benutzerdefinierte Objekte mit dem Schlüsselwort New erstellt. Das Erstellen und Benutzen von benutzerdefinierten Objekten geschieht in drei Schritten:

1. Objektvariable vereinbaren, z.B.

       Private Verzeichnis As Collection

   'Verzeichnis' wird auf Modulebene vereinbart, damit man von allen Prozeduren des Moduls aus auf das Verzeichnis zugreifen kann.

2. Objekt erstellen und der Variablen zuweisen, z.B.

       Set Verzeichnis = New Collection

   Die Zeile muss innerhalb einer Prozedur stehen. New erzeugt eine Instanz der Klasse Collection und gibt einen Verweis darauf zurück. Anschliessend wird der Verweis der Objektvariablen zugewiesen.

3. Über die Variable auf die Eigenschaften und Methoden zugreifen, z.B.

       Range("anzahl") = Verzeichnis.Count

   Die Zeile gibt die Anzahl Elemente der Auflistung auf dem Bereich "anzahl" des laufenden Tabellenblatts aus.

d) Implementation der Einträge

Die 'Eintrag'-Objekte zur Speicherung der Personendaten werden analog erstellt. Allerdings braucht man zuvor eine geeignete Klasse. Der Abschnitt über benutzerdefinierte Objektklassen zeigt ausführlich, wie man eigene Objektklassen definiert. Das Telefonverzeichnis-Projekt gibt einen ersten Einblick.

Klassen werden in VBA in Klassenmodulen beschrieben. Ein Klassenmodul ist ein VBA-Modul, das die Definition einer Objektklasse mit ihren Eigenschaften und Methoden enthält. Erstellt wird ein Klassenmodul wie ein Standardmodul mit dem Projektexplorer. Das nächste Bild zeigt das Projekt Telefonverzeichnis mit einem Klassenmodul cEintrag. Dem Namen 'Eintrag' wurde ein 'c' vorangestellt, um ihn als Name einer Klasse (engl. class) zu kennzeichnen.

In der Anwendung Telefonverzeichnis besitzen die 'Eintrag'-Objekte zwei Eigenschaften: Name und Telefon. Eigenschaften sind öffentliche Variablen eines Klassenmoduls. Das Modul cEintrag benötigt also lediglich zwei öffentliche Variablen.

Klassenmodul: cEintrag

    Option Explicit

    Public Name As String
    Public Telefon As String

Von dieser Klasse kann man nun wie von der Collection-Klasse mit dem Schlüsselwort New beliebig viele Instanzen erstellen. New erzeugt dabei für jede Instanz ein eigenes Variablenpaar Name und Telefon, so wie im Klassenmodul vereinbart. Das Erstellen und Benutzen der Instanzen geschieht wieder in drei Schritten:

1. Objektvariable vereinbaren. Als Objekttyp wird diesmal der Name der Klassenmoduls angegeben, z.B.

       Dim neuerEintrag As cEintrag

2. Objekt erstellen und der Variablen zuweisen, z.B.

       Set neuerEintrag = New cEintrag

3. Auf die Eigenschaften des Objekts zugreifen, z.B.

       neuerEintrag.Name = Range("name")
       neuerEintrag.Telefon = Range("telefon")

Das neue Objekt kann nun der zuvor erstellten Verzeichnis-Auflistung hinzugefügt werden. Ohne Angabe einer Position, wird es am Ende der Auflistung angehängt. Die Elemente werden damit im Verzeichnis in der Reihenfolge gespeichert, in der sie eingegeben werden.

    Verzeichnis.Add neuerEintrag

e) Implementation des Sortieralgorithmus

Möchte man die Einträge in alphabethischer Reihenfolge ausgeben lassen, so muss man das Verzeichnis zunächst sortieren. Algorithmen, die Listen sortieren, gibt es viele. Jeder hat Vor- und Nachteile, die sich oft erst bei konkreten Problemen zeigen. Der folgende Algorithmus wurde ohne Effizienzüberlegungen gewählt. Es soll lediglich das Arbeiten mit Auflistungen und Objektverweisen vertiefen.

Das "Sortieren durch Auswählen" arbeitet mit zwei Collection-Objekten. Zu Beginn enthält die erste Auflistung alle Elemente und die zweite ist leer. In alphabetischer Reihenfolge werden nun die Elemente der ersten Auflistung entnommen (ausgewählt) und jeweils am Ende der zweiten angehängt. Sobald die erste Auflistung leer ist, bricht der Algorithmus ab. Die zweite Auflistung enthält dann alle Elemente in sortierter Reihenfolge. Das Bild unten veranschaulicht an einem Beispiel den Zustand eines Verzeichnisses vor und nach der Sortierung. Es deutet an, dass tatsächlich nur Verweise, und nicht Objekte umsortiert werden.

Der folgende Entwurfscode formuliert den Algorithmus präziser. Die Implementation in VBA ist Gegenstand der nächsten Aufgabe.

    Sortiere durch Auswählen
      erstelle neues Verzeichnis (ohne Einträge)
      Solange noch Einträge im alten Verzeichnis
        suche kleinsten Eintrag im alten Verzeichnis
        füge Eintrag am Ende des neuen Verzeichnis ein
        entferne Eintrag aus altem Verzeichnis
      ersetzte altes Verzeichnis durch neues Verzeichnis.

    Suche kleinsten Eintrag im Verzeichnis
      setze kleinster Eintrag = erster Eintrag
      Für alle Einträge im Verzeichnis
        Falls aktueller Eintrag < kleinster Eintrag
          setze kleinster Eintrag = aktueller Eintrag.

Übungsaufgabe "Telefonverzeichnis"

©abo