{"id":55000826,"date":"2012-04-01T00:00:00","date_gmt":"2020-05-22T21:53:36","guid":{"rendered":"http:\/\/access-im-unternehmen.aix-dev.de\/aiu\/?p=826"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-30T00:00:00","slug":"Aufgaben_per_TreeView_verwalten","status":"publish","type":"post","link":"https:\/\/access-im-unternehmen.de\/Aufgaben_per_TreeView_verwalten\/","title":{"rendered":"Aufgaben per TreeView verwalten"},"content":{"rendered":"<p><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/vg05.met.vgwort.de\/na\/bddeac028a0845daa293111afcf29472\" width=\"1\" height=\"1\" alt=\"\"><\/p>\n<p><b>Aufgaben lassen sich normalerweise sch&ouml;n in einer Liste darstellen. Manche Aufgaben sind aber derart umfangreich, dass man sie lieber in kleine H&auml;ppchen aufteilt und diese nacheinander erledigt. Also stellen wir dies in hierarchischer Form im TreeView dar. Zusammen mit der M&ouml;glichkeit, Aufgaben per Kontextmen&uuml; anzulegen und zu l&ouml;schen, Unteraufgaben zu verschieben oder erledigte Aufgaben abzuhaken, wird eine richtige kleine L&ouml;sung daraus. Es kommt aber noch besser: Das Ergebnis dieses Beitrags verwenden wir in unserer L&ouml;sung &#8222;Tagesablauf verwalten&#8220; weiter.<\/b><\/p>\n<p><b>Die L&ouml;sung im &Uuml;berblick<\/b><\/p>\n<p>Die Aufgabenverwaltung soll das Anlegen, Bearbeiten, L&ouml;schen und Zuordnen von Aufgaben erleichtern. Die Aufgaben liegen in einer Tabelle, eine weitere erlaubt die hierarchische Zuordnung der Aufgaben. Hierarchie Nat&uuml;rlich: Hier kommt das TreeView-Steuerelement zum Einsatz. Es zeigt die Aufgaben wie in Bild 1 an.<\/p>\n<p><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2012_02\/AufgabenImTreeview-web-images\/pic006.png\" alt=\"pic006.png\" \/><\/p>\n<p><b><span style=\"color:darkgrey\">Bild 1: Anzeige von Aufgaben per TreeView-Steuerelement <\/span><\/b><\/p>\n<p>In der Abbildung erkennen Sie auch bereits, wie Sie Aufgaben anlegen und l&ouml;schen: n&auml;mlich per Kontextmen&uuml;eintrag. Der Eintrag <b>Neue Aufgabe <\/b>&ouml;ffnet den Dialog aus Bild 2, mit dem Sie eine neue Aufgabe anlegen k&ouml;nnen. Dort tragen Sie Informationen wie den Namen der Aufgabe, eine Beschreibung, das geplante und das tats&auml;chliche Erledigungsdatum ein, w&auml;hlen eine Kategorie aus und stellen ein, ob die Aufgabe heute erledigt werden soll. Ein Klick auf <b>OK<\/b> schlie&szlig;t das Formular und f&uuml;gt die neue Aufgabe gleich zum Baum hinzu &#8211; und zwar unterhalb des Elements, dessen Kontextmen&uuml; Sie zuvor benutzt haben.<\/p>\n<p><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2012_02\/AufgabenImTreeview-web-images\/pic007.png\" alt=\"pic007.png\" \/><\/p>\n<p><b><span style=\"color:darkgrey\">Bild 2: Anlegen einer neuen Aufgabe<\/span><\/b><\/p>\n<p>Die L&ouml;sung bietet noch mehr: So k&ouml;nnen Sie eine Aufgabe per Doppelklick in der Detailansicht &ouml;ffnen, um nachtr&auml;gliche &auml;nderungen vorzunehmen. &auml;nderungen an der Bezeichnung werden gleich in das TreeView-Steuerelement &uuml;bernommen.<\/p>\n<p>Nicht sichtbar, aber sehr n&uuml;tzlich ist die M&ouml;glichkeit, Aufgaben per Drag and Drop zu verschieben oder zu kopieren. Das Verschieben erledigen Sie, indem Sie ein Element bei gedr&uuml;ckter Maustaste auf ein anderes Element ziehen. Die Aufgabe wird der Zielaufgabe untergeordnet.<\/p>\n<p>Wenn Sie beim Drag-and-Drop-Vorgang die <b>Strg<\/b>-Taste gedr&uuml;ckt halten, legt die Anwendung eine Kopie der betroffenen Aufgabe an und speichert diese direkt unterhalb der Zielaufgabe. Die Aufgabe erh&auml;lt dann genau die gleichen Eigenschaften wie die Originalaufgabe.<\/p>\n<p>Sollten Sie eine Aufgabe ein zweites Mal unterhalb einer Aufgabe anlegen wollen, ziehen Sie diese einfach bei gedr&uuml;ckter <b>Strg<\/b>-Taste auf die gemeinsame &uuml;bergeordnete Aufgabe.<\/p>\n<p>Der Aufgabenbaum soll eine &Uuml;bersicht &uuml;ber alle zu erledigenden Aufgaben bieten. In der L&ouml;sung <b>Tagesablauf verwalten<\/b>, die wir im n&auml;chsten Heft vervollst&auml;ndigen, wird der Aufgabenbaum neben einer Liste der heute zu erledigenden Aufgaben und einem Zeitplan f&uuml;r den jeweiligen Tag dargestellt. Sie k&ouml;nnen dann Aufgaben aus dem Aufgabenbaum per Drag and Drop in die verschiedenen Listen ziehen &#8211; entweder als Aufgabe in die Liste der heutigen Aufgaben oder auch als T&auml;tigkeit in die Liste der T&auml;tigkeiten des entsprechenden Tages.<\/p>\n<p>Die Aufgabendetails enthalten eine Eigenschaft, mit der Sie eine Kategorie festlegen k&ouml;nnen. Diese w&auml;hlen Sie entweder per Kombinationsfeld aus den bestehenden Kategorien aus oder Sie klicken auf die Schaltfl&auml;che mit den drei Punkten. Dies &ouml;ffnet zun&auml;chst den Dialog <b>Kategorie-&Uuml;bersicht <\/b>aus Bild 3. Hier k&ouml;nnen Sie eine der vorhandenen Kategorien ausw&auml;hlen, Kategorien l&ouml;schen oder neue Kategorien anlegen. In jedem Fall wird hier gleich die bereits gew&auml;hlte Kategorie ausgew&auml;hlt und beim Schlie&szlig;en des Formulars &uuml;bernommen.<\/p>\n<p><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2012_02\/AufgabenImTreeview-web-images\/pic008.png\" alt=\"pic008.png\" \/><\/p>\n<p><b><span style=\"color:darkgrey\">Bild 3: Ausw&auml;hlen und verwalten der Kategorien<\/span><\/b><\/p>\n<p><b>Datenmodell<\/b><\/p>\n<p>Die Grundlage f&uuml;r unseren Aufgabenbaum ist eine Tabelle namens <b>tblAufgaben<\/b>, welche die wesentlichen Informationen &uuml;ber eine Aufgabe enth&auml;lt: Die Bezeichnung, eine Kurzbeschreibung, Felder zum Eintragen von Datumsangaben wie dem geplanten und dem tats&auml;chlichen Erledigungsdatum sowie ein Auswahlfeld f&uuml;r eine Kategorie. Schlie&szlig;lich besitzt die Tabelle noch ein <b>Ja\/Nein<\/b>-Feld namens <b>HeuteErledigen<\/b>. Warum das, wenn es doch bereits ein Fertigstellungsdatum gibt Nun: Auch wenn eine Aufgabe erst in einer Woche fertiggestellt werden muss, kann man sie ja durchaus schon vorher erledigen. Und da f&uuml;r die Tagesablauf-Verwaltung, zu der die hier vorgestellte Teill&ouml;sung geh&ouml;ren soll, auch eine Liste der f&uuml;r den heutigen Tag vorgesehenen Aufgaben geplant ist, wollen wir solche Aufgaben mit dem Wert <b>True <\/b>f&uuml;r die Eigenschaft <b>HeuteErledigen <\/b>kennzeichnen. Die Tabelle sieht im Entwurf wie in Bild 4 aus.<\/p>\n<p><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2012_02\/AufgabenImTreeview-web-images\/pic001.png\" alt=\"pic001.png\" \/><\/p>\n<p><b><span style=\"color:darkgrey\">Bild 4: Entwurf der Tabelle tblAufgaben<\/span><\/b><\/p>\n<p>Au&szlig;erdem ben&ouml;tigen wir noch eine M&ouml;glichkeit, die hierarchische Abh&auml;ngigkeit einzelner Aufgaben voneinander abzubilden. Dazu verwenden wir eine weitere Tabelle namens <b>tblAufgabenUnteraufgaben<\/b>, die neben einem Prim&auml;rschl&uuml;sselfeld zwei Fremdschl&uuml;sselfelder namens <b>AufgabeID <\/b>und <b>UnteraufgabeID <\/b>besitzt. F&uuml;r das Feld <b>UnteraufgabeID<\/b> wird ein eindeutiger Index festgelegt, damit eine Unteraufgabe nicht gleichzeitig mehreren Aufgaben zugeordnet werden kann (s. Bild 5).<\/p>\n<p><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2012_02\/AufgabenImTreeview-web-images\/pic002.png\" alt=\"pic002.png\" \/><\/p>\n<p><b><span style=\"color:darkgrey\">Bild 5: Entwurf der Tabelle tblAufgabenUnteraufgaben<\/span><\/b><\/p>\n<p>Die Beziehung zwischen den Tabellen <b>tblAufgaben <\/b>und <b>tblAufgabenUnteraufgaben <\/b>legen Sie gleich im Beziehungen-Fenster fest. Da die Tabelle <b>tblAufgaben <\/b>zweimal mit der Tabelle <b>tblAufgabenUnteraufgaben <\/b>verkn&uuml;pft ist, blenden Sie diese zum Herstellen der Verkn&uuml;pfungen ein zweites Mal im Beziehungen-Fenster ein. Die Beziehung zwischen dem Feld <b>AufgabeID <\/b>der Tabelle <b>tblAufgabenUnteraufgaben <\/b>und der Tabelle <b>tblAufgaben <\/b>erhalten Sie, indem Sie das Feld von <b>tblAufgaben <\/b>auf das gleichnamige Feld der Tabelle <b>tblAufgabenUnteraufgaben <\/b>ziehen. Dies k&ouml;nnten Sie in diesem Fall auch andersherum erledigen, aber nicht bei der Verkn&uuml;pfung mit dem Feld <b>UnteraufgabeID<\/b>: Dieses Feld ist mit einem eindeutigen Index versehen. Wenn Sie es von <b>tblAufgabenUnteraufgaben <\/b>auf das Feld <b>AufgabeID <\/b>der Tabelle <b>tblAufgaben <\/b>ziehen, fungiert das Feld <b>AufgabeID <\/b>der Tabelle <b>tblAufgaben <\/b>als Fremdschl&uuml;sselfeld. Bei gleichzeitiger Definition referentieller Integrit&auml;t f&uuml;r diese Beziehung bedeutet dies, dass Sie nur Datens&auml;tze in <b>tblAufgaben <\/b>anlegen k&ouml;nnen, deren Feld <b>AufgabeID <\/b>einen Wert enth&auml;lt, der bereits im Feld <b>UnteraufgabeID <\/b>der Tabelle <b>tblAufgabenUnteraufgaben <\/b>enthalten ist. Anderenfalls erhalten Sie beim Einf&uuml;gen eines Datensatzes in der Tabelle <b>tblAufgaben <\/b>die Fehlermeldung <b>Der Datensatz kann nicht hinzugef&uuml;gt oder ge&auml;ndert werden, da ein Datensatz in der Tabelle &euro;&#154;tblAufgabenUnteraufgaben&euro; mit diesem Datensatz in Beziehung stehen muss<\/b>. Wenn Sie hingegen das Feld <b>AufgabeID <\/b>von der Tabelle <b>tblAufgaben <\/b>auf das Feld <b>UnteraufgabeID <\/b>der Tabelle <b>tblAufgabenUnteraufgaben <\/b>ziehen, funktioniert alles wie gew&uuml;nscht &#8211; Sie k&ouml;nnen dann einfach Datens&auml;tze in der Tabelle <b>tblAufgaben <\/b>anlegen, ohne dass die Tabelle <b>tblAufgabenUnteraufgaben <\/b>davon betroffen ist. Dass das Feld <b>UnteraufgabeID<\/b> mit einem eindeutigen Index versehen ist, sorgt au&szlig;erdem daf&uuml;r, dass die Beziehung als 1:1-Beziehung gekennzeichnet wird (s. Bild 6).<\/p>\n<p><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2012_02\/AufgabenImTreeview-web-images\/pic003.png\" alt=\"pic003.png\" \/><\/p>\n<p><b><span style=\"color:darkgrey\">Bild 6: Datenmodell der Aufgabenverwaltung<\/span><\/b><\/p>\n<p><b>Aufbau der L&ouml;sung<\/b><\/p>\n<p>Die Aufgabenverwaltung per TreeView soll haupts&auml;chlich das Hinzuf&uuml;gen und L&ouml;schen von Aufgaben &uuml;ber das Kontextmen&uuml; des TreeView-Steuerelements erm&ouml;glichen. Wie soll jedoch sichergestellt werden, dass &uuml;berhaupt ein Element im TreeView-Steuerelement vorhanden ist, das ein Kontextmen&uuml; anbietet Man k&ouml;nnte nun alle Rootaufgaben, also solche Aufgaben, die keine &uuml;bergeordneten Aufgaben besitzen, in der ersten Ebene des TreeViews anzeigen. Allerdings fehlt dann immer noch ein Element, mit dessen Kontextmen&uuml; Sie ein Rootelement anlegen k&ouml;nnen. Der Einfachheit halber legen wir daher im TreeView ein einziges Root-Element an, das alle weiteren Rootaufgaben und auch einen Kontextmen&uuml;eintrag zum Anlegen von Rootaufgaben enth&auml;lt. Auf diese Weise k&ouml;nnen Sie auch eine leere Datenbank mit diesem Formular weitergeben und dem Benutzer so die M&ouml;glichkeit geben, seine Aufgaben-Hierarchie von Grund auf neu zu gestalten.<\/p>\n<p>&auml;hnliches gilt f&uuml;r die Kategorien, die der Benutzer f&uuml;r die Aufgaben ausw&auml;hlen soll. Was geschieht, wenn der Benutzer das Aufgaben-Detailformular &ouml;ffnet, um eine neue Aufgabe anzulegen, aber noch keine Kategorien vorhanden sind Grunds&auml;tzlich sollte bereits vor dem &Ouml;ffnen dieses Dialoges eine entsprechende Meldung erscheinen und den Benutzer auffordern, zun&auml;chst mindestens eine Kategorie anzulegen.<\/p>\n<p>Alternativ richten Sie das Kategorien-Auswahlsteuerelement im Aufgaben-Detailformular so ein, dass es die direkte Eingabe von Kategorien erlaubt und diese gleich als neue Datens&auml;tze der Tabelle <b>tblKategorien <\/b>speichert. Rechts neben dem Kombinationsfeld lie&szlig;e sich dann gut eine Schaltfl&auml;che unterbringen, mit welcher der Benutzer den Dialog zum Verwalten der Kategorien &ouml;ffnen kann.<\/p>\n<p><b>TreeView-Steuerelement anlegen<\/b><\/p>\n<p>Das TreeView-Steuerelement f&uuml;gen Sie &uuml;ber den Eintrag <b>ActiveX-Steuerelemente <\/b>der Toolbox mit den Steuerelementen zu einem neuen, leeren Formular hinzu. Ziehen Sie das Steuerelement auf die gew&uuml;nschte Gr&ouml;&szlig;e und nennen Sie es <b>ctlTreeView<\/b>.<\/p>\n<p><!--30percent--><\/p>\n<p>Das TreeView-Steuerelement soll per VBA-Code mit den reflexiven Daten der beiden Tabellen <b>tblAufgaben <\/b>und <b>tblAufgabenUnteraufgaben <\/b>beziehungsweise mit den darauf aufbauenden Tabellen gef&uuml;llt werden. Au&szlig;erdem wollen wir sp&auml;ter einige Features wie beispielsweise Kontextmen&uuml;eintr&auml;ge zum Anlegen und Entfernen der Aufgaben im TreeView hinzuf&uuml;gen.<\/p>\n<p>Damit diese Kontextmen&uuml;s angezeigt werden, m&uuml;ssen beim Rechtsklick auf die entsprechenden Elemente Ereignisse ausgel&ouml;st werden. Damit wir diese zum Klassenmodul des Formulars hinzuf&uuml;gen k&ouml;nnen, deklarieren wir im Kopf des Moduls die folgende Objektvariable:<\/p>\n<pre>Dim WithEvents objTreeView As MSComctlLib.TreeView<\/pre>\n<p>Das Schl&uuml;sselwort <b>WithEvents <\/b>sorgt f&uuml;r die Bereitstellung der Ereignisprozeduren &uuml;ber die beiden Kombinationsfelder im VBA-Fenster mit dem Klassenmodul des Formulars.<\/p>\n<p>Bevor wir uns um diese Ereignisse k&uuml;mmern, wollen wir die Objektvariable zun&auml;chst mit einem Verweis auf das TreeView-Steuerelement <b>ctlTreeView<\/b> f&uuml;llen und dann die Aufgaben darin anzeigen.<\/p>\n<p><b>TreeView mit Aufgaben f&uuml;llen<\/b><\/p>\n<p>Das TreeView-Steuerelement soll ein Root-Steuerelement namens <b>a0 <\/b>mit der Beschriftung <b>Aufgaben <\/b>haben. Dieses Element legen Sie gleich beim Einrichten des TreeView-Steuerelements in der Ereignisprozedur an, die durch das Ereignis <b>Beim Laden <\/b>des Formulars ausgel&ouml;st wird.<\/p>\n<p>Diese Prozedur f&uuml;llt zun&auml;chst die Objektvariable <b>objTreeView <\/b>mit einem Verweis auf das TreeView-Steuerelement (s. <span class=\"verweis-ohneumbruch\"><a href=\"#anker-49-anchor\">Listing 1<\/a><\/span>). Danach nimmt es einige Einstellungen vor, die Sie auch direkt im Eigenschaftsfenster des TreeView-Steuerelements im Formularentwurf vornehmen k&ouml;nnen. Wenn Sie jedoch &ouml;fter mal TreeView-Steuerelemente anlegen, m&ouml;chten Sie vielleicht auf die Schnelle die Eigenschaften bew&auml;hrter Modelle &uuml;bernehmen &#8211; und das geht am schnellsten, wenn Sie einfach ein paar Zeilen Code &uuml;bertragen, in diesem Fall die Anweisungen mit der Zuweisung der entsprechenden Eigenschaftswerte.<\/p>\n<p class=\"listingueberschrift\">Listing 1: Einrichten des TreeView-Steuerelements beim Laden des Formulars<\/p>\n<pre>Private Sub Form_Load()\r\n    Dim objNode As MSComctlLib.Node\r\n    Set objTreeView = Me!ctlTreeView.Object\r\n    With objTreeView\r\n        .Appearance = ccFlat\r\n        .LineStyle = tvwTreeLines\r\n        .Style = tvwTreelinesPlusMinusPictureText\r\n        .OLEDragMode = ccOLEDragAutomatic\r\n        .OLEDropMode = ccOLEDropManual\r\n        .Font.Name = \"Calibri\"\r\n        .Font.Size = 10\r\n        Set objNode = .Nodes.Add(, , \"a0\", \"Aufgaben\")\r\n        objNode.Expanded = True\r\n        FillTree\r\n    End With\r\nEnd Sub<\/pre>\n<p>Der Root-Knoten mit der Beschriftung <b>Aufgaben <\/b>und dem Key <b>a0 <\/b>wird nach dem Einstellen der Eigenschaften zum TreeView-Steuerelement hinzugef&uuml;gt. Au&szlig;erdem wird dessen Eigenschaft <b>Expanded <\/b>gleich auf den Wert <b>True <\/b>eingestellt, damit darunter enthaltene Aufgaben gleich angezeigt werden.<\/p>\n<p><b>Einlesen der ersten Aufgaben-Ebene<\/b><\/p>\n<p>Die letzte Anweisung der Prozedur <b>Form_Load <\/b>ruft eine weitere Prozedur namens <b>FillTree <\/b>auf. Diese f&uuml;llt genau genommen gar nicht den kompletten Baum, sondern k&uuml;mmert sich nur um die erste Ebene. Woher aber wissen wir, welche der Aufgaben aus der Tabelle <b>tblAufgaben <\/b>dort landen sollen, wo doch die Informationen &uuml;ber die Hierarchie in der Tabelle <b>tblAufgabenUnteraufgaben <\/b>gespeichert sind Dort sollen aber doch gerade &uuml;ber die Aufgaben ohne &uuml;bergeordnete Elemente keine Informationen enthalten sein, sondern andersherum Kein Problem: Wir verkn&uuml;pfen die beiden Tabellen trotzdem einfach in einer Abfrage, und zwar &uuml;ber das Feld <b>UnteraufgabeID <\/b>der Tabelle <b>tblAufgabenUnteraufgaben<\/b>.<\/p>\n<p>Au&szlig;erdem legen wir in den Beziehungseigenschaften f&uuml;r diese Beziehung fest, dass die Beziehung alle Datens&auml;tze der Tabelle <b>tblAufgaben <\/b>liefern soll, aber nur diejenigen Datens&auml;tze der Tabelle <b>tblAufgabenUnteraufgaben<\/b>, f&uuml;r die auch ein verkn&uuml;pfter Datensatz vorhanden ist. Dies liefert dann manche Datens&auml;tze der Tabelle <b>tblAufgaben <\/b>mit einem verkn&uuml;pfen Datensatz der Tabelle <b>tblAufgabenUnteraufgaben <\/b>und manche ohne weitere Daten aus <b>tblAufgabenUnteraufgaben<\/b>. Letztere sind diejenigen, die wir suchen: Und mit einem Kriterium, das alle Datens&auml;tze liefert, f&uuml;r die das Feld <b>AufgabeID <\/b>der Tabelle <b>tblAufgabenUnteraufgaben<\/b> den Wert <b>NULL <\/b>hat, erhalten wir schlie&szlig;lich alle Aufgaben ohne &uuml;bergeordnete Aufgaben. Die Abfrage sieht im Entwurf wie in Bild 7 aus.<\/p>\n<p><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2012_02\/AufgabenImTreeview-web-images\/pic005.png\" alt=\"pic005.png\" \/><\/p>\n<p><b><span style=\"color:darkgrey\">Bild 7: Abfrage zur Ermittlung der obersten Ebene von Aufgaben<\/span><\/b><\/p>\n<p>Diese Abfrage hei&szlig;t <b>qryRootAufgaben<\/b> und dient als Datenherkunft f&uuml;r eine Datensatzgruppe namens <b>rst<\/b>, die in der Prozedur <b>FillTree <\/b>ge&ouml;ffnet wird (s. <span class=\"verweis-ohneumbruch\"><a href=\"#anker-61-anchor\">Listing 2<\/a><\/span>). Die Prozedur durchl&auml;uft in einer <b>Do While<\/b>-Schleife alle Datens&auml;tze, die diese Abfrage liefert, und legt f&uuml;r jeden Datensatz ein neues Element unterhalb des Elements <b>Aufgaben <\/b>(mit dem <b>Key<\/b>-Wert <b>a0<\/b>) an.<\/p>\n<p class=\"listingueberschrift\">Listing 2: Die Prozedur FillTree legt die erste Ebene der Aufgaben-Hierarchie an.<\/p>\n<pre>Private Sub FillTree()\r\n    Dim db As DAO.Database\r\n    Dim rst As DAO.Recordset\r\n    Dim objNode As MSComctlLib.Node\r\n    Set db = CurrentDb\r\n    Set rst = db.OpenRecordset(\"qryRootAufgaben\", dbOpenDynaset)\r\n    Do While Not rst.EOF\r\n        Set objNode = objTreeView.Nodes.Add(\"a0\", tvwChild, \"a\" &amp; rst!AufgabeID, rst!Aufgabe)\r\n        objNode.Expanded = rst!Aufgeklappt\r\n        FillTreeRek rst!AufgabeID\r\n        rst.MoveNext\r\n    Loop\r\nEnd Sub<\/pre>\n<p>Die <b>Add<\/b>-Methode der <b>Nodes<\/b>-Auflistung verwendet als ersten Parameter den Wert <b>a0<\/b>, als zweiten <b>tvwChild<\/b>. Das bedeutet, dass das neue Element als Kind-Element des Elements mit dem <b>Key<\/b>-Wert <b>a0 <\/b>angelegt wird.<\/p>\n<p>Die Tabelle <b>tblAufgaben<\/b> enth&auml;lt auch noch ein Feld namens <b>Aufgeklappt<\/b>, das speichert, ob eine Aufgabe zuletzt ihre Unteraufgaben angezeigt hat oder nicht. Abh&auml;ngig vom Wert des Feldes <b>Aufgeklappt <\/b>der Datenherkunft stellt die Prozedur die Eigenschaft <b>Expanded <\/b>des neuen Elements ein. Schlie&szlig;lich ruft die Prozedur f&uuml;r jeden Datensatz einmal die Prozedur <b>FillTreeRek <\/b>auf, die f&uuml;r das F&uuml;llen der &uuml;brigen Aufgaben-Ebenen zust&auml;ndig ist.<\/p>\n<p><b>F&uuml;llen der untergeordneten Aufgaben<\/b><\/p>\n<p>Die unteren Ebenen f&uuml;llt die Prozedur <b>FillTreeRek<\/b>, die sich f&uuml;r jede weitere Ebene selbst aufruft. Die wesentlichen Unterschiede zur Prozedur sind der Parameter, der beim Aufrufen &uuml;bergeben wird und die leicht ge&auml;nderte Datenherkunft beim Durchlaufen der untergeordneten Elemente.<\/p>\n<p>Die Datenherkunft bezieht sich diesmal explizit auf diejenigen verkn&uuml;pften Datens&auml;tze der Tabellen <b>tblAufgaben <\/b>und <b>tblAufgabenUnteraufgaben<\/b>, bei denen das Feld <b>AufgabeID <\/b>der Tabelle <b>tblAufgabenUnteraufgaben <\/b>dem Wert der Variablen <b>lngParentID <\/b>entspricht. Und dieser entspricht wiederum der Variablen, die beim Aufruf der rekursiven Funktion &uuml;bergeben wurde und den Wert des Feldes <b>AufgabeID <\/b>der Aufgabe enth&auml;lt, unter der die folgenden Aufgaben angelegt werden sollen. Die Abfrage <b>qryUnteraufgaben<\/b>, die als Datenherkunft zum Anlegen der Unteraufgaben dient, sieht wie in Bild 8 aus.<\/p>\n<p><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2012_02\/AufgabenImTreeview-web-images\/pic004.png\" alt=\"pic004.png\" \/><\/p>\n<p><b><span style=\"color:darkgrey\">Bild 8: Abfrage zur Ermittlung der untergeordneten Aufgaben<\/span><\/b><\/p>\n<p>Die Prozedur <b>FillTreeRek <\/b>finden Sie in <span class=\"verweis-ohneumbruch\"><a href=\"#anker-62-anchor\">Listing 3<\/a><\/span>.<\/p>\n<p class=\"listingueberschrift\">Listing 3: Die Prozedur FillTreeRek f&uuml;llt die &uuml;brigen Aufgaben-Ebenen.<\/p>\n<pre>Private Sub FillTreeRek(lngParentID As Long)\r\n    Dim db As DAO.Database\r\n    Dim rst As DAO.Recordset\r\n    Dim objNode As MSComctlLib.Node\r\n    Set db = CurrentDb\r\n    Set rst = db.OpenRecordset(\"SELECT * FROM qryUnteraufgaben WHERE ParentaufgabeID = \" &amp; lngParentID, dbOpenDynaset)\r\n    Do While Not rst.EOF\r\n        Set objNode = objTreeView.Nodes.Add(\"a\" &amp; lngParentID, tvwChild, \"a\" &amp; rst!AufgabeID, rst!Aufgabe)\r\n        objNode.Expanded = rst!Aufgeklappt\r\n        FillTreeRek rst!AufgabeID\r\n        rst.MoveNext\r\n    Loop\r\nEnd Sub<\/pre>\n<p>Nach dem Aufruf dieser Prozeduren beim &Ouml;ffnen des Formulars ist das TreeView mit allen in den Tabellen enthaltenen Elementen gef&uuml;llt.<\/p>\n<p><b>Kontextmen&uuml;s<\/b><\/p>\n<p>Damit Sie Ihre erste Aufgabe im TreeView anlegen k&ouml;nnen, legen wir nun zun&auml;chst das daf&uuml;r notwendige Kontextmen&uuml; an beziehungsweise erstellen den Code, der dieses beim Rechtsklick auf das entsprechende Node-Element &ouml;ffnet.<\/p>\n<p>Wenn Sie mit Kontextmen&uuml;s arbeiten, f&uuml;gen Sie dem VBA-Projekt zuvor einen Verweis auf die Bibliothek <b>Microsoft Office x.0 Object Library <\/b>hinzu.<\/p>\n<p>Anschlie&szlig;end legen Sie eine Ereignisprozedur an, die beim Dr&uuml;cken der Maustaste im TreeView-Steuerelement ausgel&ouml;st wird (s. <span class=\"verweis-ohneumbruch\"><a href=\"#anker-64-anchor\">Listing 4<\/a><\/span>). Nun m&ouml;chten Sie nicht auf Mausklicks im Allgemeinen reagieren, sondern nur auf einen Klick auf die rechte Maustaste &#8211; und das auch nur, wenn der Benutzer dabei auch ein Element getroffen hat. Die Vorbereitung zur Pr&uuml;fung des betroffenen Elements f&uuml;hrt die Prozedur zuerst durch: Sie ermittelt mit der <b>HitTest<\/b>-Methode das angeklickte Element und tr&auml;gt einen Verweis darauf in die Objektvariable <b>objNode <\/b>ein.<\/p>\n<p class=\"listingueberschrift\">Listing 4: Anzeigen des Kontextmen&uuml;s bei Rechtsklick auf ein Aufgaben-Element<\/p>\n<pre>Private Sub objTreeView_MouseDown(ByVal Button As Integer, ByVal Shift As Integer, _\r\n        ByVal X As stdole.OLE_XPOS_PIXELS, ByVal Y As stdole.OLE_YPOS_PIXELS)\r\n    Dim objNode As MSComctlLib.Node\r\n    Dim cbr As CommandBar\r\n    Dim cbb As CommandBarButton\r\n    Dim lngAufgabeID As Long\r\n    Set objNode = objTreeView.HitTest(X, Y)\r\n    objTreeView.SelectedItem = objNode\r\n    Select Case Button\r\n        Case 2 ''rechte Maustaste\r\n            If Not objNode Is Nothing Then\r\n                lngAufgabeID = Mid(objNode.Key, 2)\r\n                On Error Resume Next\r\n                CommandBars(\"cbrAufgaben&euro;).Delete\r\n                On Error GoTo 0\r\n                Set cbr = CommandBars.Add(\"cbrAufgaben&euro;, msoBarPopup, , True)\r\n                Set cbb = cbr.Controls.Add(msoControlButton)\r\n                cbb.Caption = \"Neue Aufgabe&euro;\r\n                cbb.OnAction = \"=AufgabeErstellen(\" &amp; lngAufgabeID &amp; \")&euro;\r\n                If lngAufgabeID &gt; 0 Then\r\n                    Set cbb = cbr.Controls.Add(msoControlButton)\r\n                    cbb.Caption = \"Aufgabe l&ouml;schen&euro;\r\n                    cbb.OnAction = \"=AufgabeLoeschen(\" &amp; lngAufgabeID &amp; \")&euro;\r\n                End If\r\n                cbr.ShowPopup\r\n            End If\r\n    End Select\r\nEnd Sub<\/pre>\n<p>Wurde ein Element getroffen, wird dieses mit der Eigenschaft <b>SelectedItem <\/b>als ausgew&auml;hltes Element markiert (Letzteres ist gar nicht f&uuml;r die Anzeige des Kontextmen&uuml;s wichtig, sondern f&uuml;r das Drag and Drop, was sp&auml;ter beschrieben wird).<\/p>\n<p>Erst dann pr&uuml;ft eine <b>Select Case<\/b>-Bedingung, ob der Benutzer &uuml;berhaupt die rechte Maustaste angeklickt hat. Auskunft dar&uuml;ber gibt der Parameter <b>Button<\/b>, der in diesem Fall den Wert <b>2 <\/b>aufweisen sollte. Ist dies der Fall, pr&uuml;ft die Prozedur, ob <b>objNode <\/b>gef&uuml;llt, und der Benutzer somit nicht in Niemandsland geklickt hat.<\/p>\n<p>Falls nicht, geht es los: Aus der <b>Key<\/b>-Eigenschaft (<b>a0<\/b> f&uuml;r das Root-Element, <b>a <\/b>+ AufgabeID f&uuml;r die &uuml;brigen Elemente) ermittelt die Prozedur die ID der angeklickten Aufgabe und speichert diese in <b>lngAufgabeID<\/b>. Ein eventuell noch vom vorherigen Rechtsklick vorhandenes Kontextmen&uuml; namens <b>cbrAufgaben <\/b>wird ohne R&uuml;cksicht auf Verluste gel&ouml;scht &#8211; und gleich neu erstellt, und zwar per Parameter <b>msoBarPopup <\/b>als Kontextmen&uuml; und nicht etwa als Men&uuml;- oder Symbolleiste, die in modernen Access-Versionen ohnehin nicht mehr angezeigt werden.<\/p>\n<p>Das Kontextmen&uuml; wird dann in jedem Fall um den Befehl <b>Neue Aufgabe <\/b>angereichert, f&uuml;r den die Prozedur einen Ausdruck wie <b>=AufgabeErstellen(123) <\/b>f&uuml;r die Eigenschaft <b>onAction <\/b>festlegt. Dabei steht <b>AufgabeErstellen <\/b>f&uuml;r die Funktion, die beim Ausw&auml;hlen des Kontextmen&uuml;eintrags ausgew&auml;hlt werden soll, und <b>123 <\/b>f&uuml;r die ID der angeklickten Aufgabe, unterhalb der eine neue Aufgabe eingef&uuml;gt werden soll.<\/p>\n<p>Nicht in jedem Fall, sondern nur f&uuml;r alle Elemente au&szlig;er dem Root-Element (gekennzeichnet durch den <b>Key<\/b>-Wert <b>a0 <\/b>und somit den Wert <b>0 <\/b>f&uuml;r <b>lngAufgabeID<\/b>) wird dem Kontextmen&uuml; auch noch ein Eintrag zum L&ouml;schen des jeweiligen Elements spendiert.<\/p>\n<p>Dieser Eintrag ruft die Funktion <b>AufgabeLoeschen <\/b>mit der ID der zu l&ouml;schenden Aufgabe als Parameter auf.<\/p>\n<p>Wenn Sie das Formular nun erneut in der Formularansicht &ouml;ffnen, k&ouml;nnen Sie das Kontextmen&uuml; bereits anzeigen, ein Klick auf die Befehle bewirkt jedoch noch nichts.<\/p>\n<p><b>Neue Aufgabe erstellen<\/b><\/p>\n<p>Dies &auml;ndert sich erst, wenn Sie die Funktion <b>AufgabeErstellen<\/b> aus <span class=\"verweis-ohneumbruch\"><a href=\"#anker-65-anchor\">Listing 5<\/a><\/span> in das Klassenmodul des Formulars einf&uuml;gen.<\/p>\n<p class=\"listingueberschrift\">Listing 5: &Ouml;ffnen des Formulars frmAufgabeDetails nach Bet&auml;tigen des Kontextmen&uuml;s<\/p>\n<pre>Public Function AufgabeErstellen(lngAufgabeID As Long)\r\n    Dim lngAufgabeNeuID As Long\r\n    Dim strAufgabeNeu As String\r\n    DoCmd.OpenForm &quot;frmAufgabeDetails&quot;, WindowMode:=acDialog, DataMode:=acFormAdd, OpenArgs:=lngAufgabeID\r\n    If IstFormularGeoeffnet(&quot;frmAufgabeDetails&quot;) Then\r\n        lngAufgabeNeuID = Forms!frmAufgabeDetails.AufgabeID\r\n        strAufgabeNeu = Forms!frmAufgabeDetails.Aufgabe\r\n        DoCmd.Close acForm, &quot;frmAufgabeDetails&quot;\r\n        CurrentDb.Execute &quot;INSERT INTO tblAufgabenUnteraufgaben(AufgabeID, UnteraufgabeID) VALUES(&quot; &amp; lngAufgabeID &amp; &quot;, &quot; &amp; lngAufgabeNeuID &amp; &quot;)&quot;, dbFailOnError\r\n        objTreeView.Nodes(&quot;a&quot; &amp; lngAufgabeID).Expanded = True\r\n        objTreeView.Nodes.Add &quot;a&quot; &amp; lngAufgabeID, tvwChild, &quot;a&quot; &amp; lngAufgabeNeuID, strAufgabeNeu\r\n    End If\r\nEnd Function<\/pre>\n<p>Die Funktion nimmt denPrim&auml;rschl&uuml;sselwert der &uuml;bergeordneten Funktion als Parameter in Empfang und &ouml;ffnet gleich mit der ersten Anweisung das Formular <b>frmAufgabeDetails<\/b>. Wichtig ist, dass die ID der Parent-Aufgabe hier gleich als &Ouml;ffnungsargument an das Formular weitergereicht wird. Warum das Nun, damit erhalten Sie ein klein wenig Komfort: Eine untergeordnete Aufgabe wird wahrscheinlich meist die gleiche Aufgabenkategorie wie die &uuml;bergeordnete Aufgabe besitzen. Daher liest das Formular <b>frmAufgabeDetails <\/b>die ID des &uuml;bergeordneten Elements aus dem &Ouml;ffnungsparameter aus, ermittelt per <b>DLookup <\/b>die Kategorie der Aufgabe mit dieser ID und tr&auml;gt diese als Standardwert f&uuml;r das Kombinationsfeld <b>cboKategorieID <\/b>ein:<\/p>\n<pre>Private Sub Form_Load()\r\n    Dim lngParentID As Long\r\n    Dim lngKategorieID As Long\r\n    If Not IsNull(Me.OpenArgs) Then\r\n        lngParentID = Me.OpenArgs\r\n        lngKategorieID = Nz(DLookup(&quot;KategorieID&quot;, &quot;tblAufgaben&quot;, &quot;AufgabeID = &quot; &amp; lngParentID))\r\n        Me!cboKategorieID.DefaultValue = lngKategorieID\r\n    End If\r\nEnd Sub<\/pre>\n<p>Nach dem Eintragen der Eigenschaften der neuen Aufgabe schlie&szlig;t man das Formular mit der <b>OK<\/b>-Taste, was im Hintergrund jedoch nur zum Ausblenden f&uuml;hrt:<\/p>\n<pre>Private Sub cmdOK_Click()\r\n    Me.Visible = False\r\nEnd Sub<\/pre>\n<p>Dies ist f&uuml;r die folgenden Schritte n&ouml;tig: Zun&auml;chst soll das neue Aufgaben-Element gleich nach dem Schlie&szlig;en im TreeView angelegt werden. Dazu liest die Prozedur aus dem noch ge&ouml;ffneten Formular die <b>AufgabeID <\/b>und die Bezeichnung der Aufgabe aus.<\/p>\n<p>Danach, und die Reihenfolge ist sehr wichtig, wird zuerst das Formular geschlossen. Der Grund sind die folgenden Anweisungen: Die erste tr&auml;gt n&auml;mlich einen neuen Datensatz in die Tabelle <b>tblAufgabenUnteraufgaben <\/b>ein, um die neue Aufgabe in die Hierarchie einzugliedern.<\/p>\n<p>Dies gelingt aber nur ohne Fehler, wenn beide mit den Fremdschl&uuml;sselfeldern <b>AufgabeID <\/b>und <b>UnteraufgabeID <\/b>referenzierten Datens&auml;tze bereits in der Tabelle <b>tblAufgaben <\/b>vorhanden sind. Und gerade der im Formular angelegte Datensatz wird erst mit dem Schlie&szlig;en des Formulars gespeichert.<\/p>\n<p>Danach stellt die Prozedur noch die Eigenschaft <b>Expanded <\/b>des &uuml;bergeordneten Elements auf <b>True <\/b>ein, damit die neue Aufgabe auch gleich sichtbar ist, und legt diese mit der folgenden Anweisung auch gleich an.<\/p>\n<p><b>Aufgaben l&ouml;schen<\/b><\/p>\n<p>Das L&ouml;schen einer Aufgabe erfolgt &uuml;ber die Funktion <b>AufgabeLoeschen<\/b>, die ebenfalls im Klassenmodul des Formulars <b>frmAufgabenbaum <\/b>Platz findet (s. <span class=\"verweis-ohneumbruch\"><a href=\"#anker-66-anchor\">Listing 6<\/a><\/span>). Die Funktion pr&uuml;ft zun&auml;chst, ob die Aufgabe noch untergeordnete Aufgaben enth&auml;lt. Dies wirkt sich nicht weiter aus, als dass die Funktion dann einen anderen Text im Meldungsfenster zur Best&auml;tigung des Vorgangs anzeigt.<\/p>\n<p class=\"listingueberschrift\">Listing 6: L&ouml;schen einer Aufgabe per Kontextmen&uuml;<\/p>\n<pre>Public Function AufgabeLoeschen(lngAufgabeID As Long)\r\n    Dim bolLoeschen As Boolean\r\n    If IsNull(DLookup(&quot;AufgabeID&quot;, &quot;qryUnteraufgaben&quot;, &quot;ParentaufgabeID = &quot; &amp; lngAufgabeID)) Then\r\n        bolLoeschen = MsgBox(&quot;Aufgabe wirklich l&ouml;schen&quot;, vbOKCancel + vbExclamation, &quot;Aufgabe l&ouml;schen&quot;) = vbOK\r\n    Else\r\n        bolLoeschen = MsgBox(&quot;Die Aufgabe enth&auml;lt Unteraufgaben. Trotzdem l&ouml;schen&quot;, vbOKCancel + vbExclamation, &quot;Aufgabe l&ouml;schen&quot;) = vbOK\r\n    End If\r\n    If bolLoeschen = True Then\r\n        CurrentDb.Execute &quot;DELETE FROM tblAufgaben WHERE AufgabeID = &quot; &amp; lngAufgabeID, dbFailOnError\r\n        objTreeView.Nodes.Remove &quot;a&quot; &amp; lngAufgabeID\r\n    End If\r\nEnd Function<\/pre>\n<p>Falls der Benutzer die L&ouml;schen-Meldung bejaht, wird die Variable <b>bolLoeschen <\/b>auf <b>True <\/b>eingestellt. Dies f&uuml;hrt in der Folge dazu, dass die Funktion zun&auml;chst mit einer <b>DELETE<\/b>-Anweisung den betroffnen Datensatz l&ouml;scht, und mit diesem gegebenenfalls auch noch untergeordnete Datens&auml;tze.<\/p>\n<p><b>Zusammenfassung und Ausblick<\/b><\/p>\n<p>Die hier vorgestellte Teill&ouml;sung k&ouml;nnen Sie in eigene Datenbanken integrieren oder aber bis zur n&auml;chsten Ausgabe warten, wo wie eine Tagesablauf-Verwaltung vorstellen. Diese zeigt auch, wie die Drag-and-Drop-Features funktionieren.<\/p>\n<p>Einige Elemente der Teill&ouml;sung wurden hier nicht im Detail beschrieben. Dazu geh&ouml;ren das Anzeigen einer bestehenden Aufgabe per Doppelklick auf einen der Eintr&auml;ge im TreeView-Steuerelement oder auch die Details zu den einzelnen Formularen zum Bearbeiten von Aufgaben et cetera. F&uuml;r n&auml;here Informationen hierzu konsultieren Sie einfach den Entwurf der entsprechenden Elemente in der Beispieldatenbank.<\/p>\n<p><a id=\"anker-57-anchor\" name=\"anker-57-anchor\" \/><br \/>\n<a id=\"anker-58-anchor\" name=\"anker-58-anchor\" \/><br \/>\n<a id=\"anker-59-anchor\" name=\"anker-59-anchor\" \/><br \/>\n<a id=\"anker-48-anchor\" name=\"anker-48-anchor\" \/><br \/>\n<a id=\"anker-50-anchor\" name=\"anker-50-anchor\" \/><br \/>\n<a id=\"anker-53-anchor\" name=\"anker-53-anchor\" \/><br \/>\n<a id=\"anker-60-anchor\" name=\"anker-60-anchor\" \/><br \/>\n<a id=\"anker-63-anchor\" name=\"anker-63-anchor\" \/><\/p>\n<h3>Downloads zu diesem Beitrag<\/h3>\n<p>Enthaltene Beispieldateien:<\/p>\n<p>TagesablaufVerwalten.mdb<\/p>\n<p>TagesablaufVerwalten_2003UndAelter.mdb<\/p>\n<p><a href=\"..\/fileadmin\/beispiele\/{A86DE0F4-764C-4AEB-9282-E239D6C09924}\/aiu_826.zip\">Download<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Aufgaben lassen sich normalerweise sch&ouml;n in einer Liste darstellen. Manche Aufgaben sind aber derart umfangreich, dass man sie lieber in kleine H&auml;ppchen aufteilt und diese nacheinander erledigt. Also stellen wir dies in hierarchischer Form im TreeView dar. Zusammen mit der M&ouml;glichkeit, Aufgaben per Kontextmen&uuml; anzulegen und zu l&ouml;schen, Unteraufgaben zu verschieben oder erledigte Aufgaben abzuhaken, wird eine richtige kleine L&ouml;sung daraus. Es kommt aber noch besser: Das Ergebnis dieses Beitrags verwenden wir in unserer L&ouml;sung &#8222;Tagesablauf verwalten&#8220; weiter.<\/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":[66022012,662012,44000023],"tags":[],"class_list":["post-55000826","post","type-post","status-publish","format-standard","hentry","category-66022012","category-662012","category-Mit_Formularen_arbeiten"],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v20.9 (Yoast SEO v27.4) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>Aufgaben per TreeView verwalten - 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\/Aufgaben_per_TreeView_verwalten\/\" \/>\n<meta property=\"og:locale\" content=\"de_DE\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Aufgaben per TreeView verwalten\" \/>\n<meta property=\"og:description\" content=\"Aufgaben lassen sich normalerweise sch&ouml;n in einer Liste darstellen. Manche Aufgaben sind aber derart umfangreich, dass man sie lieber in kleine H&auml;ppchen aufteilt und diese nacheinander erledigt. Also stellen wir dies in hierarchischer Form im TreeView dar. Zusammen mit der M&ouml;glichkeit, Aufgaben per Kontextmen&uuml; anzulegen und zu l&ouml;schen, Unteraufgaben zu verschieben oder erledigte Aufgaben abzuhaken, wird eine richtige kleine L&ouml;sung daraus. Es kommt aber noch besser: Das Ergebnis dieses Beitrags verwenden wir in unserer L&ouml;sung &quot;Tagesablauf verwalten&quot; weiter.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/access-im-unternehmen.de\/Aufgaben_per_TreeView_verwalten\/\" \/>\n<meta property=\"og:site_name\" content=\"Access im Unternehmen\" \/>\n<meta property=\"article:published_time\" content=\"2020-05-22T21:53:36+00:00\" \/>\n<meta property=\"og:image\" content=\"http:\/\/vg05.met.vgwort.de\/na\/bddeac028a0845daa293111afcf29472\" \/>\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=\"20\u00a0Minuten\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Aufgaben_per_TreeView_verwalten\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Aufgaben_per_TreeView_verwalten\\\/\"},\"author\":{\"name\":\"Andr\u00e9 Minhorst\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#\\\/schema\\\/person\\\/13395c4bcd7d7963efe33be9c584d93f\"},\"headline\":\"Aufgaben per TreeView verwalten\",\"datePublished\":\"2020-05-22T21:53:36+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Aufgaben_per_TreeView_verwalten\\\/\"},\"wordCount\":3496,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Aufgaben_per_TreeView_verwalten\\\/#primaryimage\"},\"thumbnailUrl\":\"http:\\\/\\\/vg05.met.vgwort.de\\\/na\\\/bddeac028a0845daa293111afcf29472\",\"articleSection\":[\"2\\\/2012\",\"2012\",\"Mit Formularen arbeiten\"],\"inLanguage\":\"de\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/access-im-unternehmen.de\\\/Aufgaben_per_TreeView_verwalten\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Aufgaben_per_TreeView_verwalten\\\/\",\"url\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Aufgaben_per_TreeView_verwalten\\\/\",\"name\":\"Aufgaben per TreeView verwalten - Access im Unternehmen\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Aufgaben_per_TreeView_verwalten\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Aufgaben_per_TreeView_verwalten\\\/#primaryimage\"},\"thumbnailUrl\":\"http:\\\/\\\/vg05.met.vgwort.de\\\/na\\\/bddeac028a0845daa293111afcf29472\",\"datePublished\":\"2020-05-22T21:53:36+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Aufgaben_per_TreeView_verwalten\\\/#breadcrumb\"},\"inLanguage\":\"de\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/access-im-unternehmen.de\\\/Aufgaben_per_TreeView_verwalten\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"de\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Aufgaben_per_TreeView_verwalten\\\/#primaryimage\",\"url\":\"http:\\\/\\\/vg05.met.vgwort.de\\\/na\\\/bddeac028a0845daa293111afcf29472\",\"contentUrl\":\"http:\\\/\\\/vg05.met.vgwort.de\\\/na\\\/bddeac028a0845daa293111afcf29472\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Aufgaben_per_TreeView_verwalten\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/access-im-unternehmen.de\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Aufgaben per TreeView verwalten\"}]},{\"@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":"Aufgaben per TreeView verwalten - 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\/Aufgaben_per_TreeView_verwalten\/","og_locale":"de_DE","og_type":"article","og_title":"Aufgaben per TreeView verwalten","og_description":"Aufgaben lassen sich normalerweise sch&ouml;n in einer Liste darstellen. Manche Aufgaben sind aber derart umfangreich, dass man sie lieber in kleine H&auml;ppchen aufteilt und diese nacheinander erledigt. Also stellen wir dies in hierarchischer Form im TreeView dar. Zusammen mit der M&ouml;glichkeit, Aufgaben per Kontextmen&uuml; anzulegen und zu l&ouml;schen, Unteraufgaben zu verschieben oder erledigte Aufgaben abzuhaken, wird eine richtige kleine L&ouml;sung daraus. Es kommt aber noch besser: Das Ergebnis dieses Beitrags verwenden wir in unserer L&ouml;sung \"Tagesablauf verwalten\" weiter.","og_url":"https:\/\/access-im-unternehmen.de\/Aufgaben_per_TreeView_verwalten\/","og_site_name":"Access im Unternehmen","article_published_time":"2020-05-22T21:53:36+00:00","og_image":[{"url":"http:\/\/vg05.met.vgwort.de\/na\/bddeac028a0845daa293111afcf29472","type":"","width":"","height":""}],"author":"Andr\u00e9 Minhorst","twitter_card":"summary_large_image","twitter_misc":{"Verfasst von":"Andr\u00e9 Minhorst","Gesch\u00e4tzte Lesezeit":"20\u00a0Minuten"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/access-im-unternehmen.de\/Aufgaben_per_TreeView_verwalten\/#article","isPartOf":{"@id":"https:\/\/access-im-unternehmen.de\/Aufgaben_per_TreeView_verwalten\/"},"author":{"name":"Andr\u00e9 Minhorst","@id":"https:\/\/access-im-unternehmen.de\/#\/schema\/person\/13395c4bcd7d7963efe33be9c584d93f"},"headline":"Aufgaben per TreeView verwalten","datePublished":"2020-05-22T21:53:36+00:00","mainEntityOfPage":{"@id":"https:\/\/access-im-unternehmen.de\/Aufgaben_per_TreeView_verwalten\/"},"wordCount":3496,"commentCount":0,"publisher":{"@id":"https:\/\/access-im-unternehmen.de\/#organization"},"image":{"@id":"https:\/\/access-im-unternehmen.de\/Aufgaben_per_TreeView_verwalten\/#primaryimage"},"thumbnailUrl":"http:\/\/vg05.met.vgwort.de\/na\/bddeac028a0845daa293111afcf29472","articleSection":["2\/2012","2012","Mit Formularen arbeiten"],"inLanguage":"de","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/access-im-unternehmen.de\/Aufgaben_per_TreeView_verwalten\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/access-im-unternehmen.de\/Aufgaben_per_TreeView_verwalten\/","url":"https:\/\/access-im-unternehmen.de\/Aufgaben_per_TreeView_verwalten\/","name":"Aufgaben per TreeView verwalten - Access im Unternehmen","isPartOf":{"@id":"https:\/\/access-im-unternehmen.de\/#website"},"primaryImageOfPage":{"@id":"https:\/\/access-im-unternehmen.de\/Aufgaben_per_TreeView_verwalten\/#primaryimage"},"image":{"@id":"https:\/\/access-im-unternehmen.de\/Aufgaben_per_TreeView_verwalten\/#primaryimage"},"thumbnailUrl":"http:\/\/vg05.met.vgwort.de\/na\/bddeac028a0845daa293111afcf29472","datePublished":"2020-05-22T21:53:36+00:00","breadcrumb":{"@id":"https:\/\/access-im-unternehmen.de\/Aufgaben_per_TreeView_verwalten\/#breadcrumb"},"inLanguage":"de","potentialAction":[{"@type":"ReadAction","target":["https:\/\/access-im-unternehmen.de\/Aufgaben_per_TreeView_verwalten\/"]}]},{"@type":"ImageObject","inLanguage":"de","@id":"https:\/\/access-im-unternehmen.de\/Aufgaben_per_TreeView_verwalten\/#primaryimage","url":"http:\/\/vg05.met.vgwort.de\/na\/bddeac028a0845daa293111afcf29472","contentUrl":"http:\/\/vg05.met.vgwort.de\/na\/bddeac028a0845daa293111afcf29472"},{"@type":"BreadcrumbList","@id":"https:\/\/access-im-unternehmen.de\/Aufgaben_per_TreeView_verwalten\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/access-im-unternehmen.de\/"},{"@type":"ListItem","position":2,"name":"Aufgaben per TreeView verwalten"}]},{"@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\/55000826","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=55000826"}],"version-history":[{"count":0,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/posts\/55000826\/revisions"}],"wp:attachment":[{"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/media?parent=55000826"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/categories?post=55000826"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/tags?post=55000826"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}