Dateiverknüpfung per Drag and Drop hinzufügen

Es gibt verschiedene Möglichkeiten, Dateien mit Access zu verwalten. Je nach Speicherplatz speichert man diese in einem Anlage-Feld oder in einem externen Ordner und verweist dann über die Angabe des Pfades auf diese Datei. Es gibt zwar auch noch OLE-Felder, aber Anlagefelder sind intuitiver zu nutzen, da man diesen auch ohne Code Dateien hinzufügen kann. Aufgrund der begrenzten Größe von Access-Dateien mit zwei Gigabyte ist es oft sinnvoller, nur die Dateipfade zu speichern. Spannend wird es beim Hinzufügen der Dateien selbst: Dies geschieht in der Regel durch Öffnen eines Dateiauswahl-Dialogs. In vielen Fällen ist das Verzeichnis mit den Dateien aber bereits im Windows Explorer geöffnet und man könnte diese schneller per Drag and Drop hinzufügen. Wie das gelingt, zeigen wir im vorliegenden Beitrag.

Drag and Drop ins Anlagefeld

Grundsätzlich wäre es praktisch, wenn man Dateien direkt in ein Textfeld ziehen könnte und der Pfad zu dieser Datei dann in das Textfeld eingetragen wird. Das gelingt allerdings nicht mit Bordmitteln, denn die eingebauten Steuer-elemente erlauben kein Drag and Drop. Ein Mangel, mit dem viele Access-Entwickler hadern.

Die einzigen Steuer-elemente, welche die Behandlung von Drag and Drop-Ereignissen erlauben, sind in der Bibliothek MSCOMCTL.ocx enthalten. Dabei handelt es sich um Steuer-elemente wie das ListView-, das TreeView– oder das ImageCombo-Steuerelement.

Das erfahren Sie, wenn Sie eines dieser Steuer-elemente zu einem Formular einer Datenbankdatei hinzufügen und dann im VBA-Editor den Objektkatalog öffnen, wo Sie wie in Bild 1 nach dem Suchbegriff Drop suchen.

Steuer-elemente mit Drag and Drop-Ereignissen

Bild 1: Steuer-elemente mit Drag and Drop-Ereignissen

Wir können also nicht direkt per Drag and Drop Dateien direkt in ein Textfeld ziehen. Das ließe sich mit API-Programmierung erreichen, wovon wir aber in diesem Beitrag absehen. Stattdessen werden wir dazu ein ListView-Steuerelement verwenden, das wir an geeigneter Stelle in dem Formular unterbringen, welches wir mit der Drag and Drop-Funktion ausstatten wollen.

Wenn der Benutzer dann eine Datei auf dieses Steuer-element zieht, soll ein entsprechendes Ereignis ausgelöst werden, das den Dateipfad erkennt und diesen in das gewünschte Feld einträgt.

Alternative: Datei zusätzlich in bestimmtes Verzeichnis kopieren

Gegebenenfalls sollen die Dateien, deren Pfad in der Tabelle gespeichert werden sollen, zuvor in ein spezielles Verzeichnis kopiert oder verschoben werden. Das kann beispielsweise ein Verzeichnis sein, dass sich im gleichen Ordner wie die Datenbankdatei befindet. Diese Funktion wollen wir alternativ vorsehen.

Tabelle zum Speichern der Dateipfade

Die Tabelle, in der wir die Pfade zu den per Drag and Drop einzufügenden Dateien speichern, sieht in der Entwurfsansicht wie in Bild 2 aus. Neben dem Primärschlüsselfeld namens ID soll die Tabelle nur noch das Feld Dateipfad enthalten.

Tabelle zum Speichern der Dateipfade

Bild 2: Tabelle zum Speichern der Dateipfade

Formular mit der Drag and Drop-Funktion

Das Formular, dem wir die Drag and Drop-Funktion hinzufügen wollen, verwendet die Tabelle tblDateipfade als Datensatzquelle. Wir ziehen beide Felder dieser Tabelle in den Formularentwurf. Außerdem fügen wir über den Dialog ActiveX-Steuerelemente einfügen ein Steuer-element des Typs Microsoft ListView Control, version 6.0 zum Formular hinzu. Dieses sieht anschließend wie in Bild 3 aus.

Formular zum Hinzufügen von Dateipfaden

Bild 3: Formular zum Hinzufügen von Dateipfaden

Darstellung des Drag and Drop-Ziels

Einfach nur ein ListView-Steuerelement als Drag and Drop-Ziel zu verwenden, ist die einfachste Lösung. Aber ergonomischer wäre es, wenn das ListView-Element sich direkt als Drag and Drop-Ziel zeigt – beispielsweise, indem wir einen passenden Text oder ein Icon darin abbilden.

Das soll später so aussehen wie in Bild 4. Im Ruhezustand soll das Ziel den Text Ziehen Sie die Datei in diesen Bereich anzeigen, beim Ziehen einer Datei auf das Ziel den Text Lassen Sie die Maustaste los, um die Datei hinzuzufügen.

Ändern des Drag and Drop-Ziels beim Ziehen mit der Maus

Bild 4: Ändern des Drag and Drop-Ziels beim Ziehen mit der Maus

ImageList vorbereiten

Damit das geschieht, benötigen wir zunächst einmal zwei verschiedene Bilder, die wir je nach Zustand im ListView anzeigen. Außerdem müssen wir die Größe der Bilddatei festlegen. Das ist der erste Schritt:

Fügen Sie über den Dialog ActiveX-Steuerelemente einfügen ein Element des Typs Microsoft ImageList, version 6.0 hinzu, das Sie gleich in ctlImageList umbenennen. Das Steuer-element erscheint dann wie in Bild 5 links oben im Formular. Wenn Sie in die Formularansicht wechseln, wird das Steuer-element jedoch nicht sichtbar sein.

Das neu hinzugefügte ImageList-Steuerelement

Bild 5: Das neu hinzugefügte ImageList-Steuerelement

Nach einem Doppelklick auf das Steuer-element in der Entwurfsansicht erscheint das Eigenschaftsfenster aus Bild 6. Hier stellen Sie für die Option Custom die Größe der zu verwendenden Bilddatei ein, hier 71 x 311.

Einstellen der Größe der Icons im ImageList-Steuerelement

Bild 6: Einstellen der Größe der Icons im ImageList-Steuerelement

Auf der zweiten Registerseite fügen Sie mit der Schaltfläche Insert Picture… die beiden Bilder hinzu, die im Ruhezustand und beim Ziehen eines Elements über dem ListView-Steuerelement angezeigt werden sollen. Die Index-Werte für die beiden Bilder lauten 1 und 2. Key und Tag können Sie ausfüllen, aber die Eigenschaften werden nicht benötigt (siehe Bild 7).

Einfügen des ersten Bildes in das ImageList-Steuerelement

Bild 7: Einfügen des ersten Bildes in das ImageList-Steuerelement

ListView programmieren

Nun müssen wir das ListView-Steuerelement erst einmal so programmieren, dass es das erste Bild aus dem ImageList-Steuerelement anzeigt. Dazu deklarieren wir im Klassenmodul des Formulars zunächst einmal zwei Variablen. Die erste nimmt einen Verweis auf das Steuer-element lvwDragAndDrop auf und erhält zusätzlich das Schlüsselwort WithEvents, damit wir im gleichen Klassenmodul Ereignisse für dieses Steuer-element deklarieren können:

Dim WithEvents objDragAndDrop As MSComctlLib.ListView

Die zweite soll einen Verweis auf das erste im ListView-Steuerelement enthaltene Element enthalten:

Dim objListItem As MSComctlLib.ListItem

Den Hauptteil der Arbeit erledigen wir in der Prozedur Form_Load, die durch das Ereignis Beim Laden des Formulars ausgelöst wird. Dieses deklariert eine weitere Variable namens objImageList, mit der wir auf das ImageList-Steuerelement ctlImageList verweisen wollen:

Private Sub Form_Load()
     Dim objImageList As MSComctlLib.ImageList

Dann ordnen wir der modulweit deklarierten Variable objDragAndDrop einen Verweis auf die Eigenschaft Object des Steuerelements lvwDragAndDrop zu und schließlich der soeben deklarierten Variable objImageList einen Verweis auf die Eigenschaft object des ImageList-Steuerelements.

     Set objDragAndDrop = Me!lvwDragAndDrop.Object
     Set objImageList = Me!ctlImageList.Object

Für das mit objDragAndDrop referenzierte ListView-Steuerelement stellen wir nun einige Eigenschaften ein. Die Eigenschaft SmallIcons füllen wir mit einem Verweis auf das ImageList-Steuerelement:

     With objDragAndDrop
         Set .SmallIcons = objImageList

Für das Erscheinungsbild stellen wir unter Appearance ccFlat ein (im Gegensatz zu cc3d). BorderStyle erhält den Wert ccNone. Damit stellen wir sicher, dass man das ListView-Steuerelement nicht an der Darstellung oder am Rahmen als solches erkennen kann. Für die Eigenschaft View stellen wir lvwList ein, da so das Bild angezeigt wird, das wir gleich zuweisen:

         .Appearance = ccFlat
         .BorderStyle = ccNone
         .View = lvwList

Mit dem Wert ccOLEDragAutomatic für die Eigenschaft OLEDragMode und dem Wert ccOLEDropManual für die Eigenschaft OLEDropMode legen wir fest, dass wir mit Ereignisprozeduren auf Drag and Drop-Ereignisse reagieren können:

         .OLEDragMode = ccOLEDragAutomatic
         .OLEDropMode = ccOLEDropManual

Danach leeren wir die Auflistung ListItems des ListView-Steuerelements mit der Clear-Methode, damit eventuell bereits vorhandene Elemente gelöscht werden:

         objDragAndDrop.ListItems.Clear

Schließlich fügen wir ein neues Listenelement hinzu und nutzen dazu die Add-Methode von ListItems:

         Set objListItem =  objDragAndDrop.ListItems.Add(, "a", , , 1)
     End With
End Sub

Das damit neu angelegte Element mit dem Schlüssel a und dem Wert 1 für den Parameter SmallIcon zeigt dann das mit dem Index 1 versehene Bild aus dem ImageList-Steuerelement an.

Wechseln des Bildes beim Ziehen auf das ListView

Damit beim Ziehen eines Elements auf das ListView-Steuerelement das zweite im ImageList-Steuerelement gespeicherte Bild angezeigt wird, stellen wir einfach die Eigenschaft SmallIcon auf den Wert 2 an. Das erledigen wir in der Prozedur, die durch das Ereignis OLEDragOver ausgelöst wird und die dann wie folgt aussieht:

Private Sub objDragAndDrop_OLEDragOver(Data As  MSComctlLib.DataObject, Effect As Long, Button As  Integer, Shift As Integer, X As Single, Y As Single,  State As Integer)
     objListItem.SmallIcon = 2
End Sub

Das Ereignis feuert, wenn der Benutzer irgendein Objekt über das ListView-Steuerelement zieht, und blendet das zweite Bild mit dem Text Lassen Sie die Maustaste los, um die Datei hinzuzufügen ein.

Sollte es sich der Benutzer anders überlegen und die Datei nicht über dem Listenfeld fallen lassen, sondern irgendwo anders, dann sorgt diese Ereignisprozedur dafür, dass wieder das Bild mit dem Text Ziehen Sie Dateien in diesen Bereich erscheint:

Private Sub Detailbereich_MouseMove(Button As Integer,  Shift As Integer, X As Single, Y As Single)
     objListItem.SmallIcon = 1
End Sub

Das reicht allerdings nicht aus, wenn der Benutzer einmal mit der Datei über das ListView-Steuerelement gefahren ist und die Maustaste dann über irgendeinem anderen Bereich als dem Formular loslässt. Dann bleibt das Bild mit der zweiten Meldung angezeigt.

Für diesen Fall gibt es keine einfache Lösung, die sich direkt durch ein Ereignis realisieren lässt. Eine Möglichkeit wäre es, ein Zeitgeber-Ereignis zu implementieren, wobei der Zeitgeber beim ersten Überfahren des ListView-Steuerelements mit einer Datei gestartet wird. Das Ereignis soll dann bei jeder Ausführung prüfen, ob der Benutzer die Maustaste bereits losgelassen hat, ohne das Element auf das ListView-Steuerelement fallenzulassen.

Ende des frei verfügbaren Teil. Wenn Du mehr lesen möchtest, hole Dir ...

den kompletten Artikel im PDF-Format mit Beispieldatenbank

diesen und alle anderen Artikel mit dem Jahresabo

Schreibe einen Kommentar