{"id":55001576,"date":"2025-12-01T00:00:00","date_gmt":"2025-12-02T21:35:16","guid":{"rendered":"http:\/\/access-im-unternehmen.aix-dev.de\/aiu\/?p=1576"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-30T00:00:00","slug":"mnBeziehung_mit_Drag_and_Drop_per_ListView","status":"publish","type":"post","link":"https:\/\/access-im-unternehmen.de\/mnBeziehung_mit_Drag_and_Drop_per_ListView\/","title":{"rendered":"m:n-Beziehung mit Drag and Drop per ListView"},"content":{"rendered":"<p><b>Wir haben uns bereits in einigen Beitr&auml;gen angesehen, wie man die Daten einer m:n-Beziehung mit zwei nebeneinander liegenden Listenfeldern verwalten kann. Das Hinzuf&uuml;gen oder Entfernen erfolgte dabei per Doppelklick auf den jeweiligen Eintrag oder &uuml;ber entsprechende Schaltfl&auml;chen. Im Gegensatz zu Listenfeldern k&ouml;nnen wir im ListView-Steuerelement jedoch auch Drag and Drop einsetzen. Wie das grundlegend funktioniert, haben wir uns bereits im hinteren Teil des Beitrags &#8222;ListView-Steuerelement mit VBA programmieren&#8220; (www.access-im-unternehmen.de\/1573) angesehen. Im vorliegenden Beitrag schauen wir uns an, wie wir die Daten aus zwei ListView-Steuerelementen per Drag and Drop hin- und herschieben k&ouml;nnen. <\/b><\/p>\n<h2>Datenmodell des Beispiels<\/h2>\n<p>Als Beispiel wollen wir einen Verteiler f&uuml;r Newsletter verwenden. Wir ben&ouml;tigen also eine Tabelle mit den Empf&auml;ngern des Newsletters, eine Tabelle f&uuml;r die einzelnen Newsletter und eine weitere, um die Empf&auml;nger den verschiedenen Newslettern zuordnen zu k&ouml;nnen.<\/p>\n<p>Die erste Tabelle namens <b>tblEmpfaenger <\/b>enth&auml;lt die Felder <b>EmpfaengerID<\/b>, <b>Empfaenger <\/b>und <b>EMail <\/b>(siehe Bild 1). Hier speichern wir die Empf&auml;nger f&uuml;r die Newsletter.<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2025_06\/pic_1576_003.png\" alt=\"Die Tabelle tblEmpfaenger\" width=\"499,5589\" height=\"373,5276\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 1: Die Tabelle tblEmpfaenger<\/span><\/b><\/p>\n<p>Die Newsletter wiederum speichern wir in der Tabelle <b>tblNewsletter<\/b>, die wir in Bild 2 sehen. Hier haben wir nur die wichtigsten Felder eingef&uuml;gt, man k&ouml;nnte noch weitere Felder wie Versanddatum et cetera hinzuf&uuml;gen, wenn man die Anwendung in der Praxis nutzen m&ouml;chte.<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2025_06\/pic_1576_002.png\" alt=\"Die Tabelle tblNewsletter\" width=\"499,5589\" height=\"369,8745\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 2: Die Tabelle tblNewsletter<\/span><\/b><\/p>\n<p>Zus&auml;tzlich zu den dazu notwendigen Tabellen <b>tblNewsletter<\/b> und <b>tblEmpfaenger <\/b>brauchen wir eine Tabelle zum Verkn&uuml;pfen der Datens&auml;tze der beiden Tabellen namens <b>tblVerteiler<\/b> &uuml;ber eine m:n-Beziehung. Diese enth&auml;lt neben dem Prim&auml;rschl&uuml;sselfeld <b>VerteilerID<\/b> zwei weitere Felder, &uuml;ber die wir die Datens&auml;tze der Tabellen <b>tblEmpfaenger <\/b>und <b>tblNewsletter <\/b>miteinander verkn&uuml;pfen. Dies realisieren wir &uuml;ber die beiden Felder <b>EmpfaengerID <\/b>und <b>NewsletterID<\/b>. In diesem Fall wollen wir keine Nachschlagefelder einrichten, da wir diese im zu erstellenden Formular nicht ben&ouml;tigen.<\/p>\n<p>Damit jeder Empf&auml;nger nur einmal jedem Newsletter zugewiesen werden kann, haben wir au&szlig;erdem einen eindeutigen Schl&uuml;ssel &uuml;ber die beiden Felder <b>EmpfaengerID <\/b>und <b>NewsletterID <\/b>hinzugef&uuml;gt (siehe Bild 3).<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2025_06\/pic_1576_001.png\" alt=\"Die m:n-Verkn&uuml;pfungstabelle tblVerteiler\" width=\"649,559\" height=\"462,2809\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 3: Die m:n-Verkn&uuml;pfungstabelle tblVerteiler<\/span><\/b><\/p>\n<p>Stattdessen legen wir die Beziehungen direkt im Beziehungen-Fenster von Access an. Hier ziehen wir alle drei Tabellen der Anwendung hinein und verkn&uuml;pfen diese wie in Bild 4. F&uuml;r beide Beziehungen definieren wir referenzielle Integrit&auml;t mit L&ouml;schweitergabe. Damit erreichen wir, dass beim L&ouml;schen eines Empf&auml;ngers oder eines Newsletters auch die damit verkn&uuml;pften Eintr&auml;ge der Tabelle <b>tblVerteiler <\/b>gel&ouml;scht werden.<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2025_06\/pic_1576_004.png\" alt=\"Beziehungen zum Herstellen der m:n-Beziehung\" width=\"700\" height=\"258,125\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 4: Beziehungen zum Herstellen der m:n-Beziehung<\/span><\/b><\/p>\n<h2>Formular zum Zuordnen von Empf&auml;ngern zu den Newslettern<\/h2>\n<p>Das Formular soll in zwei <b>ListView<\/b>-Steuerelementen die Empf&auml;nger und die Nicht-Empf&auml;nger der Newsletter anzeigen. Als Datensatzquelle des Formulars dient die Tabelle <b>tblNewsletter<\/b>. Das Formular zeigt beide Felder der Tabelle untereinander im Detailbereich an (siehe Bild 5).<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2025_06\/pic_1576_005.png\" alt=\"Hinzuf&uuml;gen der Felder der Tabelle tblNewsletter\" width=\"649,559\" height=\"457,5067\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 5: Hinzuf&uuml;gen der Felder der Tabelle tblNewsletter<\/span><\/b><\/p>\n<p>Au&szlig;erdem f&uuml;gen wir zwei <b>ListView<\/b>-Steuerelemente namens <b>lvwEmpfaenger <\/b>und <b>lvwKeinEmpfaenger <\/b>hinzu.<\/p>\n<p>Dazu bet&auml;tigen wir den Befehl <b>Formularentwurf|Steuerelemente|ActiveX-Steuerelemente<\/b>. Dies &ouml;ffnet den Dialog <b>ActiveX-Steuerelemente <\/b>einf&uuml;gen, wo wie den Eintrag <b>Microsoft ListView Control <\/b>finden (siehe Bild 6).<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2025_06\/pic_1576_006.png\" alt=\"Ausw&auml;hlen des ListView-Steuerelements\" width=\"424,5589\" height=\"465,2869\"\/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 6: Ausw&auml;hlen des ListView-Steuerelements<\/span><\/b><\/p>\n<p>Die beiden <b>ListView<\/b>-Steuerelemente f&uuml;gen wir unterhalb der bereits vorhandenen Steuerelemente ein und passen ihre Bezeichnungen an (siehe Bild 7).<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2025_06\/pic_1576_007.png\" alt=\"Hinzuf&uuml;gen der ListView-Steuerelemente\" width=\"599,559\" height=\"444,3539\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 7: Hinzuf&uuml;gen der ListView-Steuerelemente<\/span><\/b><\/p>\n<h2>Einstellungen f&uuml;r die ListView-Steuerelemente<\/h2>\n<p>In der Ereignisprozedur, die durch das Ereignis <b>Beim Laden <\/b>ausgel&ouml;st wird, wollen wir die Einstellungen f&uuml;r die beiden <b>ListView<\/b>-Steuerelemente vornehmen.<\/p>\n<p>Den Gro&szlig;teil der Arbeit wollen wir jedoch in eine weitere Prozedur auslagern, weil die Befehle f&uuml;r beide <b>ListView<\/b>-Steuerelemente fast identisch sind. Zun&auml;chst jedoch deklarieren wir Objektvariablen f&uuml;r die beiden <b>ListView<\/b>-Steuerelemente im Kopf des Klassenmoduls des Formulars:<\/p>\n<pre><span style=\"color:blue;\">Dim <\/span>objEmpfaenger<span style=\"color:blue;\"> As <\/span>MSComctlLib.ListView\r\n<span style=\"color:blue;\">Dim <\/span>objKeinEmpfaenger<span style=\"color:blue;\"> As <\/span>MSComctlLib.ListView<\/pre>\n<p>Die <b>Form_Load<\/b>-Ereignisprozedur f&uuml;llt diese mit Verweisen auf die <b>Object<\/b>-Eigenschaften der entsprechenden Steuerelemente und ruft f&uuml;r jedes die Prozedur <b>ListViewEinstellen <\/b>auf.<\/p>\n<p>Dabei &uuml;bergibt sie den Verweis auf das jeweilige <b>ListView<\/b>-Steuerelement und den Text, der im Spaltenkopf erscheinen soll:<\/p>\n<pre><span style=\"color:blue;\">Private Sub <\/span>Form_Load()\r\n     <span style=\"color:blue;\">Set<\/span> objKeinEmpfaenger = Me.lvwKeinEmpfaenger.Object\r\n     <span style=\"color:blue;\">Set<\/span> objEmpfaenger = Me.lvwEmpfaenger.Object\r\n     <span style=\"color:blue;\">Call<\/span> ListViewEinstellen(objKeinEmpfaenger, _\r\n         \"Nicht in Empf&auml;ngerliste\")\r\n     <span style=\"color:blue;\">Call<\/span> ListViewEinstellen(objEmpfaenger, _\r\n         \"In Empf&auml;ngerliste\")\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p>Die Prozedur <b>ListViewEinstellen<\/b> nimmt diese Parameter entgegen und stellt einige Eigenschaften ein (siehe Listing 1).<\/p>\n<pre><span style=\"color:blue;\">Private Sub <\/span>ListViewEinstellen(objListView<span style=\"color:blue;\"> As <\/span>_\r\n         MSComctlLib.ListView, strHeader<span style=\"color:blue;\"> As String<\/span>)\r\n     <span style=\"color:blue;\">With<\/span> objListView\r\n         .View = lvwReport\r\n         .BorderStyle = ccNone\r\n         .Appearance = ccFlat\r\n         .FullRowSelect = <span style=\"color:blue;\">True<\/span>\r\n         .HideSelection = <span style=\"color:blue;\">False<\/span>\r\n         .MultiSelect = <span style=\"color:blue;\">True<\/span>\r\n         .Font.Name = \"Calibri\"\r\n         .Font.Size = 11\r\n         .OLEDragMode = ccOLEDragAutomatic\r\n         .OLEDropMode = ccOLEDropManual\r\n         .ColumnHeaders.Clear\r\n         .ColumnHeaders.Add , \"c1\", strHeader\r\n         .ColumnHeaders(1).Width = Me.lvwEmpfaenger.Width\r\n     End <span style=\"color:blue;\">With<\/span>\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p><b><span style=\"color:darkgrey;\">Listing 1: Einstellen der Eigenschaften f&uuml;r die ListView-Steuerelemente<\/span><\/b><\/p>\n<p>Dazu geh&ouml;ren die Ansicht als <b>lvwReport<\/b>, das Ausblenden des Randes, das Umstellen von 3-D zum flachen Erscheinungsbild, das vollst&auml;ndige Markieren der markierten Zeile, das Sichtbarmachen der Markierung, auch wenn das <b>ListView<\/b>-Steuerelement nicht den Fokus hat, Einstellungen f&uuml;r die Schriftart und den Drag and Drop-Modus sowie das Einf&uuml;gen einer Spalten&uuml;berschrift.<\/p>\n<h2>F&uuml;llen der ListView-Steuerelemente beim Anzeigen<\/h2>\n<p>Die beiden <b>ListView<\/b>-Steuerelemente sollen im Ereignis <b>Beim Anzeigen <\/b>gef&uuml;llt werden. Zuvor legen wir jedoch noch zwei Abfragen an, die wir als Basis f&uuml;r das F&uuml;llen der <b>ListView<\/b>-Steuerelemente nutzen.<\/p>\n<h2>Abfrage f&uuml;r die Empf&auml;nger<\/h2>\n<p>Die erste Abfrage hei&szlig;t <b>qryEmpfaenger <\/b>und enth&auml;lt die beiden Tabellen <b>tblEmpfaenger <\/b>und <b>tblVerteiler<\/b>. Aus der Tabelle <b>tblEmpfaenger <\/b>f&uuml;gen wir die beiden Felder <b>EmpfaengerID <\/b>und <b>Empfaenger <\/b>hinzu, aus der Tabelle <b>tblNewsletter <\/b>das Feld <b>NewsletterID<\/b>. Das Feld <b>NewsletterID <\/b>dient lediglich als Kriteriumsfeld. Hier legen wir als Vergleichswert einen Parameter namens <b>prmNewsletterID <\/b>fest (siehe Bild 8). Auf diese Weise liefert die Abfrage alle Empf&auml;nger, die dem mit dem Parameter <b>prmNewsletterID <\/b>zugewiesenen Newsletter zugeordnet sind.<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2025_06\/pic_1576_008.png\" alt=\"Datenherkunft f&uuml;r das ListView-Steuerelement lvwEmpfaenger\" width=\"599,559\" height=\"426,7022\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 8: Datenherkunft f&uuml;r das ListView-Steuerelement lvwEmpfaenger<\/span><\/b><\/p>\n<h2>Abfrage f&uuml;r die noch nicht zugeordneten Empf&auml;nger<\/h2>\n<p>Die zweite Abfrage ist etwas aufwendiger (siehe Bild 9). Sie enth&auml;lt nur die Tabelle <b>tblEmpfaenger<\/b> und liefert die Werte der Felder <b>EmpfaengerID <\/b>und <b>Empfaenger <\/b>der Tabelle. Sie filtert die Empf&auml;nger, indem sie alle in einer Unterabfrage enthaltenen Empf&auml;nger ausschlie&szlig;t. Das Kriterium mit der Unterabfrage lautet:<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2025_06\/pic_1576_009.png\" alt=\"Datenherkunft f&uuml;r das ListView-Steuerelement lvwKeinEmpfaenger\" width=\"700\" height=\"303,8369\"\/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 9: Datenherkunft f&uuml;r das ListView-Steuerelement lvwKeinEmpfaenger<\/span><\/b><\/p>\n<pre>Nicht In (\r\n   SELECT tblEmpfaenger.EmpfaengerID   FROM tblEmpfaenger   INNER JOIN tblVerteiler   ON tblEmpfaenger.EmpfaengerID =    tblVerteiler.EmpfaengerID   WHERE tblVerteiler.NewsletterID = [prmNewsletterID])<\/pre>\n<p>Die Unterabfrage enth&auml;lt also alle Empf&auml;nger, die bereits dem Newsletter aus dem Parameter <b>prmNewsletterID <\/b>zugeordnet sind.<\/p>\n<h2>Eintragen der Empf&auml;nger und Nicht-Empf&auml;nger in die ListView-Steuerelemente<\/h2>\n<p>Die Prozedur <b>Form_Current <\/b>aus Listing 2 deklariert verschiedene Variablen, um Recordsets auf Basis der beiden zuvor beschriebenen Abfragen zu erzeugen.<\/p>\n<pre><span style=\"color:blue;\">Sub <\/span>Form_Current()\r\n     <span style=\"color:blue;\">Dim <\/span>db<span style=\"color:blue;\"> As <\/span>dao.Database\r\n     <span style=\"color:blue;\">Dim <\/span>qdfKeinEmpfaenger<span style=\"color:blue;\"> As <\/span>dao.QueryDef\r\n     <span style=\"color:blue;\">Dim <\/span>qdfEmpfaenger<span style=\"color:blue;\"> As <\/span>dao.QueryDef\r\n     <span style=\"color:blue;\">Dim <\/span>rstKeinEmpfaenger<span style=\"color:blue;\"> As <\/span>dao.Recordset\r\n     <span style=\"color:blue;\">Dim <\/span>rstEmpfaenger<span style=\"color:blue;\"> As <\/span>dao.Recordset\r\n     <span style=\"color:blue;\">Dim <\/span>prm<span style=\"color:blue;\"> As <\/span>dao.Parameter\r\n     <span style=\"color:blue;\">Set<\/span> db = CurrentDb\r\n     <span style=\"color:blue;\">Set<\/span> qdfKeinEmpfaenger = db.QueryDefs(\"qryKeinEmpfaenger\")\r\n     <span style=\"color:blue;\">Set<\/span> prm = qdfKeinEmpfaenger.Parameters(\"prmNewsletterID\")\r\n     prm.Value = Me.NewsletterID\r\n     <span style=\"color:blue;\">Set<\/span> rstKeinEmpfaenger = qdfKeinEmpfaenger.OpenRecordset\r\n     ListeAktualisieren rstKeinEmpfaenger, objKeinEmpfaenger\r\n         \r\n     <span style=\"color:blue;\">Set<\/span> qdfEmpfaenger = db.QueryDefs(\"qryEmpfaenger\")\r\n     <span style=\"color:blue;\">Set<\/span> prm = qdfEmpfaenger.Parameters(\"prmNewsletterID\")\r\n     prm.Value = Me.NewsletterID\r\n     <span style=\"color:blue;\">Set<\/span> rstEmpfaenger = qdfEmpfaenger.OpenRecordset\r\n     ListeAktualisieren rstEmpfaenger, objEmpfaenger\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p><b><span style=\"color:darkgrey;\">Listing 2: F&uuml;llen der ListView-Steuerelemente<\/span><\/b><\/p>\n<p>Dabei holt sie zun&auml;chst einen Verweis auf das aktuelle <b>Database<\/b>-Objekt und referenziert dann die Abfrage <b>qryKeinEmpfaenger <\/b>mit der <b>QueryDef<\/b>-Variablen <b>qdfKeinEmpfaenger<\/b>. Dann stellt sie den Parameter <b>prmNewsletterID<\/b> auf den Wert des Feldes <b>NewsletterID <\/b>des aktuellen Datensatzes des Formulars ein.<\/p>\n<p>Schlie&szlig;lich &ouml;ffnet sie ein Recordset auf Basis dieses <b>QueryDef<\/b>-Objekts und referenziert dieses mit der Variablen <b>rst<\/b> und &uuml;bergibt dieses samt einem Verweis auf das zu f&uuml;llende <b>ListView<\/b>-Steuerelement an eine weitere Prozedur namens <b>ListeAktualisieren<\/b>, die wir im Anschluss beschreiben.<\/p>\n<p>F&uuml;r das <b>ListView<\/b>-Steuerelement <b>lvwEmpfaenger <\/b>und die Abfrage <b>qryEmpfaenger <\/b>geht die Prozedur analog vor.<\/p>\n<p>Die Prozedur <b>ListeAktualisieren <\/b>nimmt die Verweise auf das Recordset und das zu f&uuml;llende <b>ListView<\/b>-Steuerelement entgegen und leert zun&auml;chst mit der <b>Clear<\/b>-Methode der <b>ListItems<\/b>-Auflistung das <b>ListView<\/b>-Steuerelement (siehe Listing 3).<\/p>\n<pre><span style=\"color:blue;\">Private Sub <\/span>ListeAktualisieren(rst<span style=\"color:blue;\"> As <\/span>DAO.Recordset, objListView<span style=\"color:blue;\"> As <\/span>MSComctlLib.ListView)\r\n     objListView.ListItems.Clear\r\n     <span style=\"color:blue;\">Do While<\/span> <span style=\"color:blue;\">Not<\/span> rst.EOF\r\n         objListView.ListItems.Add , \"a\" & rst!EmpfaengerID, rst!Empfaenger\r\n         rst.Move<span style=\"color:blue;\">Next<\/span>\r\n     <span style=\"color:blue;\">Loop<\/span>\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p><b><span style=\"color:darkgrey;\">Listing 3: F&uuml;llen der ListView-Steuerelemente per Recordset<\/span><\/b><\/p>\n<p>Dann durchl&auml;uft sie in einer <b>Do While<\/b>-Schleife alle Eintr&auml;ge des Recordsets und f&uuml;gt f&uuml;r jeden Datensatz einen neuen Eintrag zum <b>ListView<\/b>-Steuerelement hinzu. Dabei &uuml;bergibt sie als <b>Key <\/b>den Buchstaben <b>a <\/b>und die ID des Datensatzes und als <b>Text <\/b>den Namen des Empf&auml;ngers.<\/p>\n<p>Damit sind die Listenfelder nun beispielsweise wie in Bild 10 gef&uuml;llt.<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2025_06\/02-11-2025_21-24-06.png\" alt=\"Die gef&uuml;llten ListView-Steuerelemente\" width=\"549,559\" height=\"408,0679\"\/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 10: Die gef&uuml;llten ListView-Steuerelemente<\/span><\/b><\/p>\n<h2>Daten zwischen den ListView-Steuerelementen verschieben<\/h2>\n<p>Da <b>ListView<\/b>-Steuerelemente ungebunden sind, ist wie auch beim <b>TreeView<\/b>-Steuerelement vor allem eines zu beachten: Neben dem Verschieben des Eintrags zwischen den Listen m&uuml;ssen auch die dahinter liegenden Datenbanktabellen aktualisiert werden.<\/p>\n<p>F&uuml;r das Ziehen eines Eintrags von einem zum anderen <b>ListView<\/b>-Steuerelement ben&ouml;tigen wir zwei Ereignisprozeduren je Liste. Diese f&uuml;gen wir nun &uuml;ber die beiden Auswahlfelder oben im Codefenster hinzu. Dazu w&auml;hlen wir zuerst den Eintrag <b>lvwEmpfaenger <\/b>im linken Auswahlfeld aus und dann nacheinander die drei Eintr&auml;ge <b>OLEStartDrag<\/b> und <b>OLEDragDrop<\/b>.<\/p>\n<p>Die gleiche Prozedur wiederholen wir f&uuml;r das <b>ListView<\/b>-Steuerelement <b>lvwKeinEmpfaenger<\/b>.<\/p>\n<h2>Eintr&auml;ge in die Empf&auml;ngerliste verschieben<\/h2>\n<p>Wenn wir einen der Eintr&auml;ge oder auch mehrere markierte Eintr&auml;ge mit der Maus fassen und den Drag and Drop-Vorgang initiieren, wird das Ereignis <b>OLEStartDrag <\/b>des Steuerelements <b>lvwEmpfaenger <\/b>ausgel&ouml;st (siehe Listing 4).<\/p>\n<pre><span style=\"color:blue;\">Private Sub <\/span>lvwKeinEmpfaenger_OLEStartDrag(Data<span style=\"color:blue;\"> As Object<\/span>, AllowedEffects<span style=\"color:blue;\"> As Long<\/span>)\r\n     <span style=\"color:blue;\">Dim <\/span>objListitem<span style=\"color:blue;\"> As <\/span>ListItem\r\n     <span style=\"color:blue;\">Dim <\/span>strData<span style=\"color:blue;\"> As String<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>strDataItems()<span style=\"color:blue;\"> As String<\/span>\r\n     For Each objListitem In lvwKeinEmpfaenger.ListItems\r\n         <span style=\"color:blue;\">If <\/span>objListitem.Selected = <span style=\"color:blue;\">True<\/span><span style=\"color:blue;\"> Then<\/span>\r\n             strData = strData & objListitem.Key & \"&brvbar;\" & objListitem.Text & \";\"\r\n         <span style=\"color:blue;\">End If<\/span>\r\n     <span style=\"color:blue;\">Next<\/span>\r\n     strData = <span style=\"color:blue;\">Left<\/span>(strData, <span style=\"color:blue;\">Len<\/span>(strData) - 1)\r\n     Data.Clear\r\n     Data.SetData strData, ccCFText\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p><b><span style=\"color:darkgrey;\">Listing 4: Starten des Drag and Drop in der Liste der Nicht-Empf&auml;nger<\/span><\/b><\/p>\n<p>Diese Prozedur durchl&auml;uft alle Eintr&auml;ge des <b>ListView<\/b>-Steuerelements und pr&uuml;ft f&uuml;r jedes Element mit der <b>Selected<\/b>-Eigenschaft, ob dieses markiert ist. Ist das der Fall, f&uuml;gt sie der <b>String<\/b>-Variablen <b>strData <\/b>ein Semikolon, den <b>Key<\/b>, das Zeichen <b>&brvbar; <\/b>und den Wert der Eigenschaft <b>Text <\/b>hinzu, also zum Beispiel <b>a1 &brvbar;Minhorst, Andr&eacute;<\/b>. Bei mehreren markierten Eintr&auml;gen kommt so eine Zeichenkette wie die folgende zusammen:<\/p>\n<pre>;a1 &brvbar;Minhorst, Andr&eacute;;a2 &brvbar;M&uuml;ller, Klaus<\/pre>\n<p>Im folgenden Schritt schneiden wir noch das f&uuml;hrende Semikolon ab. Schlie&szlig;lich leeren wir den Parameter Data, um sicherzugehen, dass dieser leer ist, und weisen diesem mit der <b>SetData<\/b>-Methode den Inhalt von <b>strData <\/b>plus den Wert<b> ccCFText <\/b>als Kennzeichnung des Inhalts als Zeichenkette hinzu.<\/p>\n<h2>Fallenlassen der Eintr&auml;ge in der Liste der Empf&auml;nger<\/h2>\n<p>Lassen wir die Eintr&auml;ge &uuml;ber dem <b>ListView<\/b>-Steuerelement <b>lvwEmpfaenger <\/b>fallen, l&ouml;st dies die Prozedur <b>OLEDragDrop <\/b>dieses Steuerelements aus (siehe Listing 5). Diese erh&auml;lt mit dem Parameter <b>Data <\/b>die Daten, die wir in der Ereignisprozedur <b>lvwKeinEmpfaenger_OLEStartDrag<\/b> des jeweils anderen <b>ListView<\/b>-Steuerelements gef&uuml;llt haben. Den Inhalt lesen wir mit der Funktion <b>GetData <\/b>aus und splitten die Zeichenkette mit der <b>Split<\/b>-Funktion an den Stellen mit einem Semikolon in ein <b>String<\/b>-Array namens <b>strDataItems <\/b>auf.<\/p>\n<pre><span style=\"color:blue;\">Private Sub <\/span>lvwEmpfaenger_OLEDragDrop(Data<span style=\"color:blue;\"> As Object<\/span>, Effect<span style=\"color:blue;\"> As Long<\/span>, Button<span style=\"color:blue;\"> As Integer<\/span>, Shift<span style=\"color:blue;\"> As Integer<\/span>, _\r\n         x<span style=\"color:blue;\"> As Single<\/span>, y<span style=\"color:blue;\"> As Single<\/span>)\r\n     <span style=\"color:blue;\">Dim <\/span>strData<span style=\"color:blue;\"> As String<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>strDataItems()<span style=\"color:blue;\"> As String<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>strText<span style=\"color:blue;\"> As String<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>strKey<span style=\"color:blue;\"> As String<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>i<span style=\"color:blue;\"> As Integer<\/span>\r\n     strData = Data.GetData(ccCFText)\r\n     strDataItems = <span style=\"color:blue;\">Split<\/span>(strData, \";\")\r\n     For i = <span style=\"color:blue;\">LBound<\/span>(strDataItems) To <span style=\"color:blue;\">UBound<\/span>(strDataItems)\r\n         strKey = <span style=\"color:blue;\">Split<\/span>(strDataItems(i), \"&brvbar;\")(0)\r\n         strText = <span style=\"color:blue;\">Split<\/span>(strDataItems(i), \"&brvbar;\")(1)\r\n         If IsNull(DLookup(\"EmpfaengerID\", \"tblVerteiler\", \"NewsletterID = \" & Me.NewsletterID _\r\n                 & \" AND EmpfaengerID = \" & <span style=\"color:blue;\">Mid<\/span>(strKey, 2))) Then\r\n             lvwEmpfaenger.ListItems.Add , strKey, strText\r\n             lvwKeinEmpfaenger.ListItems.Remove strKey\r\n             CurrentDb.Execute \"INSERT INTO tblVerteiler(NewsletterID, EmpfaengerID) \" & \"VALUES(\" _\r\n                 & Me.NewsletterID & \", \" & <span style=\"color:blue;\">Mid<\/span>(strKey, 2) & \")\"\r\n         <span style=\"color:blue;\">End If<\/span>\r\n     <span style=\"color:blue;\">Next<\/span> i\r\n     <span style=\"color:blue;\">Call<\/span> Form_Current\r\n     For i = 1 To objEmpfaenger.ListItems.Count\r\n         objEmpfaenger.ListItems(i).Selected = <span style=\"color:blue;\">False<\/span>\r\n     <span style=\"color:blue;\">Next<\/span> i\r\n     For i = <span style=\"color:blue;\">LBound<\/span>(strDataItems) To <span style=\"color:blue;\">UBound<\/span>(strDataItems)\r\n         strKey = <span style=\"color:blue;\">Split<\/span>(strDataItems(i), \"&brvbar;\")(0)\r\n         strText = <span style=\"color:blue;\">Split<\/span>(strDataItems(i), \"&brvbar;\")(1)\r\n         objEmpfaenger.ListItems(strKey).Selected = <span style=\"color:blue;\">True<\/span>\r\n     <span style=\"color:blue;\">Next<\/span> i\r\n     Me.lvwEmpfaenger.SetFocus\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p><b><span style=\"color:darkgrey;\">Listing 5: Fallenlassen von Elementen in der Liste der Empf&auml;nger<\/span><\/b><\/p>\n<p>Anschlie&szlig;end durchl&auml;uft die Prozedur eine <b>For&#8230;Next<\/b>-Schleife &uuml;ber alle Elemente dieses Arrays.<\/p>\n<p>Im ersten Schritt nutzen wir wieder die <b>Split<\/b>-Funktion, um die einzelnen Array-Element wiederum an der Stelle mit dem Zeichen <b>&brvbar; <\/b>aufzuteilen und in die Variablen <b>strKey <\/b>und <b>strText <\/b>zu schreiben.<\/p>\n<p>Wir pr&uuml;fen sicherheitshalber mit der <b>DLookup<\/b>-Funktion, ob noch kein Eintrag in der Zieltabelle <b>tblVerteiler <\/b>enthalten ist. Ist dies der Fall, f&uuml;gen wir zun&auml;chst dem <b>ListView<\/b>-Steuerelement <b>lvwEmpfaenger <\/b>einen neuen Eintrag mit dem entsprechenden Key und Text hinzu. Danach entfernen wir den gezogenen Eintrag mit der <b>Remove<\/b>-Methode aus dem <b>ListView<\/b>-Steuerelement <b>lvwKeinEmpfaenger<\/b>.<\/p>\n<p>Schlie&szlig;lich tragen wir mit einer <b>INSERT INTO<\/b>-Anweisung einen neuen Datensatz in die Tabelle <b>tblVerteiler <\/b>ein, der den Wert des Feldes <b>NewsletterID <\/b>des aktuellen Datensatzes aus dem Formular und den aus dem Key extrahierten Prim&auml;rschl&uuml;sselfeld des zu verschiebenden Empf&auml;ngers enth&auml;lt.<\/p>\n<p>Damit w&auml;ren wir fast fertig, allerdings wurde der neue Eintrag nicht alphabetisch zum <b>ListView<\/b>-Steuerelement <b>lvwEmpfaenger <\/b>hinzugef&uuml;gt, sondern einfach hinten angeh&auml;ngt. Also rufen wir an dieser Stelle der Einfachheit halber nochmals die Prozedur <b>Form_Current <\/b>auf, die sonst nur beim Datensatzwechsel im Formular ausgel&ouml;st wird, und sorgen so f&uuml;r ein erneutes Einlesen der Daten, diesmal in alphabetischer Reihenfolge. So wird der neu hinzugef&uuml;gte Eintrag direkt an der richtigen Stelle angezeigt.<\/p>\n<p>Wir k&ouml;nnten dies durch zwei Alternativen ersetzen:<\/p>\n<ul>\n<li>erstens das gezielte Einf&uuml;gen an dem entsprechenden Index des Ziel-<b>ListView<\/b>-Steuerelements und <\/li>\n<li>zweitens, indem wir zumindest nur das Ziel-<b>ListView<\/b>-Steuerelement aktualisieren.<\/li>\n<\/ul>\n<p>Bei gr&ouml;&szlig;eren Datenmengen empfiehlt sich die eine oder andere Vorgehensweise, zur Verdeutlichung nutzen wir aber hier die einfachere Variante. Schlie&szlig;lich wollen wir noch die zuletzt eingef&uuml;gten Datens&auml;tze im <b>ListView<\/b>-Steuerelement markieren. Dazu durchlaufen wir in einer <b>For&#8230;Next<\/b>-Schleife alle Eintr&auml;ge und entfernen zun&auml;chst eine eventuell noch vorhandene Markierung.<\/p>\n<p>Danach durchlaufen wir noch einmal alle &uuml;bermittelten und in dem Array <b>strDataItems <\/b>gespeicherten Eintr&auml;ge, lesen hier erneut den Key aus und selektieren die mit <b>strKey <\/b>ermittelten Eintr&auml;ge durch das Einstellen der Eigenschaft <b>Selected<\/b>. Damit erhalten wir beispielsweise die Ansicht aus Bild 11.<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2025_06\/^pic_1576_010.png\" alt=\"Frisch &uuml;bertragene Empf&auml;nger im ListView-Steuerelement\" width=\"549,559\" height=\"404,7772\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 11: Frisch &uuml;bertragene Empf&auml;nger im ListView-Steuerelement<\/span><\/b><\/p>\n<h2>&Uuml;bertragen von Empf&auml;nger zu den Nicht-Empf&auml;ngern<\/h2>\n<p>Die beiden Ereignisprozeduren zum Starten des Drag and Drop-Vorgangs vom <b>ListView<\/b>-Steuerelement <b>lvwEmpfaenger <\/b>zur Liste <b>lvwKeinEmpfaenger <\/b>sehen ganz &auml;hnlich aus. Die Prozedur <b>lvwEmpfaenger_OLEStartDrag <\/b>k&ouml;nnen wir sogar analog aufbauen und tauschen nur <b>lvwKeinEmpfaenger <\/b>durch <b>lvwEmpfaenger <\/b>aus.<\/p>\n<p>Bei der Prozedur <b>lvwKeinEmpfaenger <\/b>m&uuml;ssen wir ebenfalls diesen Austausch vorzunehmen. Au&szlig;erdem m&uuml;ssen wir die SQL-Anweisung &auml;ndern.<\/p>\n<p>Diese soll nun nicht mehr einen neuen Datensatz zur Tabelle <b>tblVerteiler <\/b>hinzuf&uuml;gen, sondern den Datensatz mit der entsprechenden <b>NewsletterID <\/b>und <b>EmpfaengerID <\/b>aus der Tabelle entfernen. Dementsprechend definieren wir hier keine <b>INSERT INTO<\/b>-Anweisung, sondern eine <b>DELETE<\/b>-Anweisung (siehe Listing 6).<\/p>\n<pre><span style=\"color:blue;\">Private Sub <\/span>lvwKeinEmpfaenger_OLEDragDrop(Data<span style=\"color:blue;\"> As Object<\/span>, Effect<span style=\"color:blue;\"> As Long<\/span>, Button<span style=\"color:blue;\"> As Integer<\/span>, _\r\n         Shift<span style=\"color:blue;\"> As Integer<\/span>, x<span style=\"color:blue;\"> As Single<\/span>, y<span style=\"color:blue;\"> As Single<\/span>)\r\n     <span style=\"color:blue;\">Dim <\/span>strData<span style=\"color:blue;\"> As String<\/span>, strDataItems()<span style=\"color:blue;\"> As String<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>strText<span style=\"color:blue;\"> As String<\/span>, strKey<span style=\"color:blue;\"> As String<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>i<span style=\"color:blue;\"> As Integer<\/span>\r\n     strData = Data.GetData(ccCFText)\r\n     strDataItems = <span style=\"color:blue;\">Split<\/span>(strData, \";\")\r\n     For i = <span style=\"color:blue;\">LBound<\/span>(strDataItems) To <span style=\"color:blue;\">UBound<\/span>(strDataItems)\r\n         strKey = <span style=\"color:blue;\">Split<\/span>(strDataItems(i), \"&brvbar;\")(0)\r\n         strText = <span style=\"color:blue;\">Split<\/span>(strDataItems(i), \"&brvbar;\")(1)\r\n         If <span style=\"color:blue;\">Not<\/span> IsNull(DLookup(\"EmpfaengerID\", \"tblVerteiler\", \"NewsletterID = \" & Me.NewsletterID _\r\n                 & \" AND EmpfaengerID = \" & <span style=\"color:blue;\">Mid<\/span>(strKey, 2))) Then\r\n             lvwKeinEmpfaenger.ListItems.Add , strKey, strText\r\n             lvwEmpfaenger.ListItems.Remove strKey\r\n             CurrentDb.Execute \"DELETE FROM tblVerteiler WHERE NewsletterID = \" & Me.NewsletterID _\r\n                 & \" AND EmpfaengerID =  \" & <span style=\"color:blue;\">Mid<\/span>(strKey, 2)\r\n         <span style=\"color:blue;\">End If<\/span>\r\n     <span style=\"color:blue;\">Next<\/span> i\r\n     <span style=\"color:blue;\">Call<\/span> Form_Current\r\n     <span style=\"color:blue;\">Call<\/span> Form_Current\r\n     For i = 1 To objKeinEmpfaenger.ListItems.Count\r\n         objKeinEmpfaenger.ListItems(i).Selected = <span style=\"color:blue;\">False<\/span>\r\n     <span style=\"color:blue;\">Next<\/span> i\r\n     For i = <span style=\"color:blue;\">LBound<\/span>(strDataItems) To <span style=\"color:blue;\">UBound<\/span>(strDataItems)\r\n         strKey = <span style=\"color:blue;\">Split<\/span>(strDataItems(i), \"&brvbar;\")(0)\r\n         strText = <span style=\"color:blue;\">Split<\/span>(strDataItems(i), \"&brvbar;\")(1)\r\n         objKeinEmpfaenger.ListItems(strKey).Selected = <span style=\"color:blue;\">True<\/span>\r\n     <span style=\"color:blue;\">Next<\/span> i\r\n     Me.lvwKeinEmpfaenger.SetFocus\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p><b><span style=\"color:darkgrey;\">Listing 6: Fallenlassen von Elementen in der Liste der Nicht-Empf&auml;nger<\/span><\/b><\/p>\n<h2>Zusammenfassung und Ausblick<\/h2>\n<p>In diesem Beitrag haben wir einen praktischen Anwendungsfall f&uuml;r Drag and Drop zwischen zwei <b>ListView<\/b>-Steuerelementen demonstriert, und zwar am Beispiel einer m:n-Beziehung. Dabei werden die Daten der m-Seite im Formular abgebildet werden und die der n-Seite in den beiden <b>ListView<\/b>-Steuerelementen, wobei eines die &uuml;ber die Tabelle <b>tblVerteiler <\/b>verkn&uuml;pften Empf&auml;nger liefert und das andere die nicht verkn&uuml;pften Datens&auml;tze.<\/p>\n<p>Damit k&ouml;nnen wir nicht nur die Daten zwischen den <b>ListView<\/b>-Steuerelementen hin- und herziehen, sondern gleichzeitig im Hintergrund die Daten der m:n-Beziehung in der Verkn&uuml;pfungstabelle <b>tblVerteiler <\/b>pflegen.<\/p>\n<h2>Downloads zu diesem Beitrag<\/h2>\n<p>Enthaltene Beispieldateien:<\/p>\n<p>MNBeziehungPerListView.accdb<\/p>\n<p><a href=\"..\/fileadmin\/beispiele\/305037DC-0B4E-430F-9944-21179CFDBEE0\/aiu_1576.zip\">Download<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Wir haben uns bereits in einigen Beitr&auml;gen angesehen, wie man die Daten einer m:n-Beziehung mit zwei nebeneinander liegenden Listenfeldern verwalten kann. Das Hinzuf&uuml;gen oder Entfernen erfolgte dabei per Doppelklick auf den jeweiligen Eintrag oder &uuml;ber entsprechende Schaltfl&auml;chen. Im Gegensatz zu Listenfeldern k&ouml;nnen wir im ListView-Steuerelement jedoch auch Drag and Drop einsetzen. Wie das grundlegend funktioniert, haben wir uns bereits im hinteren Teil des Beitrags &#8222;ListView-Steuerelement mit VBA programmieren&#8220; (www.access-im-unternehmen.de\/1573) angesehen. Im vorliegenden Beitrag schauen wir uns an, wie wir die Daten aus zwei ListView-Steuerelementen per Drag and Drop hin- und herschieben k&ouml;nnen. <\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"om_disable_all_campaigns":false,"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"_uf_show_specific_survey":0,"_uf_disable_surveys":false,"footnotes":""},"categories":[662025,66062025,44000044],"tags":[],"class_list":["post-55001576","post","type-post","status-publish","format-standard","hentry","category-662025","category-66062025","category-AccessSteuerelemente"],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v20.9 (Yoast SEO v27.5) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>m:n-Beziehung mit Drag and Drop per ListView - Access im Unternehmen<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/access-im-unternehmen.de\/mnBeziehung_mit_Drag_and_Drop_per_ListView\/\" \/>\n<meta property=\"og:locale\" content=\"de_DE\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"m:n-Beziehung mit Drag and Drop per ListView\" \/>\n<meta property=\"og:description\" content=\"Wir haben uns bereits in einigen Beitr&auml;gen angesehen, wie man die Daten einer m:n-Beziehung mit zwei nebeneinander liegenden Listenfeldern verwalten kann. Das Hinzuf&uuml;gen oder Entfernen erfolgte dabei per Doppelklick auf den jeweiligen Eintrag oder &uuml;ber entsprechende Schaltfl&auml;chen. Im Gegensatz zu Listenfeldern k&ouml;nnen wir im ListView-Steuerelement jedoch auch Drag and Drop einsetzen. Wie das grundlegend funktioniert, haben wir uns bereits im hinteren Teil des Beitrags &quot;ListView-Steuerelement mit VBA programmieren&quot; (www.access-im-unternehmen.de\/1573) angesehen. Im vorliegenden Beitrag schauen wir uns an, wie wir die Daten aus zwei ListView-Steuerelementen per Drag and Drop hin- und herschieben k&ouml;nnen.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/access-im-unternehmen.de\/mnBeziehung_mit_Drag_and_Drop_per_ListView\/\" \/>\n<meta property=\"og:site_name\" content=\"Access im Unternehmen\" \/>\n<meta property=\"article:published_time\" content=\"2025-12-02T21:35:16+00:00\" \/>\n<meta name=\"author\" content=\"Andr\u00e9 Minhorst\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Verfasst von\" \/>\n\t<meta name=\"twitter:data1\" content=\"Andr\u00e9 Minhorst\" \/>\n\t<meta name=\"twitter:label2\" content=\"Gesch\u00e4tzte Lesezeit\" \/>\n\t<meta name=\"twitter:data2\" content=\"14\u00a0Minuten\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/mnBeziehung_mit_Drag_and_Drop_per_ListView\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/mnBeziehung_mit_Drag_and_Drop_per_ListView\\\/\"},\"author\":{\"name\":\"Andr\u00e9 Minhorst\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#\\\/schema\\\/person\\\/13395c4bcd7d7963efe33be9c584d93f\"},\"headline\":\"m:n-Beziehung mit Drag and Drop per ListView\",\"datePublished\":\"2025-12-02T21:35:16+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/mnBeziehung_mit_Drag_and_Drop_per_ListView\\\/\"},\"wordCount\":2271,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#organization\"},\"articleSection\":[\"2025\",\"6\\\/2025\",\"Access-Steuerelemente\"],\"inLanguage\":\"de\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/access-im-unternehmen.de\\\/mnBeziehung_mit_Drag_and_Drop_per_ListView\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/mnBeziehung_mit_Drag_and_Drop_per_ListView\\\/\",\"url\":\"https:\\\/\\\/access-im-unternehmen.de\\\/mnBeziehung_mit_Drag_and_Drop_per_ListView\\\/\",\"name\":\"m:n-Beziehung mit Drag and Drop per ListView - Access im Unternehmen\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#website\"},\"datePublished\":\"2025-12-02T21:35:16+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/mnBeziehung_mit_Drag_and_Drop_per_ListView\\\/#breadcrumb\"},\"inLanguage\":\"de\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/access-im-unternehmen.de\\\/mnBeziehung_mit_Drag_and_Drop_per_ListView\\\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/mnBeziehung_mit_Drag_and_Drop_per_ListView\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/access-im-unternehmen.de\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"m:n-Beziehung mit Drag and Drop per ListView\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#website\",\"url\":\"https:\\\/\\\/access-im-unternehmen.de\\\/\",\"name\":\"Access im Unternehmen\",\"description\":\"Das Magazin f\u00fcr Datenbankentwickler auf Basis von Microsoft Access\",\"publisher\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/access-im-unternehmen.de\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"de\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#organization\",\"name\":\"Andr\u00e9 Minhorst Verlag\",\"url\":\"https:\\\/\\\/access-im-unternehmen.de\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"de\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/access-im-unternehmen.de\\\/wp-content\\\/uploads\\\/2019\\\/09\\\/aiu_wp.png\",\"contentUrl\":\"https:\\\/\\\/access-im-unternehmen.de\\\/wp-content\\\/uploads\\\/2019\\\/09\\\/aiu_wp.png\",\"width\":370,\"height\":111,\"caption\":\"Andr\u00e9 Minhorst Verlag\"},\"image\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#\\\/schema\\\/logo\\\/image\\\/\"}},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#\\\/schema\\\/person\\\/13395c4bcd7d7963efe33be9c584d93f\",\"name\":\"Andr\u00e9 Minhorst\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"de\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/1b9d010cf1716692cb9c34f21554e07d17d461acaea5b61b8cb21cbec678d48a?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/1b9d010cf1716692cb9c34f21554e07d17d461acaea5b61b8cb21cbec678d48a?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/1b9d010cf1716692cb9c34f21554e07d17d461acaea5b61b8cb21cbec678d48a?s=96&d=mm&r=g\",\"caption\":\"Andr\u00e9 Minhorst\"}}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"m:n-Beziehung mit Drag and Drop per ListView - Access im Unternehmen","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/access-im-unternehmen.de\/mnBeziehung_mit_Drag_and_Drop_per_ListView\/","og_locale":"de_DE","og_type":"article","og_title":"m:n-Beziehung mit Drag and Drop per ListView","og_description":"Wir haben uns bereits in einigen Beitr&auml;gen angesehen, wie man die Daten einer m:n-Beziehung mit zwei nebeneinander liegenden Listenfeldern verwalten kann. Das Hinzuf&uuml;gen oder Entfernen erfolgte dabei per Doppelklick auf den jeweiligen Eintrag oder &uuml;ber entsprechende Schaltfl&auml;chen. Im Gegensatz zu Listenfeldern k&ouml;nnen wir im ListView-Steuerelement jedoch auch Drag and Drop einsetzen. Wie das grundlegend funktioniert, haben wir uns bereits im hinteren Teil des Beitrags \"ListView-Steuerelement mit VBA programmieren\" (www.access-im-unternehmen.de\/1573) angesehen. Im vorliegenden Beitrag schauen wir uns an, wie wir die Daten aus zwei ListView-Steuerelementen per Drag and Drop hin- und herschieben k&ouml;nnen.","og_url":"https:\/\/access-im-unternehmen.de\/mnBeziehung_mit_Drag_and_Drop_per_ListView\/","og_site_name":"Access im Unternehmen","article_published_time":"2025-12-02T21:35:16+00:00","author":"Andr\u00e9 Minhorst","twitter_card":"summary_large_image","twitter_misc":{"Verfasst von":"Andr\u00e9 Minhorst","Gesch\u00e4tzte Lesezeit":"14\u00a0Minuten"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/access-im-unternehmen.de\/mnBeziehung_mit_Drag_and_Drop_per_ListView\/#article","isPartOf":{"@id":"https:\/\/access-im-unternehmen.de\/mnBeziehung_mit_Drag_and_Drop_per_ListView\/"},"author":{"name":"Andr\u00e9 Minhorst","@id":"https:\/\/access-im-unternehmen.de\/#\/schema\/person\/13395c4bcd7d7963efe33be9c584d93f"},"headline":"m:n-Beziehung mit Drag and Drop per ListView","datePublished":"2025-12-02T21:35:16+00:00","mainEntityOfPage":{"@id":"https:\/\/access-im-unternehmen.de\/mnBeziehung_mit_Drag_and_Drop_per_ListView\/"},"wordCount":2271,"commentCount":0,"publisher":{"@id":"https:\/\/access-im-unternehmen.de\/#organization"},"articleSection":["2025","6\/2025","Access-Steuerelemente"],"inLanguage":"de","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/access-im-unternehmen.de\/mnBeziehung_mit_Drag_and_Drop_per_ListView\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/access-im-unternehmen.de\/mnBeziehung_mit_Drag_and_Drop_per_ListView\/","url":"https:\/\/access-im-unternehmen.de\/mnBeziehung_mit_Drag_and_Drop_per_ListView\/","name":"m:n-Beziehung mit Drag and Drop per ListView - Access im Unternehmen","isPartOf":{"@id":"https:\/\/access-im-unternehmen.de\/#website"},"datePublished":"2025-12-02T21:35:16+00:00","breadcrumb":{"@id":"https:\/\/access-im-unternehmen.de\/mnBeziehung_mit_Drag_and_Drop_per_ListView\/#breadcrumb"},"inLanguage":"de","potentialAction":[{"@type":"ReadAction","target":["https:\/\/access-im-unternehmen.de\/mnBeziehung_mit_Drag_and_Drop_per_ListView\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/access-im-unternehmen.de\/mnBeziehung_mit_Drag_and_Drop_per_ListView\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/access-im-unternehmen.de\/"},{"@type":"ListItem","position":2,"name":"m:n-Beziehung mit Drag and Drop per ListView"}]},{"@type":"WebSite","@id":"https:\/\/access-im-unternehmen.de\/#website","url":"https:\/\/access-im-unternehmen.de\/","name":"Access im Unternehmen","description":"Das Magazin f\u00fcr Datenbankentwickler auf Basis von Microsoft Access","publisher":{"@id":"https:\/\/access-im-unternehmen.de\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/access-im-unternehmen.de\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"de"},{"@type":"Organization","@id":"https:\/\/access-im-unternehmen.de\/#organization","name":"Andr\u00e9 Minhorst Verlag","url":"https:\/\/access-im-unternehmen.de\/","logo":{"@type":"ImageObject","inLanguage":"de","@id":"https:\/\/access-im-unternehmen.de\/#\/schema\/logo\/image\/","url":"https:\/\/access-im-unternehmen.de\/wp-content\/uploads\/2019\/09\/aiu_wp.png","contentUrl":"https:\/\/access-im-unternehmen.de\/wp-content\/uploads\/2019\/09\/aiu_wp.png","width":370,"height":111,"caption":"Andr\u00e9 Minhorst Verlag"},"image":{"@id":"https:\/\/access-im-unternehmen.de\/#\/schema\/logo\/image\/"}},{"@type":"Person","@id":"https:\/\/access-im-unternehmen.de\/#\/schema\/person\/13395c4bcd7d7963efe33be9c584d93f","name":"Andr\u00e9 Minhorst","image":{"@type":"ImageObject","inLanguage":"de","@id":"https:\/\/secure.gravatar.com\/avatar\/1b9d010cf1716692cb9c34f21554e07d17d461acaea5b61b8cb21cbec678d48a?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/1b9d010cf1716692cb9c34f21554e07d17d461acaea5b61b8cb21cbec678d48a?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/1b9d010cf1716692cb9c34f21554e07d17d461acaea5b61b8cb21cbec678d48a?s=96&d=mm&r=g","caption":"Andr\u00e9 Minhorst"}}]}},"_links":{"self":[{"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/posts\/55001576","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/comments?post=55001576"}],"version-history":[{"count":0,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/posts\/55001576\/revisions"}],"wp:attachment":[{"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/media?parent=55001576"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/categories?post=55001576"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/tags?post=55001576"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}