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.10.13 Drag and Drop im TreeView-Steuerelement

5.10.14 VBA-Ereignisprozeduren für Drag and Drop einrichten

Außerdem sind einige Ereignisprozeduren mit Leben zu füllen. Diese lassen sich nicht wie bei den üblichen Access-Steuerelementen über das Eigenschaftsfenster anlegen, sondern müssen direkt im VBA-Editor erstellt werden.

Nachdem Sie ein passendes TreeView-Steuerelement im Formular angelegt haben, können Sie die beiden Kombinationsfelder im VBA-Editor zum Anlegen von Ereigniseigenschaften für das TreeView-Steuerelement verwenden. Wählen Sie dazu im linken Kombinationsfeld den Namen des Steuerelements aus. Dies führt zum automatischen Anlegen des Prozedurrumpfs, der durch das Updated-Ereignis ausgelöst wird. Weitere Ereignisprozeduren legen Sie durch Auswahl des gewünschten Ereignisses aus dem rechten Kombinationsfelds an (siehe Abbildung 5.32).

Abbildung 5.32: Anlegen von Ereignisprozeduren im VBA-Codefenster

Auf diese Weise sind die nachfolgend benötigten drei Prozeduren schnell erstellt. Das Ereignis OLEStartDrag wird ausgelöst, wenn Sie den Mauszeiger auf einem Eintrag positionieren, die linke Maustaste gedrückt halten und den Mauszeiger dabei bewegen.

Das Ereignis OLEDragOver wird nach dem Ereignis OLEStartDrag in kurzen Abständen ausgelöst - es könnte eigentlich OLEDragMouseMove heißen -, bis Sie die Maustaste loslassen. Dies wiederum ruft das Ereignis OLEDragDrop auf den Plan. Damit hätten Sie das Werkzeug beisammen - mit Ausnahme einiger nützlicher Eigenschaften des TreeView-Steuerelements:

  • HitTest(x,y): Liefert einen Verweis auf den Knoten mit den Koordinaten x und y.
  • SelectedItem: Legt den markierten Knoten fest oder liest diesen aus.
  • DropHighlight: Markiert den Knoten, über dem sich der Mauszeiger bei einer Drag-and-Drop-Operation befindet, sofern dies nicht der Ausgangsknoten ist.
  • Aber der Beginn der Drag-and-Drop-Operation hat es in sich: Die Operation bezieht sich nämlich auf das aktuell markierte Element. Wenn Sie ein Element mit der Maus markieren, passiert dies jedoch erst beim Loslassen der Maustaste. Beim Ziehen lassen Sie die Taste aber erst zum Ablegen wieder los. Wenn nun wie in Abbildung 5.33 vor Beginn des Ziehens ein anderes Element markiert ist, denkt Access, Sie wollten dieses aktuell markierte Element ziehen, aber nicht das, auf das Sie mit der Maus geklickt haben (das gestrichelte Element ist das aktuell markierte, das blau hinterlegte das zu ziehende Element). Sobald Access den Start einer Drag-and-Drop-Operation erkennt, soll also das aktuelle Element demarkiert und das tatsächlich zu ziehende Element markiert werden. Den ersten Schritt erledigt der Einzeiler aus folgender Routine:

    Private Sub tvwTreeView_OLEStartDrag(Data As Object, _
        AllowedEffects As Long)
        objTreeView. SelectedItem = Nothing
    End Sub

    Listing 5.18: Aufheben der aktuellen Markierung

    Abbildung 5.33: Zu Beginn einer Drag-and-Drop-Operation ist noch ein anderes als das zu bewegende Element markiert

    Die Markierung des zu ziehenden Elements erfolgt im OLEDragOver-Ereignis, das immer wieder während des Drag-and-Drop-Vorgangs ausgelöst wird. Das Markieren soll aber nur einmal zu Beginn erfolgen, weshalb die folgende Routine abfragt, ob ein Element markiert ist, und gegebenenfalls dasjenige markiert, über dem sich aktuell der Mauszeiger befindet.

    Private Sub tvwTreeView_OLEDragOver(Data As _
        Object, Effect As Long, Button As _
        Integer, Shift As Integer, x As Single, _
        y As Single, State As Integer)
        If objTreeView.SelectedItem Is Nothing Then
            Set objTreeView.SelectedItem = objTreeView. HitTest(x, y)
        End If
        Set objTreeView. DropHighlight = objTreeView.HitTest(x, y)
    End Sub

    Listing 5.19: Diese Routine wird immer wieder während des Drag-and-Drop-Vorgangs ausgeführt

    Bei jedem Aufruf der OLEDragOver-Prozedur passiert allerdings Folgendes: Die Routine markiert das Element, über dem sich der Mauszeiger aktuell befindet, mit der Eigenschaft DropHighlight und kennzeichnet es so als potenzielles Ziel der Drag-and-Drop-Operation.

    Das große Finish folgt dann in der Ereignisprozedur OLEDragDrop. Diese wird beim Loslassen der Maustaste ausgelöst und sorgt dafür, dass das Element an die neue Stelle verschoben wird. Aber nicht nur das: Das Abbild der Daten im TreeView-Steuerelement und die in den Tabellen befindlichen Daten werden natürlich nicht automatisch synchronisiert. Also müssen Sie auch noch dafür sorgen, dass der entsprechende Datensatz der neuen Situation im TreeView-Steuerelement angepasst wird.

    Das hört sich zwar erst einmal recht kompliziert an, ist aber letzten Endes reine Fleißarbeit. Im vorliegenden Beispiel sieht die Routine wie im folgenden Listing aus.

    Private Sub tvwTreeView_OLEDragDrop(Data As Object, Effect As Long, _
        Button As Integer, _
        Shift As Integer, x As Single, y As Single)
        Dim db As DAO.Database
        Dim lngID As Long
        Dim lngParentID As Long
        Dim strKey As String
        Dim strText As String
        Set db = CurrentDb
        'zu verschiebenden Datensatz ermitteln
        lngID = Mid(objTreeView.SelectedItem.Key, 9)
        strKey = objTreeView.SelectedItem.Key
        strText = objTreeView.SelectedItem.Text
        'Wurde an eine freie Stelle oder auf einen anderen Knoten gezogen?
        If objTreeView.HitTest(x, y) Is Nothing Then
            'Knoten entfernen
            objTreeView.Nodes.Remove objTreeView.SelectedItem.Index
            'Knoten neu anlegen
            objTreeView.Nodes.Add , , strKey, strText
            'Änderung in die Datenbank übertragen
            db.Execute "UPDATE tblPersonal SET Vorgesetzter = NULL " _
                & "WHERE PersonalID = " & lngID
            'Untergeordnete Elemente des verschobenen Knotens wiederherstellen
            TreeViewRekursivFuellen lngID
        Else
            If objTreeView.SelectedItem <> objTreeView.DropHighlight Then
                'neuen übergeordneten Datensatz ermitteln
                lngParentID = Mid(objTreeView.DropHighlight.Key, 9)
                'Zielknoten als neuen übergeordneten Knoten festlegen
                Set objTreeView.SelectedItem.Parent = objTreeView.DropHighlight

                'Änderung in die Datenbank übertragen
                db.Execute "UPDATE tblPersonal SET Vorgesetzter = " _
                    & lngParentID & " WHERE PersonalID = " & lngID
            End If
            Set objTreeView.DropHighlight = Nothing
        End If
    End Sub

    Listing 5.20: Durchführen der Drag-and-Drop-Operation

    Es gibt beim Drag and Drop grundsätzlich zwei zu unterscheidende Fälle:

  • Der Knoten wird in den leeren Raum gezogen und soll so in die oberste Hierarchie-Ebene eingeordnet werden.
  • Der Knoten wird auf einen anderen Knoten gezogen und soll so diesem untergeordnet werden.
  • Nach dem Ermitteln einiger Informationen des Knotens, der verschoben werden soll (Primärschlüsselwert des entsprechenden Datensatzes, Key, angezeigter Text), zweigt eine If Then-Bedingung die Routine entsprechend den beiden oben genannten Fällen auf.

    Beim Ziehen in den leeren Raum wird zunächst der Knoten entfernt und neu angelegt. Leider nicht ohne Reibungsverluste, denn eventuell untergeordnete Knoten gehen so verloren. Um diese wiederherzustellen, wird die Änderung zunächst in der Tabelle tblPersonal durchgeführt: Der Wert des Feldes Vorgesetzter des verschobenen Datensatzes wird auf NULL gesetzt. Anschließend ruft die Routine die Prozedur TreeViewRekursivFuellen (siehe Listing 5.13) mit dem neuen Knoten als Parameter auf, um die untergeordneten Knoten wiederherzustellen.

    Zieht der Benutzer den Knoten auf einen anderen Knoten, ist etwas weniger zu tun: Nach einer Prüfung, ob der Knoten nicht auf sich selbst abgelegt werden soll, ermittelt die Routine zunächst den Primärschlüsselwert des neuen übergeordneten Knotens. Anschließend weist man der Parent-Eigenschaft des verschobenen Knotens den neuen übergeordneten Knoten zu. Damit werden auch automatisch alle untergeordneten Knoten mitgezogen. Fehlt noch die Übernahme der Änderung in die Datenbank mit der entsprechenden UPDATE-Abfrage - auch dies erledigt obige Routine.

    Nächster Abschnitt:

    5.11 ListView

    © 2006-2008 André Minhorst Alle Rechte vorbehalten.