Zur Hauptseite ... Zum Onlinearchiv ... Zum Abonnement ... Zum Newsletter ... Zu den Tools ... Zum Impressum ... Zum Login ...

Achtung: Dies ist nicht der vollständige Artikel, sondern nur ein paar Seiten davon. Wenn Sie hier nicht erfahren, was Sie wissen möchten, finden Sie am Ende Informationen darüber, wie Sie den ganzen Artikel lesen können.

Kompletten Artikel lesen?

Einfach für den Newsletter anmelden, dann lesen Sie schon in einer Minute den kompletten Artikel und erhalten die Beispieldatenbanken.

E-Mail:

Gedrucktes Heft

Diesen Beitrag finden Sie in Ausgabe 2/2005.

Unser Angebot für Sie!

Lesen Sie diesen Beitrag und 500 andere sofort im Onlinearchiv, und erhalten Sie alle zwei Monate brandheißes Access-Know-how auf 72 gedruckten Seiten! Plus attraktive Präsente, zum Beispiel das bald erscheinende Buch 'Access 2010 - Das Grundlagenbuch für Entwickler'!

Diesen Beitrag twittern

Formular mehrfach anzeigen

André Minhorst, Duisburg

In den meisten Fällen reicht eine Instanz eines Formulars zum Darstellen der gewünschten Daten aus. Selbst wenn man einmal zwei oder mehr Datensätze vergleichen möchte, kann man diese in Listenform untereinander anzeigen. Wenn die betreffenden Datensätze allerdings einmal mehr Felder enthalten, als nebeneinander angezeigt werden können, kommt schnell der Wunsch nach der Verwendung mehrerer Instanzen eines Formulars mit unterschiedlichen Datensätzen auf. Wie Sie das realisieren, erfahren Sie im vorliegenden Beitrag.

Mehrere Formulare?

Die Anzeige mehrerer gleicher Formulare mit verschiedenen Datensätzen ist vor allem sinnvoll, wenn Sie beispielsweise Daten von Artikeln, Kunden, Lieferanten oder Mitarbeitern ansehen und vergleichen möchten.

Wenn Sie die Formulare aus Abb. 1 beispielsweise noch nebeneinander positionieren, können Sie die Eigenschaften der Artikel gut miteinander vergleichen.

Abb. 1: Mehrere Formularinstanzen mit verschiedenen Artikeln

Mehrere physikalisch vorhandene
Formulare

Wer nicht zu VBA greifen möchte, um mehrere Datensätze gleichzeitig in je einem einzigen Formular anzuzeigen, kann theoretisch das gewünschte Formular mehrmals kopieren und mit unterschiedlichen Namen versehen. Ganz davon abgesehen, dass auch hier ein wenig VBA-Code nötig ist, um beispielsweise zu prüfen, welche Kopie des Formulars schon geöffnet ist und welche man als Nächstes verwendet, hat diese Variante zwei große Nachteile: Erstens müssen Sie Änderungen entweder direkt an allen Exemplaren durchführen oder bei jeder Änderung alle Kopien löschen und durch neue Kopien des geänderten Originalformulars ersetzen. Zweitens ist diese Variante nicht besonders flexibel: Die Anzahl der verfügbaren Formulare ist in jedem Fall begrenzt.

Mehrere Instanzen eines Formulars

Die alternative Variante besteht in der Verwendung eines einzigen Formulars, das Sie mehrfach öffnen können - und zwar mit verschiedenen Inhalten. Dazu ist zwar ein wenig VBA-Code erforderlich, aber es handelt sich nur um wenige Zeilen, wie Sie nachfolgend sehen werden.

Beispieldatenbank

Das nachfolgend beschriebene Beispiel bezieht sich auf die Anzeige von Daten verschiedener Artikel aus der Nordwind-Datenbank. Um den Aufwand beim Nachvollziehen des Beispiels gering zu halten, können Sie einige bereits bestehende Objekte aus der Nordwind-Datenbank verwenden.

Wenn Sie das Beispiel nachvollziehen möchten, legen Sie eine neue, leere Datenbank an und importieren zunächst einige Objekte aus der Nordwind-Datenbank:

  • Führen Sie den Menübefehl Datei/Externe Daten/Importieren... aus.
  • Wählen Sie die Datei Nordwind.mdb aus. Sie befindet sich üblicherweise im Office-Verzeichnis.
  • Importieren Sie die Tabellen Artikel, Kategorien und Lieferanten und das Formular Artikel. (
  • Formular-Objekte erzeugen

    Die Anweisung DoCmd.OpenForm öffnet jeweils die Standardinstanz eines Formulars. Auch das wiederholte Aufrufen bringt keine weiteren Instanzen hervor.

    Ein Formular ist aber ein Objekt und diese lassen sich in der Regel auch mehrfach erzeugen. Dazu deklarieren Sie einfach eine Variable mit einem der gewünschten Formularklasse entsprechenden Datentyp. Diesen Datentyp können Sie ganz leicht ermitteln: Es handelt sich dabei um den Formularnamen mit vorangestelltem "Form_". Um eine Objektvariable zu deklarieren, deren Datentyp der Klasse des zu erzeugenden Formulars entspricht, verwenden Sie im Fall des Formulars Artikel also folgende Zeile:

    Dim frm As Form_Artikel

    Hinweis

    Wenn Sie eine entsprechende Objektvariable für einen Bericht erzeugen möchten, gehen Sie genauso vor - lediglich das Suffix des Ausdrucks für den Datentyp lautet dann "Report_". (

    Nun füllen Sie die Objektvariable mit dem Objekt:

    Set frm = New Form_Artikel

    Damit haben Sie eine neue Instanz des Formulars erzeugt, die aber noch nicht sichtbar ist. Die nächste Anweisung lautet folglich:

    frm.Visible = True

    Wenn Sie diese drei Anweisungen in eine Prozedur in einem Standardmodul packen und über das Testfenster aufrufen, sollten Sie doch eigentlich die gewünschten Formulare erstellen können.

    Public Sub FormularinstanzErstellen()

        Dim frm As Form_Artikel

        Set frm = New Form_Artikel

        frm.Visible = True

    End Sub

    Oder doch nicht? Wenn Sie es ausprobieren, sehen Sie zwar ein kurzes Aufflackern, aber das Formular verschwindet sofort wieder. Kein Wunder: Die innerhalb einer Prozedur deklarierten und erzeugten Objekte leben nicht länger als die Prozedur selbst. Klammern Sie also die Deklaration aus der Prozedur aus und ändern Sie ihren Gültigkeitsbereich auf Public:

    Public frm As Form_Artikel

    Ein erneuter Aufruf der Prozedur FormularinstanzErstellen führt zum Erfolg: Das Artikel-Formular erscheint. Aktivieren Sie einen anderen als den zuerst angezeigten Artikel-Datensatz. Führen Sie die Prozedur zum Erzeugen einer Formularinstanz erneut aus und schauen Sie, was passiert: Das erste Formular verschwindet und ein neues erscheint - das erkennen Sie daran, dass wieder der erste Datensatz der Datenherkunft angezeigt wird. Das war eigentlich zu erwarten, denn der Inhalt der Objektvariablen wird mit dem neuen Objekt überschrieben.

    Wie es aussieht, benötigen Sie also mehrere Objektvariablen, um mehr als eine Instanz des Formulars anzuzeigen. Damit wären Sie wieder an einer ähnlichen Stelle wie am Anfang. Dort gab es ja alternativ zu diesem Weg die Möglichkeit, einfach mehrere gleiche Formulare zu erstellen - und nun soll das statische Deklarieren mehrerer Objektvariablen das Ende vom Lied sein? Nein, das ist es natürlich nicht. Objektvariablen können Sie zur Laufzeit deklarieren und erzeugen, so viele Sie möchten - und Sie können auch unterschiedliche Instanzen des gewünschten Objekts damit kontrollieren.

    Formulare im Collection-Objekt

    Das Zauberwort heißt Collection-Objekt. Das ist das Pendant zu Arrays, nur dass Sie darin Objekte aufbewahren und wieder entfernen und natürlich auch auf die enthaltenen Objekte zugreifen können.

    Für ein solches Objekt gelten genau die gleichen Regeln wie für die übrigen Variablen: Sie haben den gleichen Gültigkeitsbereich - also global, objektweit oder prozedurweit - und werden gleichzeitig mit dem Objekt, in dem sie enthalten sind, zerstört.

    Ein Collection-Objekt hat zwei Methoden und zwei Eigenschaften:

  • Add: Fügt ein Objekt hinzu.
  • Remove: Entfernt ein Objekt.
  • Count: Gibt die Anzahl der enthaltenen Objekte wieder.
  • Item: Dient zum Bezugnehmen auf ein bestimmtes Objekt innerhalb der Collection.
  • Im folgenden Beispiel fügen Sie die Kenntnis um die Tatsache, dass man Formular-Objekte beliebig oft erzeugen und diese Objekte in Collections sammeln kann, zu einer kleinen Beispielanwendung zusammen.

    Jedem Artikel sein Formular

    Sie haben bereits erfahren, dass Objekte wie auch Collections wieder zerstört werden, wenn auch das Objekt, in dessen Gültigkeitsbereich Sie diese deklariert haben, zerstört wird.

    Im Beispiel soll dieses Objekt ein Formular sein, das die Artikelbezeichnungen aus der Artikeltabelle in einem Listenfeld anzeigt und einige Schaltflächen zum Anzeigen und Entfernen eines Detailformulars zu dem jeweiligen Artikel enthält. Die damit erzeugten Formularobjekte können manuell wieder geschlossen werden, aber spätestens mit dem Schließen des aufrufenden Formulars ist ihre Zeit vorbei.

    Das Formular ist recht einfach aufgebaut, wie Abb. 2 zeigt. Das Listenfeld hat den Namen lstArtikel und als Datensatzherkunft die Tabelle Artikel.

    Abb. 2: Formular zum Öffnen der Detailansicht von Artikeln

    Sowohl die Prozedur, die durch das Beim Doppelklicken-Ereignis des Listenfeldes, als auch die, die durch das Beim Klicken-Ereignis der Schaltfläche cmdAnzeigen ausgelöst wird, enthält lediglich die folgende Anweisung:

    ArtikelAnzeigen Me.lstArtikel, _
        Me.lstArtikel.Column(1)

    Die aufgerufene Prozedur ArtikelAnzeigen enthält die eigentliche Funktion. Sie finden diese Prozedur in Quellcode 2.

    Private colFrmArtikel As New Collection

    Private Private Sub ArtikelAnzeigen(lngArtikelID As _
            Long, strArtikel As String)

        'Kontrollieren, ob Artikel schon angezeigt wird...

        Dim i As Integer

        Dim intFormCount As Integer

        intFormCount = colFrmArtikel.Count

        If intFormCount > 0 Then

            For i = 1 To intFormCount

                If colFrmArtikel.Item(i).Form.Tag = _
                    "Artikel" & lngArtikelID Then

                    colFrmArtikel.Item("Artikel" & _
                        lngArtikelID).Form.SetFocus

                    Exit Sub

                End If

            Next i

        End If

        '... und falls nicht, eine neue Formularinstanz 
        'mit dem Artikel öffnen.

        Dim frm As Form_Artikel

        Set frm = New Form_Artikel

        With frm

            .Filter = "[Artikel-Nr] = " & lngArtikelID

            .FilterOn = True

            .Tag = "Artikel" & lngArtikelID

            .Caption = "Artikel: " & strArtikel

            .Visible = True

        End With

        colFrmArtikel.Add frm, "Artikel" & lngArtikelID

        intFormCount = colFrmArtikel.Count

        DoCmd.MoveSize (intFormCount * 500) + 1000, _
            (intFormCount * 500) + 1000

    End Sub

    Quellcode 2

    Die allein stehende Deklaration der Collection colFrmArtikel sorgt dafür, dass die Collection formularweit verfügbar ist und erst zerstört wird, wenn Sie das Formular schließen.

    Damit werden dann auch alle in der Collection enthaltenen Formulare - also die Detailansichten der Artikel - geschlossen.

    Die Prozedur ArtikelAnzeigen prüft zunächst, ob das zu instanzierende Formular bereits vorhanden ist. Vergessen Sie diesen Teil vorerst - Sie benötigen noch einige Details, um ihn zu verstehen. Schauen Sie sich zunächst an, was die Prozedur macht, wenn der betreffende Artikel noch nicht in einem Formular angezeigt wird.

    In dem Fall deklariert die Prozedur zunächst eine Objektvariable des Datentyps Form_Artikel. Mit der Set-Anweisung erzeugt sie eine neue Instanz des Form_Artikel-Objekts.

    Mit dieser Instanz des Artikel-Formulars passieren dann folgende Dinge:

  • Der Filter wird auf den aktuell im Listenfeld markierten Artikel gesetzt und aktiviert.
  • Die Tag-Eigenschaft erhält einen Ausdruck, der sich aus der Zeichenkette "Artikel" und der Artikelnummer zusammensetzt.
  • Der Titel des Formulars wird aus der Zeichenkette Artikel: und der Artikelnummer zusammengesetzt.
  • Das Formular wird sichtbar gemacht.
  • Nun muss die Instanz noch im Collection-Objekt untergebracht werden. Dazu verwendet die Prozedur dessen Add-Methode. Die Methode hat zwei Parameter: Den Parameter namens Item füllen Sie mit der das Formular repräsentierenden Objektvariablen und dem Parameter Key weisen Sie den gleichen Wert zu, den bereits die Tag-Eigenschaft der neuen Formularinstanz erhalten hat. So können Sie beispielsweise mit dem folgenden Ausdruck das Formular referenzieren, das den Artikel mit der Artikelnummer 4 anzeigt:

    colFrmArtikel.Item("Artikel" _
        & lngArtikelID).Form

    Private Sub cmdSchliessen_Click()

        ArtikelAusblenden "Artikel" & Me.lstArtikel

    End Sub

    Quellcode 3

    Public Sub ArtikelAusblenden(strTag As String)

        On Error GoTo ArtikelAusblenden_Err

        colFrmArtikel.Item(strTag).Tag = ""

        colFrmArtikel.Remove strTag

    ArtikelAusblenden_Exit:

        Exit Sub

    ArtikelAusblenden_Err:

        If Err.Number = 5 Or Err.Number = 9 Then

            GoTo ArtikelAusblenden_Exit

        Else

            MsgBox Err.Number & " " & Err.Description

            GoTo ArtikelAusblenden_Exit

        End If

    End Sub

    Quellcode 4

    Zuletzt sorgen Sie noch dafür, dass jedes neue Formular versetzt zum vorherigen angezeigt wird. Dazu ermitteln Sie die Anzahl der bisherigen Instanzen des Formulars und verschieben die neue Instanz um einen entsprechenden Wert nach rechts unten.

    Jetzt, da Sie wissen, dass Sie über den in der Tag-Eigenschaft enthaltenen Wert auf den entsprechenden Eintrag des Formulars in der Collection colFrmArtikel zugreifen können, macht eine Betrachtung des ersten Teils der Prozedur ArtikelAnzeigen Sinn: Hier zählt die Prozedur zunächst die Elemente der Collection und speichert das Ergebnis in der Integer-Variablen intFormCount. Wenn eines oder mehr Elemente enthalten sind, durchläuft eine For Next-Schleife alle Elemente der Collection und überprüft, ob die Tag-Eigenschaft eines der in der Collection enthaltenen Formulare mit dem Wert übereinstimmt, der für die neue Instanz verwendet würde. Ist das der Fall und damit schon ein Formular für diesen Artikel vorhanden, erhält dieses den Fokus und die Prozedur wird verlassen. Anderenfalls folgt das weiter oben bereits beschriebene Anlegen der neuen Instanz.

    Schließen einer
    Formularinstanz

    Die Beispielanwendung soll die Möglichkeit bieten, eine Formularinstanz eines im Listenfeld ausgewählten Artikels wieder zu schließen. Dazu dient die Schaltfläche cmdSchliessen. Die Prozedur, die durch die Ereigniseigenschaft Beim Klicken ausgelöst wird, sieht wie in Quellcode 3 aus.

    Die Prozedur ruft eine Routine namens ArtikelAusblenden auf und übergibt einen aus der Zeichenkette "Artikel" und der Artikelnummer des im Listenfeld ausgewählten Artikel als Parameter - das ist der Wert, der weiter oben bereits als Inhalt der Tag-Eigenschaft der Formularinstanzen und als Key-Wert der Collection-Elemente verwendet wurde.

    Die Prozedur ArtikelAusblenden setzt den Wert der Tag-Eigenschaft des gesuchten Formulars auf eine leere Zeichenfolge. Den Hintergrund für diesen Schritt erfahren Sie weiter unten. Außerdem verwendet die Prozedur die Remove-Methode der Collection, um den Eintrag mit dem als Parameter übergebenen Key-Wert aus der Collection zu entfernen und die Formularinstanz damit zu zerstören (s. Quellcode 5).

    Und dann wäre da noch die Fehlerbehandlung: Diese sorgt dafür, dass Fehler, die durch den Versuch, ein nicht vorhandenes Formular zu löschen, entstehen, sich nicht bemerkbar machen.

    Sie haben das Ende des frei verfügbaren Teils des Artikels erreicht. Lesen Sie weiter, um zu erfahren, wie Sie den vollständigen Artikel lesen und auf viele hundert weitere Artikel zugreifen können.

    Sind Sie Abonnent?Jetzt einloggen ...
     

    Kompletten Artikel lesen?

    Einfach für den Newsletter anmelden, dann lesen Sie schon in einer Minute den kompletten Artikel und erhalten die Beispieldatenbanken.

    E-Mail:

    © 2003-2015 André Minhorst Alle Rechte vorbehalten.