Warum noch ein Access-Buch?
Für wen ist das Buch?
Jetzt bestellen
+ direkter Download des eBooks!
Nur EUR 59,95!
Fehler gefunden?
Bitte melden!
Wünsche an das Buch?
Her damit!
Was denken die Leser über dieses Buch?
Lesen Sie aktuelle Rezensionen!
Kapitel des noch nicht veröffentlichten Buchs zum Downloaden, Probelesen und Kommentieren
Beispieldatenbanken
Zusätzliches Material

Das Buch im HTML-Format

Für unbestimmte Zeit bieten Addison-Wesley und André Minhorst den kompletten Inhalt des Buchs als Download an. Schauen Sie rein und informieren Sie sich über den Inhalt! Und wenn Ihnen das Buch nützlich erscheint und Sie glauben, dass Sie etwas gelernt haben oder durch das Gelesene sogar etwas Zeit und somit Geld bei Ihrer Arbeit einsparen konnten, können Sie sich ja beim Autor und beim Verlag revanchieren - beispielsweise durch den Kauf dieses Buchs.

Am schönsten wäre es natürlich, wenn Sie das Buch direkt hier bestellen - Sie erhalten das Buch dann direkt vom Verlag, und der Autor und Verlag haben dann noch mehr davon, als wenn Sie es anderswo kaufen.

Danke für Ihr Interesse!

5.11.7 Icons im ListView-Steuerelement

5.11.8 Drag and Drop mit dem ListView-Steuerelement

Im Gegensatz zu Listenfeldern können Sie im ListView-Steuerelement auch Drag and Drop einsetzen. Wie das funktioniert, erfahren Sie im folgenden Beispiel: Dabei sollen Daten aus zwei ListView-Steuerelementen hin- und hergeschoben werden - natürlich per Drag and Drop und nicht, wie sonst bei Listenfeldern üblich, per Doppelklick oder mit passenden Schaltflächen. Die Daten kommen dabei aus einer m:n-Beziehung zwischen zwei Tabellen mit Publikationen und Empfängern. Zusätzlich zu den dazu notwendigen Tabellen tblPublikationen und tblEmpfaenger brauchen Sie eine Tabelle zum Verknüpfen der Datensätze der beiden Tabellen namens tblVerteiler. Im Beziehungsfenster sieht das wie in Abbildung 5.43 aus.

Abbildung 5.43: Datenmodell des Verteiler-Beispiels

Das Formular soll in zwei ListView-Steuerelementen die Empfänger und die Nicht-Empfänger der Publikation anzeigen (siehe Abbildung 5.44). Als Datensatzquelle des Formulars dient die Tabelle tblPublikationen. Das Formular zeigt beide Felder der Tabelle im Detailbereich an.

Außerdem fügen Sie zwei ListView-Steuerelemente namens lvwEmpfaenger und lvwKeinEmpfaenger hinzu. Stellen Sie für beide die Eigenschaft View auf 3 - lvwReport ein. Fügen Sie außerdem auf der Registerseite Spaltenköpfe des Eigenschaftsfensters der ListView-Steuerelemente jeweils eine Spalte mit den Bezeichnungen Empfänger und Kein Empfänger hinzu. Für das Füllen beider ListView-Steuerelemente ist die folgende Routine verantwortlich, die jeweils mit einem Objektverweis auf das entsprechende ListView-Steuerelement und einer passenden Datenherkunft aufgerufen wird.

Abbildung 5.44: So soll das Formular zum Hin- und Herschieben von Empfängern aussehen

Private Sub ListeAktualisieren(objListView As ListView, strSQL As String)
    Dim db As DAO.Database
    Dim rst As DAO.Recordset
    Set db = CurrentDb
    Set rst = db.OpenRecordset(strSQL, dbOpenDynaset)
    objListView. ListItems. Clear
    Do While Not rst.EOF
        objListView.ListItems. Add , "a" & rst(0), rst(1)
        rst.MoveNext
    Loop
    rst.Close
    Set rst = Nothing
    Set db = Nothing
End Sub

Listing 5.35: Diese Routine füllt eine Liste mit den Daten einer Tabelle

Den Aufruf dieser Routine übernimmt die Prozedur, die durch das Anzeigen eines Datensatzes im Formular ausgelöst wird - so ist gewährleistet, dass die beiden ListView-Steuerelemente immer die Daten zur aktuellen Publikation anzeigen. Die Beim Anzeigen-Ereignisprozedur sieht wie folgt aus:

Private Sub Form_Current()
    Dim strSQLEmpfaenger As String
    Dim strSQLKeinEmpfaenger As String
    If Not IsNull(Me.Publikation) Then
        strSQLEmpfaenger = "SELECT tblEmpfaenger.EmpfaengerID, " _
            & "tblEmpfaenger.Empfaenger FROM tblEmpfaenger INNER JOIN " _
            & "tblVerteiler ON tblEmpfaenger.EmpfaengerID = " _
            & "tblVerteiler.EmpfaengerID WHERE " _
            & "tblVerteiler.PublikationID = " _
            & Me.PublikationID & " ORDER BY tblEmpfaenger.Empfaenger"

        strSQLKeinEmpfaenger = "SELECT tblEmpfaenger.EmpfaengerID, " _
            & "tblEmpfaenger.Empfaenger FROM tblEmpfaenger WHERE " _
            & "tblEmpfaenger.EmpfaengerID NOT IN " _
            & "(SELECT tblEmpfaenger.EmpfaengerID FROM tblEmpfaenger " _
            & "INNER JOIN tblVerteiler ON tblEmpfaenger.EmpfaengerID " _
            & "= tblVerteiler.EmpfaengerID WHERE " _
            & " tblVerteiler.PublikationID = " & Me.PublikationID _
            & ") ORDER BY tblEmpfaenger.Empfaenger"
        ListeAktualisieren Me.lvwZugeordnet.Object, strSQLEmpfaenger
        ListeAktualisieren Me.lvwNichtZugeordnet.Object, _
            strSQLKeinEmpfaenger
    End If
End Sub

Listing 5.36: Aufruf der Routine zum Füllen der beiden ListView-Steuerelemente

Die Routine stellt für jedes ListView-Steuerelement eine SQL-Anweisung zusammen, die aus den verknüpften Tabellen jeweils die Empfänger auswählt, die einer Publikation zugeordnet sind, und jene, die nicht mit der aktuellen Publikation verknüpft sind. Dann ruft sie die Prozedur aus Listing 5.35 auf und übergibt einen Objektverweis auf das jeweilige ListView-Steuerelement und die passende SQL-Anweisung.

Die zweite SQL-Anweisung verwendet dabei fast die gleiche Anweisung wie die erste, allerdings nur als Unterabfrage. Damit ermittelt diese Abfrage alle Empfänger-Datensätze, die nicht durch die erste SQL-Anweisung erfasst werden und dementsprechend nicht über die Tabelle tblVerteiler mit der aktuell angezeigten Publikation verknüpft sind.

Daten verschieben

Um die Empfänger komfortabel verschieben zu können, stellen Sie noch die Eigenschaft Multiselect auf True ein - so lassen sich auch mehrere Empfänger gleichzeitig verschieben. Außerdem setzen Sie für beide ListView-Steuerelemente die Eigenschaft OLEDragMode auf den Wert 1 - ccOLEDragAutomatic und OLEDropMode auf 1 - ccOLEDropManual.

Beim Drag and Drop mit ungebundenen Steuerelementen, wie es die ListViews nun einmal sind, ist wie auch beim TreeView-Steuerelement vor allem eines zu beachten: Neben dem Verschieben des Eintrags zwischen den Listen müssen auch die dahinter liegenden Datenbanktabellen aktualisiert werden.

Für das Ziehen eines Eintrags von einem zum anderen ListView benötigen Sie nur zwei Ereignisprozeduren - vorausgesetzt, Sie verzichten auf jeglichen Schnickschnack:

  • OLEStartDrag beim Ausgangs-ListView-Steuerelement
  • OLEDragDrop beim Ziel-ListView-Steuerelement
  • Die OLEStartDrag-Prozedur durchläuft in einer Schleife alle Elemente des ListView-Steuerelements und prüft, welche Elemente markiert sind. Alle markierten Elemente werden an eine String-Variable angehängt - und zwar in der Form: ¦;

    Wozu das alles? Ganz einfach: Die Parameterliste der Ereignisprozedur enthält ein Objekt namens Data, das zunächst mit der Clear-Methode geleert und dann über die SetData-Methode mit der soeben zusammengestellten Liste gefüllt wird. Dieses Objekt (OLE-DataObject) ist eine Art Zwischenablage für Drag-and-Drop-Operationen und wird im Ziel-Steuerelement ausgelesen.

    Private Sub lvwNichtZugeordnet_OLEStartDrag(Data As Object, _
        AllowedEffects As Long)
        Dim objListItem As ListItem
        Dim strData As String
        Dim strDataItems() As String
        For Each objListItem In lvwKeinEmpfaenger.ListItems
            If objListItem.Selected = True Then
                strData = strData & objListItem.Key & "¦" _
                    & objListItem.Text & ";"
            End If
        Next
        Data.Clear
        Data.SetData strData, ccCFText
    End Sub

    Listing 5.37: Der Drag-and-Drop-Vorgang startet im ListView lvwKeinEmpfaenger ...

    Dies geschieht dann in der OLEDragDrop-Ereignisprozedur des Ziel-ListView-Steuerelements: Hier taucht das Objekt Data erneut in der Parameterliste auf. Die GetData-Methode gibt den Inhalt dieses Objekts preis. In der String-Variablen strData angekommen, werden die Daten direkt weiterverarbeitet: Nach der Prüfung, ob mindestens ein »Pipe«-Zeichen (¦) in der übergebenen Zeichenkette enthalten ist, teilen die folgenden Anweisungen die Zeichenkette zunächst in die durch Semikola (;) getrennten Bestandteile auf und speichern sie in einem String-Array. Dieses wird in einer For Next-Schleife über alle Elemente durchlaufen, wobei die Split-Anweisung die Elemente vor und hinter dem »Pipe«-Zeichen in die Variablen strKey und strText extrahiert. Und damit lässt sich natürlich leicht ein neues Element zum ListView-Steuerelement hinzufügen. Gleiches gilt auch andersherum: Nachdem die Add-Methode der ListItems-Auflistung des Ziel-ListView-Steuerelements das neue Element hinzugefügt hat, entfernt die Remove-Methode selbiges aus dem Ausgangs-ListView-Steuerelement:

    Private Sub lvwEmpfaenger_OLEDragDrop(Data As Object, Effect As Long, _
        Button As Integer, Shift As Integer, x As Single, y As Single)
        Dim strData As String
        Dim strDataItems() As String
        Dim strText As String

        Dim strKey As String
        Dim i As Integer
        strData = Data.GetData(ccCFText)
        If InStr(1, strData, "¦") <> 0 Then
            If Right(strData, 1) = ";" Then
                strData = Left(strData, Len(strData) - 1)
            End If
            strDataItems = Split(strData, ";")
            For i = 0 To UBound(strDataItems)
                strKey = Split(strDataItems(i), "¦")(0)
                strText = Split(strDataItems(i), "¦")(1)
                If IsNull(DLookup("EmpfaengerID", "tblVerteiler", _
                    "PublikationID = " & Me.PublikationID _
                    & " AND EmpfaengerID = " & Mid(strKey, 2))) Then
                    lvwEmpfaenger.ListItems.Add , strKey, strText
                    lvwKeinEmpfaenger.ListItems.Remove strKey
                    CurrentDb.Execute "INSERT INTO tblVerteiler" _
                        & "(PublikationID, EmpfaengerID) " & "VALUES(" _
                        & Me.PublikationID & ", " & Mid(strKey, 2) & ")"
                End If
            Next i
        End If
    End Sub

    Listing 5.38: ... und endet im ListView lvwZugeordnet

    Mit diesen beiden Routinen können Sie nun schon Elemente von rechts nach links, aber noch nicht von links nach rechts ziehen. Das lässt sich aber leicht nachholen: Legen Sie einfach die passenden Ereignisprozeduren analog für das jeweils andere ListView-Steuerelement an - die kleinen Änderungen können Sie in der Beispieldatenbank einsehen.

    Beim Probieren fällt allerdings eines auf: Nach ein paar Drag-and-Drop-Operationen und einem Wechsel zu einem anderen Publikations-Datensatz im Formular und wieder zurück enthält jedes ListView-Steuerelement wieder die ursprünglichen Elemente. Das liegt daran, dass die Datenbankseite bisher außen vor gelassen wurde: Sie können zwar lustig Elemente zwischen den ListView-Steuerelementen hin- und herschieben, aber die entsprechenden Änderungen an der Verknüpfungstabelle tblVerteiler erfolgen nicht.

    Der Aufwand hierfür ist allerdings vergleichsweise gering: Für das Hinzufügen eines Kontakts zur Liste der Empfänger müssen Sie schließlich nur einen Datensatz mit der PublikationID und der EmpfaengerID zur Tabelle tblVerteiler hinzufügen; zum Entfernen des Empfängers aus der Liste löschen Sie einfach den passenden Eintrag aus der Tabelle tblVerteiler.

    Ein Platz für die SQL-Anweisungen ist auch schnell gefunden: Da die Änderungen jeweils für alle markierten Elemente vorzunehmen sind, gehört die entsprechende Anweisung selbstverständlich in eine der For Next-Schleifen, die alle zu bewegenden Elemente durchläuft. Soll ein Eintrag aus dem Verteiler entfernt werden, fügen Sie diese Anweisung in die Routine lvwNichtZugeordnet_OLEDragDrop ein (in einer Zeile):

    CurrentDb.Execute "DELETE FROM tblVerteiler WHERE PublikationID = " & Me.PublikationID & " AND EmpfaengerID = " & Mid(strKey, 2)

    Die entsprechende Anweisung in der Routine lvwZugeordnet_OLEDragDrop sieht so aus:

    CurrentDb.Execute "INSERT INTO tblVerteiler(PublikationID, Empfaenge-rID) VALUES(" & Me.PublikationID & ", " & Mid(strKey, 2) & ")"

    Nächster Abschnitt:

    5.11.9 Reihenfolge per Drag and Drop einstellen

    © 2006-2008 André Minhorst Alle Rechte vorbehalten.