Anlagen verwalten ohne Standarddialog

Wer den Anlagen-Datentyp und das dazugehörige Steuerelement mag, möchte vielleicht die Funktionen des Dialogs zum Verwalten von Anlagen gleich in eigene Formulare integrieren. Damit würde man auch die etwas unübersichtliche Darstellung in den Griff bekommen. Wie Sie ein solches Formular erstellen und einsetzen, lesen Sie in diesem Beitrag.

Das Anlage-Feld ist in der Standardansicht nicht besonders übersichtlich, erst nach dem Öffnen des Anlagen-Dialogs erscheint eine Liste der im Anlagefeld enthaltenen Dateien (s. Bild 1).

pic001.png

Bild 1: Anlage-Feld mit Anlagen-Dialog

Ziel dieses Beitrags ist, alle im Anlage-Feld gespeicherten Dateien gleich in einer Liste anzuzeigen und die Schaltflächen bereitzustellen, um Dateien hinzuzufügen, zu entfernen, zu öffnen, unter einem anderen Dateinamen zu speichern oder alle enthaltenen Dateien zu speichern – also genau wie im Standarddialog zur Verwaltung von Anlagen.

Um dieses Element einfach wiederverwertbar zu machen, verwenden wir dazu ein Unterformular, dem wir beim Öffnen einen Parameter mit dem Verweis auf das entsprechende Anlage-Feld übergeben. Das Unterformular soll die Dateien dann im einfachsten Fall in einem Listenfeld anzeigen. Denkbar wäre natürlich auch der Einsatz eines ListView-Steuerelements, das zusätzlich noch dem Dateityp entsprechende Icons anzeigen könnte.

Das benötigte Unterformular sieht im Entwurf wie in Bild 1 – mit Ausnahme der Schaltfläche Abbrechen, die ohnehin keinen anderen Nutzen als die OK-Schaltfläche besitzt.

pic002.png

Bild 2: Entwurf des Anlagen-Unterformulars

Das Hauptformular muss dem Unterformular irgendwie mitteilen, aus welchem Feld die anzuzeigenden Dateien eingelesen werden sollen. Da das übergeordnete Formular vermutlich einen Datensatz der Tabelle anzeigt, in dem sich das Anlagenfeld befindet, greifen wir entweder vom Unterformular auf das Hauptformular zu oder übergeben vom Hauptformular aus eine Referenz auf dieses Feld. Für den Moment verwenden wir im Unterformular zwei Objektvariablen namens m_AttachmentRecordset und m_Attachmentfield, die wie folgt im Klassenmodul des Formulars deklariert sind:

Dim m_Attachmentfield As DAO.Field2
Dim m_AttachmentRecordset As DAO.Recordset

Außerdem brauchen wir einen Verweis auf das Hauptformular, damit wir später auf das Wechseln des Datensatzes reagieren können:

Dim WithEvents m_Form As Form

Zusätzlich definieren wir eine öffentliche Prozedur zum Initialisieren des Formulars (s. Listing 1).

Listing 1: Initialisieren des Anlagen-Formulars

Public Sub Initialize(frm As Form, strAttachmentfield As String)
    Set m_Form = frm
    m_Form.OnCurrent = "[Event Procedure]"
    Set m_AttachmentRecordset = frm.RecordsetClone
    Set m_Attachmentfield = rstAttachment.Fields(strAttachmentfield)
    AnlagenAktualisieren
End Sub

Diese Prozedur speichert den Verweis auf das Formular, in dem sich das Unterformular befindet. Die Variable m_AttachmentRecordset wird mit einem Verweis auf den RecordsetClone des Hauptformulars gefüllt und m_AttachmentField mit einem Verweis auf das Anlage-Feld selbst.

Schließlich ruft die Prozedur noch eine weitere Routine namens AnlagenAktualisieren auf, die dafür verantwortlich ist, das Listenfeld mit den im Anlagefeld des aktuellen Datensatzes enthaltenen Anlagen zu füllen – dazu später mehr.

Listing 2: Anlagefeld aktualisieren

Private Sub AnlagenAktualisieren()
    m_AttachmentRecordset.Bookmark = m_Form.Recordset.Bookmark
    If Not m_Form.NewRecord Then
        AnlagenAuflisten
        Me!lstAnlagen = Me!lstAnlagen.ItemData(0)
    Else
        Me!lstAnlagen.RowSource = ""
    End If
    SchaltflaechenAktivieren
End Sub

Da das Formular frmAnlagen später als Unterformular dienen soll, fügen Sie es auch während der Entwicklung in ein weiteres Formular ein. In unserem Fall heißt dieses Formular frmKunden und zeigt die Daten der Tabelle tblKunden der Beispieldatenbank an (s. Bild 3).

pic004.png

Bild 3: Das Anlageformular als Unterformular

Fügen Sie das Unterformular in das Hauptformular ein und legen Sie für das Hauptformular eine Ereignisprozedur für die Eigenschaft Beim Laden an, die wie folgt aussieht:

Private Sub Form_Load()
    Me!frmAnlagen.Form.Initialize Me, "Dateianlagen"
End Sub

Diese Prozedur übergibt nur einen Verweis auf das Hauptformular sowie den Namen des Anlage-Feldes an die Initialize-Prozedur des Unterformulars.

Anlagen aktualisieren

Die oben referenzierte Prozedur AnlagenAktualisieren fasst einige Anweisungen zusammen, die sowohl beim erstmaligen Anzeigen des Anlagen-Listenfeldes, als auch beim späteren Datensatzwechsel im Hauptformular aufgerufen werden sollen (s. Listing 2). Die Prozedur prüft zunächst, ob das Hauptformular überhaupt einen Datensatz anzeigt. Falls ja, verschiebt es den Datensatzzeiger des unter m_AttachmentRecordset referenzierten Recordsets auf den aktuell im Formular angezeigten Datensatz und ruft die Routine AnlagenAuflisten auf, welche die Anlagen ausliest und das Listenfeld mit deren Dateinamen füllt. Zeigt das Formular einen neuen Datensatz an, wird lediglich das Listenfeld geleert. In beiden Fällen ruft die Prozedur die gleich vorgestellte Routine SchaltflaechenAktualisieren auf.

Listing 3: Füllen des Listenfeldes mit den Anlagen

Public Sub AnlagenAuflisten()
    Dim db As DAO.Database
    Dim rstAttachments As Recordset2
    Dim rstAttachmentsSortiert As Recordset2
    Set rstAttachments = m_Attachmentfield.Value
    rstAttachments.Sort = "Filename ASC"
    Set rstAttachmentsSortiert = rstAttachments.OpenRecordset
    Me!lstAnlagen.RowSource = ""
    Do While Not rstAttachments.EOF
         Me!lstAnlagen.AddItem rstAttachments!FileName
        rstAttachments.MoveNext
    Loop
End Sub

Liste mit Anlagen füllen

Die Prozedur AnlagenAuflisten füllt das Listenfeld des Formulars, das wir lstAnlagen nennen, mit den Dateinamen der im übergebenen Feld enthaltenen Dateien. Damit wir die AddItem und die RemoveItem-Methoden des Listenfeldes verwenden können, stellen wir die Eigenschaft Herkunftsart dieses Steuerelements auf Wertliste ein. Die Prozedur füllt dann das Listenfeld mit den Namen der im Anlagenfeld gespeicherten Dateien – und zwar in alphabetischer Reihenfolge (s. Listing 3). Das zukünftige Unterformular gestalten wir noch ein wenig übersichtlicher, indem wir die Eigenschaften Navigationsschaltfläche, Datensatzmarkierer und Bildlaufleisten jeweils auf den Wert Nein einstellen.

Listing 5: Auslösen des Hinzufügens einer Anlage aus einer Datei

Private Sub cmdHinzufuegen_Click()
    Dim objFiles As clsFiles
    Dim strDateien As String
    Dim strDateienArray() As String
    Dim i As Integer
    Set objFiles = New clsFiles
    With objFiles
        .Filter = "Alle Dateien (*.*)"
        .StartDir = CurrentProject.Path
        .Title = "Datei(en) auswählen"
        .MultipleFiles = True
        strDateien = .OpenFileName
    End With
    strDateienArray() = Split(strDateien, vbTab)
    For i = LBound(strDateienArray) To UBound(strDateienArray)
        AnlageHinzufuegen strDateienArray(i)
    Next i
    AnlagenAuflisten
End Sub

Steuerelemente aktivieren und deaktivieren

Bevor wir die Steuerelemente selbst mit Leben füllen, sollen diese zunächst, je nach den angezeigten Daten, aktiviert oder deaktiviert werden. Die Hinzufügen-Schaltfläche etwa ist immer aktiviert. Die Schaltfläche Entfernen hingegen soll nur benutzbar sein, wenn die Liste Dateien anzeigt und mindestens eine davon markiert ist. Das gleiche gilt für die Schaltflächen Öffnen und Speichern unter…. Die Schaltfläche Alle speichern wiederum darf ebenfalls immer aktiviert sein – außer wenn die Liste keinerlei Anlagen anzeigt.

Die Prüfung des Zustands des Listenfeldes und die davon abhängige Aktivierung/Deaktivierung der Schaltflächen nimmt die folgende Prozedur vor, die Sie ebenfalls im Klassenmodul des Formulars anlegen (s. Listing 4).

Listing 4: Aktiviere und Deaktivieren der Schaltflächen

Private Sub SchaltflaechenAktivieren()
    Dim bolDateiAusgewaehlt As Boolean
    bolDateiAusgewaehlt = Not Me!lstAnlagen.ItemsSelected.Count = 0
    Me!cmdEntfernen.Enabled = bolDateiAusgewaehlt
    Me!cmdOeffnen.Enabled = bolDateiAusgewaehlt
    Me!cmdSpeichernUnter.Enabled = bolDateiAusgewaehlt
    Me!cmdAllesSpeichern.Enabled = Not (Me!lstAnlagen.ListCount = 0)
End Sub

Sie haben das Ende des frei verfügbaren Textes erreicht. Möchten Sie ...

TestzugangOder bist Du bereits Abonnent? Dann logge Dich gleich hier ein. Die Zugangsdaten findest Du entweder in der aktuellen Print-Ausgabe auf Seite U2 oder beim Online-Abo in der E-Mail, die Du als Abonnent regelmäßig erhältst:

Schreibe einen Kommentar