{"id":55001611,"date":"2026-08-01T00:00:00","date_gmt":"2026-07-04T19:26:59","guid":{"rendered":"http:\/\/access-im-unternehmen.aix-dev.de\/aiu\/?p=1611"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-30T00:00:00","slug":"Filter_speichern_und_wieder_hervorholen","status":"publish","type":"post","link":"https:\/\/access-im-unternehmen.de\/Filter_speichern_und_wieder_hervorholen\/","title":{"rendered":"Filter speichern und wieder hervorholen"},"content":{"rendered":"<p><b>Bis jetzt kann unser Filterformular schon eine ganze Menge: Man klickt sich seine Suchbedingungen zusammen und sieht sofort nur noch die passenden Datens&auml;tze. Doch sobald man das Formular schlie&szlig;t, ist der m&uuml;hsam eingestellte Filter wieder weg. Wer denselben Filter morgen erneut braucht, muss alles noch einmal eintippen. Das &auml;ndern wir jetzt. In diesem Teil bringen wir dem Filterformular bei, einen fertigen Filter unter einem Namen zu speichern und ihn sp&auml;ter mit einem Klick wieder hervorzuholen.<\/b><\/p>\n<h2>Die Idee<\/h2>\n<p>Stellen Sie sich vor, Sie malen ein sch&ouml;nes Bild und legen es in eine Schublade. Wollen Sie es sp&auml;ter wieder ansehen, holen Sie es einfach heraus. Genau das machen wir mit unseren Filtern: Wir schreiben die eingestellten Bedingungen in eine Tabelle &#8211; das ist unsere Schublade &#8211; und k&ouml;nnen sie jederzeit wieder herausholen. Damit das Ganze aufger&auml;umt bleibt, bekommt jeder gespeicherte Filter einen Namen, den man sich selbst aussucht, zum Beispiel &#8222;Gro&szlig;e Kunden&#8220; oder &#8222;Geburtstage diesen Monat&#8220;.<\/p>\n<p>Wichtig ist uns dabei eine Sache: Ein gespeicherter Filter soll nicht nur wieder angewendet werden k&ouml;nnen, sondern auch wieder vollst&auml;ndig im Formular erscheinen &#8211; mit allen Feldern, Bedingungen und Werten. So kann man einen alten Filter laden und ihn bei Bedarf noch ein bisschen anpassen, statt ganz von vorn anzufangen.<\/p>\n<h2>Ein Knopf, der alles kann<\/h2>\n<p>Man k&ouml;nnte nun zwei Kn&ouml;pfe einbauen: einen zum Speichern und einen zum Laden. Doch das w&uuml;rde schnell un&uuml;bersichtlich. Wo w&auml;hlt man beim Laden aus mehreren Filtern den richtigen aus? Wie l&ouml;scht man einen, den man nicht mehr braucht? Deshalb gehen wir einen anderen Weg: Ein einziger Knopf mit der Aufschrift <b>Filter verwalten<\/b> im Fu&szlig; des Formulars &ouml;ffnet ein kleines Fenster, in dem man alles erledigen kann &#8211; speichern, laden, umbenennen und l&ouml;schen. So bleibt der Formularfu&szlig; aufger&auml;umt.<\/p>\n<p>Wie dieser neue Knopf aussieht, zeigt Bild 1. Er sitzt zwischen den bereits bekannten Schaltfl&auml;chen zum Anwenden und Zur&uuml;cksetzen.<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2026_04\/pic_1611_001.png\" alt=\"Der neue Knopf \"Filter verwalten\" &ouml;ffnet das Verwaltungsfenster\" width=\"649,559\" height=\"271,084\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 1: Der neue Knopf &#8222;Filter verwalten&#8220; &ouml;ffnet das Verwaltungsfenster<\/span><\/b><\/p>\n<p>Ein Klick darauf &ouml;ffnet das Verwaltungsfenster <b>frmFilterVerwaltung<\/b> (siehe Bild 2). Links sieht man die Liste der bereits gespeicherten Filter, rechts die Kn&ouml;pfe f&uuml;r die einzelnen Aktionen. Praktisch: Es werden immer nur die Filter angezeigt, die zu genau diesem Formular geh&ouml;ren &#8211; so vermischt sich nichts, wenn man das Filterformular an mehreren Stellen einsetzt.<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2026_04\/pic_1611_002.png\" alt=\"Das Formular zum Verwalten der Filter\" width=\"599,559\" height=\"397,5569\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 2: Das Formular zum Verwalten der Filter<\/span><\/b><\/p>\n<p>Die Prozedur hinter der Schaltfl&auml;che <b>frmVerwalten <\/b>lautet wie folgt:<\/p>\n<pre><span style=\"color:blue;\">Private Sub <\/span>cmdVerwalten_Click()\r\n    DoCmd.OpenForm \"frmFilterVerwaltung\", , , , , _\r\n        acDialog, DatentragendesFormularName()\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<h2>Wohin die Filter wandern<\/h2>\n<p>Zum Aufbewahren brauchen wir zwei Tabellen. Die erste, <b>tblFilter<\/b>, merkt sich zu jedem Filter einen Steckbrief: zu welchem Formular er geh&ouml;rt, wie er hei&szlig;t und wann er angelegt und zuletzt ge&auml;ndert wurde.<\/p>\n<p>F&uuml;r diese Tabelle haben wir au&szlig;erdem einen eindeutigen Index &uuml;ber die Felder <b>Formularname<\/b> und <b>Filtername <\/b>definiert, damit keine doppelten Filternamen je Formular vergeben werden k&ouml;nnen (siehe Bild 3).<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2026_04\/pic_1611_003.png\" alt=\"Tabelle zum Speichern der Filter\" width=\"599,559\" height=\"436,2784\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 3: Tabelle zum Speichern der Filter<\/span><\/b><\/p>\n<p>Die zweite, <b>tblFilterZeilen<\/b>, speichert die einzelnen Filterzeilen &#8211; also welches Feld, welche Bedingung und welcher Wert in jeder Zeile stehen. Weil ein Filter aus mehreren Zeilen bestehen kann, geh&ouml;ren zu einem Steckbrief in der ersten Tabelle mehrere Eintr&auml;ge in der zweiten.<\/p>\n<p>Den Entwurf dieser Tabelle sehen wir in Bild 4.<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2026_04\/pic_1611_004.png\" alt=\"Tabelle zum Speichern der Filterzeilen eines Filters\" width=\"599,559\" height=\"444,6945\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 4: Tabelle zum Speichern der Filterzeilen eines Filters<\/span><\/b><\/p>\n<p>Damit beim L&ouml;schen eines Filters auch seine Zeilen mitverschwinden, verkn&uuml;pfen wir die beiden Tabellen mit einer Beziehung, die eine sogenannte L&ouml;schweitergabe hat. L&ouml;scht man den Steckbrief, r&auml;umt Access die zugeh&ouml;rigen Zeilen automatisch mit weg (siehe Bild 5).<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2026_04\/pic_1611_005.png\" alt=\"Tabellen der L&ouml;sung und ihre Beziehung\" width=\"599,559\" height=\"440,7999\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 5: Tabellen der L&ouml;sung und ihre Beziehung<\/span><\/b><\/p>\n<p>Ein kleiner, aber wichtiger Trick steckt bei den Nachschlagefeldern aus dem vorigen Teil. Dort w&auml;hlt man einen Wert bequem aus einer Liste aus &#8211; angezeigt wird zum Beispiel &#8222;Stammkunde&#8220;, gespeichert wird aber die dahinterliegende Nummer. Genau diese Nummer schreiben wir auch in unsere Schublade.<\/p>\n<p>Beim Hervorholen setzt das Formular die Nummer wieder ein, und die Liste zeigt von selbst wieder den richtigen Text an. So bleibt alles stimmig, selbst wenn sich der angezeigte Text einmal &auml;ndert.<\/p>\n<h2>Einen Filter in die Schublade legen<\/h2>\n<p>Das Fenster zum Verwalten der Filter sehen wir in der Entwurfsansicht in Bild 6.<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2026_04\/pic_1611_006.png\" alt=\"Entwurf des Formulars zum Verwalten der Filter\" width=\"599,559\" height=\"437,3831\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 6: Entwurf des Formulars zum Verwalten der Filter<\/span><\/b><\/p>\n<p>Klickt man hier auf <b>Aktuellen Filter speichern<\/b>, startet der Speicher-Vorgang f&uuml;r den aktuell definierten Filter.<\/p>\n<p>Die dadurch ausgel&ouml;ste Prozedur <b>cmdSpeichern_Click<\/b> (siehe Listing 1) besorgt sich zun&auml;chst &uuml;ber <b>FilterFormular<\/b> eine Referenz auf das noch ge&ouml;ffnete Filterformular &#8211; schlie&szlig;lich liegen die einzustellenden Bedingungen ja dort und nicht im Dialog.<\/p>\n<pre><span style=\"color:blue;\">Private Sub <\/span>cmdSpeichern_Click()\r\n    <span style=\"color:blue;\">Dim <\/span>frm<span style=\"color:blue;\"> As <\/span>Form, strName<span style=\"color:blue;\"> As String<\/span>, bolUeberschreiben<span style=\"color:blue;\"> As Boolean<\/span>, varVorgabe<span style=\"color:blue;\"> As Variant<\/span>\r\n    <span style=\"color:blue;\">Set<\/span> frm = FilterFormular()\r\n    <span style=\"color:blue;\">If <\/span>frm Is Nothing<span style=\"color:blue;\"> Then<\/span> <span style=\"color:blue;\">Exit Sub<\/span>\r\n    varVorgabe = \"\"\r\n    <span style=\"color:blue;\">If <\/span><span style=\"color:blue;\">Not<\/span> IsNull(Me.lstFilter.Value)<span style=\"color:blue;\"> Then<\/span>\r\n        varVorgabe = Nz(Me.lstFilter.Column(1), \"\") 'Filtername\r\n    <span style=\"color:blue;\">End If<\/span>\r\n    strName = <span style=\"color:blue;\">Trim<\/span>(Nz(InputBox(\"Name fuer den Filter:\", \"Filter speichern\", varVorgabe), \"\"))\r\n    <span style=\"color:blue;\">If <\/span><span style=\"color:blue;\">Len<\/span>(strName) = 0<span style=\"color:blue;\"> Then<\/span> <span style=\"color:blue;\">Exit Sub<\/span>\r\n    <span style=\"color:blue;\">If <\/span>FilterExistiert(strName)<span style=\"color:blue;\"> Then<\/span>\r\n        If <span style=\"color:blue;\">MsgBox<\/span>(\"Ein Filter '\" & strName & \"' existiert bereits.\" & <span style=\"color:blue;\">vbCrLf<\/span> & \"Ueberschreiben?\", _\r\n                vbQuestion + vbYesNo, \"Ueberschreiben\") = vbNo Then\r\n            <span style=\"color:blue;\">Exit Sub<\/span>\r\n        <span style=\"color:blue;\">End If<\/span>\r\n        bolUeberschreiben = <span style=\"color:blue;\">True<\/span>\r\n    <span style=\"color:blue;\">End If<\/span>\r\n    <span style=\"color:blue;\">If <\/span>frm.FilterSpeichern(strName, bolUeberschreiben)<span style=\"color:blue;\"> Then<\/span>\r\n        ListeAktualisieren\r\n        EintragMarkieren strName\r\n    <span style=\"color:blue;\">End If<\/span>\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p><b><span style=\"color:darkgrey;\">Listing 1: Aufruf des Speichervorgangs f&uuml;r einen Filter<\/span><\/b><\/p>\n<p>L&auml;sst sich das Formular nicht finden, bricht die Prozedur still ab, denn ohne Filterformular gibt es nichts zu speichern.<\/p>\n<p>Danach wird der Name erfragt. Ist in der Liste bereits ein Filter markiert, verwendet die Prozedur dessen Namen als Vorgabe &#8211; so l&auml;sst sich ein bestehender Eintrag bequem aktualisieren, ohne den Namen erneut eintippen zu m&uuml;ssen. Die <b>InputBox<\/b> zeigt diesen Vorschlag an, und das umschlie&szlig;ende <b>Trim<\/b> entfernt &uuml;berfl&uuml;ssige Leerzeichen am Rand. Gibt der Benutzer keinen Namen ein oder bricht er ab, endet die Prozedur an dieser Stelle.<\/p>\n<p>Bevor gespeichert wird, kl&auml;rt <b>FilterExistiert<\/b>, ob unter diesem Namen schon ein Filter abgelegt ist. Falls ja, fragt eine R&uuml;ckfrage, ob er &uuml;berschrieben werden soll. Verneint der Benutzer, geschieht nichts weiter; best&auml;tigt er, merkt sich die Prozedur das im Kennzeichen <b>bolUeberschreiben<\/b>. Handelt es sich dagegen um einen neuen Namen, bleibt dieses Kennzeichen auf <b>False<\/b> &#8211; es wird schlicht ein neuer Filter angelegt.<\/p>\n<p>Die eigentliche Arbeit &uuml;bergibt die Prozedur nun an das Filterformular, indem sie dessen Funktion <b>FilterSpeichern<\/b> mit Namen und &Uuml;berschreiben-Kennzeichen aufruft.<\/p>\n<p>Meldet diese Erfolg, baut <b>ListeAktualisieren<\/b> die Liste im Dialog neu auf, und <b>EintragMarkieren<\/b> hebt den soeben gespeicherten Filter darin hervor.<\/p>\n<p>Auf diese Weise sieht der Benutzer sofort, dass sein Filter angekommen ist, und das Fenster bleibt f&uuml;r weitere Aktionen ge&ouml;ffnet.<\/p>\n<h2>Die Funktion FilterSpeichern im Detail<\/h2>\n<p>Das Speichern eines Filters &uuml;bernimmt die &ouml;ffentliche Funktion <b>FilterSpeichern<\/b>. Sie erh&auml;lt zwei Parameter: den vom Benutzer vergebenen Namen sowie ein Kennzeichen, ob ein bereits vorhandener Filter gleichen Namens &uuml;berschrieben werden darf.<\/p>\n<p>Als Ergebnis liefert sie <b>True<\/b> zur&uuml;ck, wenn das Speichern geklappt hat &#8211; so kann der aufrufende Verwaltungsdialog anschlie&szlig;end die Liste aktualisieren. Den ersten Teil des Codes zeigt Listing 2.<\/p>\n<pre><span style=\"color:blue;\">Public Function <\/span>FilterSpeichern(strName<span style=\"color:blue;\"> As String<\/span>, bolUeberschreiben<span style=\"color:blue;\"> As Boolean<\/span>)<span style=\"color:blue;\"> As Boolean<\/span>\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>rstKopf<span style=\"color:blue;\"> As <\/span>DAO.Recordset\r\n    <span style=\"color:blue;\">Dim <\/span>rstZeile<span style=\"color:blue;\"> As <\/span>DAO.Recordset\r\n    <span style=\"color:blue;\">Dim <\/span>lngFilterID<span style=\"color:blue;\"> As Long<\/span>\r\n    <span style=\"color:blue;\">Dim <\/span>strFormular<span style=\"color:blue;\"> As String<\/span>\r\n    <span style=\"color:blue;\">Dim <\/span>g<span style=\"color:blue;\"> As Integer<\/span>, z<span style=\"color:blue;\"> As Integer<\/span>\r\n    <span style=\"color:blue;\">Dim <\/span>strFeld<span style=\"color:blue;\"> As String<\/span>, strBedingung<span style=\"color:blue;\"> As String<\/span>\r\n    <span style=\"color:blue;\">Dim <\/span>strWert<span style=\"color:blue;\"> As String<\/span>, strWert2<span style=\"color:blue;\"> As String<\/span>, strDatumstyp<span style=\"color:blue;\"> As String<\/span>\r\n    <span style=\"color:blue;\">On Error GoTo<\/span> Fehler\r\n    strFormular = DatentragendesFormularName()\r\n    <span style=\"color:blue;\">If <\/span><span style=\"color:blue;\">Len<\/span>(strName) = 0<span style=\"color:blue;\"> Then<\/span>\r\n        <span style=\"color:blue;\">MsgBox<\/span> \"Bitte einen Namen fuer den Filter angeben.\", vbExclamation, \"Name fehlt\"\r\n        <span style=\"color:blue;\">Exit Function<\/span>\r\n    <span style=\"color:blue;\">End If<\/span>\r\n    <span style=\"color:blue;\">Set<\/span> db = CurrentDb\r\n    'Pruefen ob schon ein Filter dieses Namens existiert\r\n    lngFilterID = FilterIDErmitteln(strFormular, strName)\r\n    <span style=\"color:blue;\">If <\/span>lngFilterID &gt; 0 And <span style=\"color:blue;\">Not<\/span> bolUeberschreiben<span style=\"color:blue;\"> Then<\/span>\r\n        <span style=\"color:blue;\">MsgBox<\/span> \"Ein Filter mit diesem Namen existiert bereits.\", vbExclamation, \"Bereits vorhanden\"\r\n        <span style=\"color:blue;\">Exit Function<\/span>\r\n    <span style=\"color:blue;\">End If<\/span>\r\n    <span style=\"color:blue;\">If <\/span>lngFilterID &gt; 0<span style=\"color:blue;\"> Then<\/span>\r\n        'Vorhandene Zeilen entfernen, Kopf aktualisieren\r\n        db.Execute \"DELETE FROM tblFilterZeilen WHERE FilterID = \" & lngFilterID, dbFailOnError\r\n        db.Execute \"UPDATE tblFilter SET GeaendertAm = Now() \" & \"WHERE FilterID = \" & lngFilterID, dbFailOnError\r\n    <span style=\"color:blue;\">Else<\/span>\r\n        'Neuen Kopf anlegen\r\n        <span style=\"color:blue;\">Set<\/span> rstKopf = db.OpenRecordset(\"tblFilter\", dbOpenDynaset)\r\n        rstKopf.Add<span style=\"color:blue;\">New<\/span>\r\n        rstKopf!Formularname = strFormular\r\n        rstKopf!Filtername = strName\r\n        rstKopf!Angelegt = Now()\r\n        rstKopf!GeaendertAm = Now()\r\n        rstKopf.Update\r\n        rstKopf.Bookmark = rstKopf.LastModified\r\n        lngFilterID = rstKopf!FilterID\r\n        rstKopf.Close\r\n    <span style=\"color:blue;\">End If<\/span>\r\n    ...<\/pre>\n<p><b><span style=\"color:darkgrey;\">Listing 2: Prozedur zum Speichern des Filters, Teil 1<\/span><\/b><\/p>\n<h2>Vorbereitung und Namenspr&uuml;fung<\/h2>\n<p>Nach den Variablendeklarationen aktiviert <b>On Error GoTo Fehler<\/b> eine Fehlerbehandlung, die am Ende der Funktion steht. Sollte beim Zugriff auf die Tabellen etwas schiefgehen, landet die Ausf&uuml;hrung dort und zeigt eine verst&auml;ndliche Meldung, statt mit einem rohen Laufzeitfehler abzust&uuml;rzen.<\/p>\n<p>Zun&auml;chst ermittelt die Funktion &uuml;ber <b>DatentragendesFormularName<\/b> den Namen des Formulars, dessen Datens&auml;tze gefiltert werden. Dieser Name dient sp&auml;ter als Zuordnung, damit im Verwaltungsdialog nur die Filter des jeweils passenden Formulars erscheinen. Ist gar kein Name f&uuml;r den Filter angegeben, bricht die Funktion mit einem Hinweis ab &#8211; ohne Namen l&auml;sst sich ein Filter sp&auml;ter schlie&szlig;lich nicht wiederfinden.<\/p>\n<h2>Neu anlegen oder &uuml;berschreiben<\/h2>\n<p>Der n&auml;chste Block kl&auml;rt, ob unter diesem Namen bereits ein Filter existiert. Die Hilfsfunktion <b>FilterIDErmitteln<\/b> liefert entweder die Kennung eines vorhandenen Filters oder den Wert 0. Findet sie einen Treffer und wurde das &Uuml;berschreiben nicht ausdr&uuml;cklich erlaubt, meldet die Funktion, dass der Name schon vergeben ist, und beendet sich. So kann ein bestehender Filter niemals versehentlich &uuml;berschrieben werden.<\/p>\n<p>Darf hingegen &uuml;berschrieben werden, r&auml;umt die Funktion zun&auml;chst auf: Sie l&ouml;scht alle bisherigen Zeilen dieses Filters aus <b>tblFilterZeilen<\/b> und vermerkt im Steckbrief &uuml;ber <b>GeaendertAm<\/b> den Zeitpunkt der &Auml;nderung. Anschlie&szlig;end werden die Zeilen neu geschrieben &#8211; so bleibt kein Rest einer fr&uuml;heren Fassung zur&uuml;ck. Gibt es den Filter dagegen noch nicht, legt die Funktion einen frischen Steckbrief an. Bemerkenswert ist hier die Zeile mit <b>rstKopf.Bookmark = rstKopf.LastModified<\/b>: Sie springt zum eben angelegten Datensatz, um dessen automatisch vergebene Kennung <b>FilterID<\/b> auszulesen. Diese Kennung brauchen wir gleich, um die einzelnen Filterzeilen dem richtigen Steckbrief zuzuordnen.<\/p>\n<h2>Die einzelnen Filterzeilen schreiben<\/h2>\n<p>Nun folgt das Herzst&uuml;ck (zweiter Teil der Prozedur <b>FilterSpeichern<\/b>, siehe Listing 3). Zwei ineinander verschachtelte Schleifen durchlaufen alle aktiven Gruppen und deren Zeilen &#8211; genau in derselben Systematik, mit der auch das Anwenden eines Filters arbeitet. F&uuml;r jede Zeile liest die Funktion das gew&auml;hlte Feld und die Bedingung aus. Nur wenn beide gef&uuml;llt sind, gilt die Zeile als echte Filterzeile und wird gespeichert; leere Zeilen &uuml;berspringt die Schleife stillschweigend.<\/p>\n<pre>    ...\r\n    'Zeilen schreiben\r\n    <span style=\"color:blue;\">Set<\/span> rstZeile = db.OpenRecordset(\"tblFilterZeilen\", dbOpenDynaset)\r\n    For g = 1 To m_intAktiveGruppen\r\n        For z = 1 To m_intAktiveZeilen(g)\r\n            strFeld = Nz(Me(\"cboFeld_\" & g & \"_\" & z).Value, \"\")\r\n            strBedingung = Nz(Me(\"cboBedingung_\" & g & \"_\" & z).Value, \"\")\r\n            <span style=\"color:blue;\">If <\/span><span style=\"color:blue;\">Len<\/span>(strFeld) &gt; 0 And <span style=\"color:blue;\">Len<\/span>(strBedingung) &gt; 0<span style=\"color:blue;\"> Then<\/span>\r\n                'Wert wie beim Anwenden ermitteln\r\n                <span style=\"color:blue;\">If <\/span>m_bolAktKombi(g, z)<span style=\"color:blue;\"> Then<\/span>\r\n                    strWert = Nz(Me(\"cboWert_\" & g & \"_\" & z).Value, \"\")\r\n                <span style=\"color:blue;\">Else<\/span>\r\n                    strWert = Nz(Me(\"txtWert_\" & g & \"_\" & z).Value, \"\")\r\n                    <span style=\"color:blue;\">If <\/span><span style=\"color:blue;\">Len<\/span>(strWert) = 0<span style=\"color:blue;\"> Then<\/span>\r\n                        strWert = Nz(Me(\"txtDatum_\" & g & \"_\" & z).Value, \"\")\r\n                    <span style=\"color:blue;\">End If<\/span>\r\n                <span style=\"color:blue;\">End If<\/span>\r\n                strWert2 = Nz(Me(\"txtWert2_\" & g & \"_\" & z).Value, \"\")\r\n                <span style=\"color:blue;\">If <\/span><span style=\"color:blue;\">Len<\/span>(strWert2) = 0<span style=\"color:blue;\"> Then<\/span>\r\n                    strWert2 = Nz(Me(\"txtDatumA_\" & g & \"_\" & z).Value, \"\")\r\n                <span style=\"color:blue;\">End If<\/span>\r\n                strDatumstyp = Nz(Me(\"cboDatumstyp_\" & g & \"_\" & z).Value, \"\")\r\n                rstZeile.Add<span style=\"color:blue;\">New<\/span>\r\n                rstZeile!FilterID = lngFilterID\r\n                rstZeile!GruppeNr = g\r\n                rstZeile!Reihenfolge = z\r\n                rstZeile!Feldname = strFeld\r\n                rstZeile!Bedingung = strBedingung\r\n                rstZeile!Datumstyp = strDatumstyp\r\n                rstZeile!Wert = strWert\r\n                rstZeile!Wert2 = strWert2\r\n                rstZeile.Update\r\n            <span style=\"color:blue;\">End If<\/span>\r\n        <span style=\"color:blue;\">Next<\/span> z\r\n    <span style=\"color:blue;\">Next<\/span> g\r\n    rstZeile.Close\r\n    FilterSpeichern = <span style=\"color:blue;\">True<\/span>\r\n    <span style=\"color:blue;\">Exit Function<\/span>\r\nFehler:\r\n    <span style=\"color:blue;\">MsgBox<\/span> \"Beim Speichern ist ein Fehler aufgetreten:\" & <span style=\"color:blue;\">vbCrLf<\/span> & _\r\n        Err.Description, <span style=\"color:blue;\">vbCr<\/span>itical, \"Fehler\"\r\n<span style=\"color:blue;\">End Function<\/span><\/pre>\n<p><b><span style=\"color:darkgrey;\">Listing 3: Prozedur zum Speichern des Filters, Teil 2<\/span><\/b><\/p>\n<p>Beim Auslesen des Vergleichswerts zeigt sich, wie eng das Speichern an die &uuml;brige Logik angelehnt ist. Handelt es sich um ein Nachschlagefeld, holt die Funktion den Wert aus dem Auswahl-Kombinationsfeld <b>cboWert<\/b> &#8211; und damit die dahinterliegende Nummer, nicht den angezeigten Text.<\/p>\n<p>Andernfalls stammt der Wert aus dem Textfeld <b>txtWert<\/b>; ist dieses leer, wird ersatzweise das Datumsfeld <b>txtDatum<\/b> herangezogen. Nach demselben Muster ermittelt die Funktion einen etwaigen zweiten Wert &#8211; n&ouml;tig bei der Bedingung <b>Ist zwischen<\/b> &#8211; aus <b>txtWert2<\/b> beziehungsweise <b>txtDatumA<\/b>. Zus&auml;tzlich sichert sie den Datumstyp, damit vordefinierte Zeitr&auml;ume wie &#8222;Diesen Monat&#8220; sp&auml;ter korrekt wiederhergestellt werden.<\/p>\n<p>Steht der Datensatz zusammen, wird er mit <b>AddNew<\/b> angelegt, mit den Werten gef&uuml;llt und mit <b>Update<\/b> gespeichert. Die Felder <b>GruppeNr<\/b> und <b>Reihenfolge<\/b> halten dabei fest, an welcher Stelle die Zeile stand &#8211; diese Angaben sind sp&auml;ter beim Laden entscheidend, damit die Zeilen wieder in der richtigen Anordnung erscheinen. Sind alle Zeilen geschrieben, schlie&szlig;t die Funktion das Recordset, meldet mit <b>True<\/b> den Erfolg und ist fertig.<\/p>\n<h2>Einen Filter wieder hervorholen<\/h2>\n<p>Das Hervorholen eines gespeicherten Filters ist der spannendste Teil, denn hier muss das Formular seinen fr&uuml;heren Zustand exakt nachbauen.<\/p>\n<p>Der Trick dabei ist einfach und clever zugleich: Statt sich etwas Neues auszudenken, tut das Formular beim Laden genau das, was auch ein Mensch t&auml;te. Es w&auml;hlt ein Feld aus, dann eine Bedingung, dann tr&auml;gt es den Wert ein &#8211; Zeile f&uuml;r Zeile. Dadurch ist garantiert, dass sich ein geladener Filter genauso verh&auml;lt wie ein von Hand eingegebener.<\/p>\n<p>Damit das klappt, ruft die Prozedur <b>FilterLaden<\/b> f&uuml;r jede gespeicherte Zeile dieselben Bausteine auf, die auch bei der normalen Bedienung laufen: erst das Feld setzen und <b>FeldGewaehlt<\/b> aufrufen, dann die Bedingung setzen und <b>BedingungGewaehlt<\/b> aufrufen, und zum Schluss den Wert eintragen.<\/p>\n<h2>Die Prozedur FilterLaden im Detail<\/h2>\n<p>Die &ouml;ffentliche Prozedur <b>FilterLaden<\/b> bekommt die Kennung des gew&uuml;nschten Filters &uuml;bergeben und baut den fr&uuml;her gespeicherten Zustand vollst&auml;ndig im Formular wieder auf (erster Teil des Codes siehe Listing 4).<\/p>\n<pre><span style=\"color:blue;\">Public Sub <\/span>FilterLaden(lngFilterID<span style=\"color:blue;\"> As Long<\/span>, <span style=\"color:blue;\">Optional<\/span> bolAnwenden<span style=\"color:blue;\"> As Boolean<\/span> = <span style=\"color:blue;\">True<\/span>)\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>rst<span style=\"color:blue;\"> As <\/span>DAO.Recordset\r\n    <span style=\"color:blue;\">Dim <\/span>g<span style=\"color:blue;\"> As Integer<\/span>, z<span style=\"color:blue;\"> As Integer<\/span>\r\n    <span style=\"color:blue;\">Dim <\/span>strDatumstyp<span style=\"color:blue;\"> As String<\/span>\r\n    <span style=\"color:blue;\">On Error GoTo<\/span> Fehler\r\n    'Formular zuerst leeren - ohne leeren Filter zu senden\r\n    FilterZuruecksetzenIntern\r\n    <span style=\"color:blue;\">Set<\/span> db = CurrentDb\r\n    <span style=\"color:blue;\">Set<\/span> rst = db.OpenRecordset(\"SELECT * FROM tblFilterZeilen WHERE FilterID = \" & lngFilterID & \" \" & _\r\n        \"ORDER BY GruppeNr, Reihenfolge\", dbOpenSnapshot)\r\n    <span style=\"color:blue;\">If <\/span>rst.EOF<span style=\"color:blue;\"> Then<\/span>\r\n        rst.Close\r\n        <span style=\"color:blue;\">Exit Sub<\/span>\r\n    <span style=\"color:blue;\">End If<\/span>\r\n    'Lademodus aktiv: FeldGewaehlt blendet keine Folgezeile ein\r\n    m_bolLadeModus = <span style=\"color:blue;\">True<\/span>\r\n    <span style=\"color:blue;\">Do While<\/span> <span style=\"color:blue;\">Not<\/span> rst.EOF\r\n        g = rst!GruppeNr\r\n        z = rst!Reihenfolge\r\n        'Bei Bedarf Gruppe aktivieren (analog cmdODERHinzufuegen)\r\n        <span style=\"color:blue;\">Do While<\/span> g &gt; m_intAktiveGruppen\r\n            m_intAktiveGruppen = m_intAktiveGruppen + 1\r\n            m_intAktiveZeilen(m_intAktiveGruppen) = 1\r\n            ZeileEinblenden m_intAktiveGruppen, 1\r\n        <span style=\"color:blue;\">Loop<\/span>\r\n        'Bei Bedarf Zeile dieser Gruppe einblenden\r\n        <span style=\"color:blue;\">Do While<\/span> z &gt; m_intAktiveZeilen(g)\r\n            m_intAktiveZeilen(g) = m_intAktiveZeilen(g) + 1\r\n            ZeileEinblenden g, m_intAktiveZeilen(g)\r\n        <span style=\"color:blue;\">Loop<\/span>\r\n        ...<\/pre>\n<p><b><span style=\"color:darkgrey;\">Listing 4: Prozedur zum Laden eines Filters, Teil 1<\/span><\/b><\/p>\n<p>Ein zweiter, optionaler Parameter steuert, ob der Filter nach dem Aufbau gleich angewendet werden soll &#8211; voreingestellt ist ja, denn in aller Regel m&ouml;chte man das geladene Ergebnis sofort sehen.<\/p>\n<h2>Erst aufr&auml;umen, dann laden<\/h2>\n<p>Bevor irgendetwas eingelesen wird, r&auml;umt <b>FilterLaden<\/b> das Formular auf. Daf&uuml;r ruft die Prozedur <b>FilterZuruecksetzenIntern<\/b> auf. Das ist bewusst nicht dieselbe Routine wie hinter dem Zur&uuml;cksetzen-Knopf: Jene w&uuml;rde n&auml;mlich zus&auml;tzlich einen leeren Filter an das aufrufende Formular melden und damit kurz alle Datens&auml;tze wieder einblenden.<\/p>\n<p>Genau dieses Flackern wollen wir beim Laden vermeiden, deshalb der ausgelagerte Kern, der nur die Anzeige leert, ohne etwas nach au&szlig;en zu senden.<\/p>\n<pre><span style=\"color:blue;\">Private Sub <\/span>FilterZuruecksetzenIntern()\r\n    <span style=\"color:blue;\">Dim <\/span>i<span style=\"color:blue;\"> As Integer<\/span>\r\n    <span style=\"color:blue;\">Dim <\/span>j<span style=\"color:blue;\"> As Integer<\/span>\r\n    'Alle Felder leeren\r\n    For i = 1 To cMaxGruppen\r\n        For j = 1 To cMaxZeilen\r\n            Me(\"cboFeld_\" & i & \"_\" & j).Value = Null\r\n            Me(\"cboBedingung_\" & i & \"_\" & j).Value = Null\r\n            Me(\"cboBedingung_\" & i & \"_\" & j).Enabled = <span style=\"color:blue;\">False<\/span>\r\n            Me(\"cboDatumstyp_\" & i & \"_\" & j).Value = Null\r\n            Me(\"txtWert_\" & i & \"_\" & j).Value = Null\r\n            Me(\"txtWert_\" & i & \"_\" & j).<span style=\"color:blue;\">Left<\/span> = 4440\r\n            Me(\"txtDatum_\" & i & \"_\" & j).Value = Null\r\n            Me(\"txtDatum_\" & i & \"_\" & j).<span style=\"color:blue;\">Left<\/span> = 6560\r\n            Me(\"txtDatumA_\" & i & \"_\" & j).Value = Null\r\n            Me(\"txtWert2_\" & i & \"_\" & j).Value = Null\r\n            Me(\"cboJaNein_\" & i & \"_\" & j).Value = Null\r\n            Me(\"cboWert_\" & i & \"_\" & j).Value = Null\r\n            m_lngAktFeldtyp(i, j) = 0\r\n            m_bolAktKombi(i, j) = <span style=\"color:blue;\">False<\/span>\r\n        <span style=\"color:blue;\">Next<\/span> j\r\n        m_intAktiveZeilen(i) = 1\r\n    <span style=\"color:blue;\">Next<\/span> i\r\n    AlleZeilenAusblenden\r\n    m_intAktiveGruppen = 1\r\n    m_intAktiveZeilen(1) = 1\r\n    ZeileEinblenden 1, 1\r\n    cmdODERHinzufuegen.Visible = <span style=\"color:blue;\">False<\/span>\r\n    cmdZuruecksetzen.Enabled = <span style=\"color:blue;\">False<\/span>\r\n    cmdAnwenden.Enabled = <span style=\"color:blue;\">False<\/span>\r\n    AktualisiereFormularHoehe\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p>Anschlie&szlig;end &ouml;ffnet die Prozedur ein Recordset auf Basis der Tabelle <b>tblFilterZeilen<\/b>, beschr&auml;nkt auf die gew&uuml;nschte Filterkennung und sortiert nach <b>GruppeNr<\/b> und <b>Reihenfolge<\/b>. Diese Sortierung ist wichtig: Nur so werden die Zeilen sp&auml;ter in genau der Anordnung aufgebaut, in der sie einmal gespeichert wurden.<\/p>\n<p>Enth&auml;lt der Filter &uuml;berhaupt keine Zeilen, bricht die Prozedur an dieser Stelle bereits ab.<\/p>\n<h2>Der Lademodus verhindert Chaos<\/h2>\n<p>Jetzt kommt der bereits angesprochene Schalter ins Spiel. Unmittelbar vor der Schleife setzt die Prozedur <b>m_bolLadeModus<\/b> auf <b>True<\/b>. Dadurch unterl&auml;sst <b>FeldGewaehlt<\/b> bei jeder Feldauswahl das automatische Einblenden einer leeren Folgezeile.<\/p>\n<p>W&uuml;rde man darauf verzichten, entst&uuml;nden nach jeder wiederhergestellten Zeile &uuml;berfl&uuml;ssige Leerzeilen, und die Z&auml;hler f&uuml;r aktive Zeilen gerieten durcheinander. Im Lademodus baut die Prozedur die Struktur stattdessen selbst gezielt auf.<\/p>\n<h2>Zeile f&uuml;r Zeile wiederherstellen<\/h2>\n<p>Die Hauptschleife durchl&auml;uft alle gespeicherten Zeilen. Zu Beginn liest sie aus jedem Datensatz die Gruppen- und die Zeilennummer. Falls die betreffende Gruppe oder Zeile noch nicht sichtbar ist, blendet die Prozedur sie zun&auml;chst ein &#8211; und zwar so, wie es auch der Knopf zum Hinzuf&uuml;gen einer ODER-Gruppe t&auml;te.<\/p>\n<p>Zwei kleine Schleifen sorgen daf&uuml;r, dass bei Bedarf mehrere Gruppen oder Zeilen nacheinander aktiviert werden, bis die richtige Position erreicht ist.<\/p>\n<p>Der eigentliche Aufbau folgt danach demselben Weg wie eine Eingabe von Hand, und genau darin liegt der Kniff (siehe Listing 5).<\/p>\n<pre>        ...\r\n        'Denselben Weg gehen wie bei manueller Eingabe: Feld -&gt; FeldGewaehlt -&gt; Bedingung -&gt; BedingungGewaehlt\r\n        Me(\"cboFeld_\" & g & \"_\" & z).Value = Nz(rst!Feldname, \"\")\r\n        FeldGewaehlt g, z\r\n        Me(\"cboBedingung_\" & g & \"_\" & z).Value = Nz(rst!Bedingung, \"\")\r\n        BedingungGewaehlt g, z\r\n        'Datumstyp setzen falls vorhanden\r\n        strDatumstyp = Nz(rst!Datumstyp, \"\")\r\n        <span style=\"color:blue;\">If <\/span><span style=\"color:blue;\">Len<\/span>(strDatumstyp) &gt; 0<span style=\"color:blue;\"> Then<\/span>\r\n            Me(\"cboDatumstyp_\" & g & \"_\" & z).Value = strDatumstyp\r\n            DatumstypGewaehlt g, z\r\n        <span style=\"color:blue;\">End If<\/span>\r\n        'Werte eintragen\r\n        WertWiederherstellen g, z, Nz(rst!Wert, \"\"), Nz(rst!Wert2, \"\")\r\n        rst.Move<span style=\"color:blue;\">Next<\/span>\r\n    <span style=\"color:blue;\">Loop<\/span>\r\n    rst.Close\r\n    'Pro Gruppe eine leere Folge-Eingabezeile anhaengen, damit sich der geladene Filter wie ein manuell eingegebener\r\n    'weiter bearbeiten laesst (sofern noch Platz in der Gruppe).\r\n    For g = 1 To m_intAktiveGruppen\r\n        <span style=\"color:blue;\">If <\/span>m_intAktiveZeilen(g) &lt; cMaxZeilen<span style=\"color:blue;\"> Then<\/span>\r\n            m_intAktiveZeilen(g) = m_intAktiveZeilen(g) + 1\r\n            ZeileEinblenden g, m_intAktiveZeilen(g)\r\n        <span style=\"color:blue;\">End If<\/span>\r\n    <span style=\"color:blue;\">Next<\/span> g\r\n    'Lademodus beenden, Zustand gebuendelt aktualisieren\r\n    m_bolLadeModus = <span style=\"color:blue;\">False<\/span>\r\n    AktualisiereFormularHoehe\r\n    AktualisiereSchaltflaechen\r\n    'Optional sofort anwenden\r\n    <span style=\"color:blue;\">If <\/span>bolAnwenden<span style=\"color:blue;\"> Then<\/span>\r\n        cmdAnwenden_Click\r\n    <span style=\"color:blue;\">End If<\/span>\r\n    <span style=\"color:blue;\">Exit Sub<\/span>\r\nFehler:\r\n    m_bolLadeModus = <span style=\"color:blue;\">False<\/span>\r\n    <span style=\"color:blue;\">MsgBox<\/span> \"Beim Laden ist ein Fehler aufgetreten:\" & <span style=\"color:blue;\">vbCrLf<\/span> & Err.Description, <span style=\"color:blue;\">vbCr<\/span>itical, \"Fehler\"\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p><b><span style=\"color:darkgrey;\">Listing 5: Prozedur zum Laden des Filters, Teil 2<\/span><\/b><\/p>\n<p>Zuerst setzt die Prozedur das Feld und ruft <b>FeldGewaehlt<\/b> auf &#8211; damit werden die passende Bedingungsliste erzeugt, ein etwaiges Nachschlagefeld erkannt und dessen Auswahlliste vorbereitet.<\/p>\n<p>Danach setzt sie die Bedingung und ruft <b>BedingungGewaehlt<\/b> auf, wodurch das jeweils richtige Wertfeld eingeblendet wird. Ist ein Datumstyp gespeichert, wird auch dieser gesetzt und mit <b>DatumstypGewaehlt<\/b> verarbeitet. Weil die Prozedur genau die Bausteine der normalen Bedienung nutzt, verh&auml;lt sich ein geladener Filter am Ende exakt wie ein von Hand eingegebener.<\/p>\n<p>Den Abschluss jeder Zeile bildet das Eintragen der Werte. Diese Aufgabe &uuml;bernimmt die Hilfsprozedur <b>WertWiederherstellen<\/b>, die den gespeicherten Wert &#8211; und bei <b>Ist zwischen<\/b> auch den zweiten Wert &#8211; in das jeweils passende Feld schreibt. Bei einem Nachschlagefeld setzt sie die gespeicherte Nummer in das Auswahl-Kombinationsfeld, worauf dieses von selbst wieder den zugeh&ouml;rigen Text anzeigt. Danach r&uuml;ckt die Schleife zum n&auml;chsten Datensatz vor.<\/p>\n<h2>Den letzten Schliff geben<\/h2>\n<p>Ist die Schleife durch, sind alle gespeicherten Zeilen wiederhergestellt &#8211; es fehlt aber noch die leere Eingabezeile, die man von der normalen Bedienung gewohnt ist. Deshalb h&auml;ngt die Prozedur pro Gruppe noch eine leere Folgezeile an, sofern dort &uuml;berhaupt noch Platz ist.<\/p>\n<p>So l&auml;sst sich ein geladener Filter anschlie&szlig;end genauso bequem erweitern, als h&auml;tte man ihn gerade selbst eingegeben.<\/p>\n<p>Zum Schluss schaltet <b>FilterLaden<\/b> den Lademodus wieder aus und bringt die Anzeige in einem Rutsch auf den neuesten Stand: <b>AktualisiereFormularHoehe<\/b> passt die H&ouml;he des Formulars an die nun sichtbaren Zeilen an, <b>AktualisiereSchaltflaechen<\/b> schaltet die Kn&ouml;pfe richtig. War das Anwenden gew&uuml;nscht, l&ouml;st die Prozedur abschlie&szlig;end denselben Vorgang aus wie ein Klick auf <b>Filter anwenden<\/b>, sodass im Hintergrund sofort die gefilterten Datens&auml;tze erscheinen.<\/p>\n<h2>Wenn etwas schiefgeht<\/h2>\n<p>&Uuml;ber allem liegt eine Fehlerbehandlung. Sollte beim Zugriff auf die Tabelle oder beim Aufbau einer Zeile ein Problem auftreten, springt die Ausf&uuml;hrung in den Fehlerzweig.<\/p>\n<p>Dort wird zuerst <b>m_bolLadeModus<\/b> wieder auf False gesetzt &#8211; das ist wichtig, damit das Formular nicht versehentlich im Lademodus steckenbleibt und danach keine Folgezeilen mehr einblendet &#8211; und anschlie&szlig;end eine verst&auml;ndliche Meldung ausgegeben. So bleibt das Filterformular auch im Fehlerfall bedienbar.<\/p>\n<h2>Einen Filter umbenennen<\/h2>\n<p>Manchmal passt ein einmal vergebener Name nicht mehr recht, und man m&ouml;chte ihn &auml;ndern, ohne den Filter neu anlegen zu m&uuml;ssen. Genau daf&uuml;r sorgt <b>cmdUmbenennen_Click<\/b> (siehe Listing 6).<\/p>\n<pre><span style=\"color:blue;\">Private Sub <\/span>cmdUmbenennen_Click()\r\n    <span style=\"color:blue;\">Dim <\/span>lngID<span style=\"color:blue;\"> As Long<\/span>\r\n    <span style=\"color:blue;\">Dim <\/span>strAlt<span style=\"color:blue;\"> As String<\/span>\r\n    <span style=\"color:blue;\">Dim <\/span>strNeu<span style=\"color:blue;\"> As String<\/span>\r\n    lngID = MarkierteFilterID()\r\n    <span style=\"color:blue;\">If <\/span>lngID = 0<span style=\"color:blue;\"> Then<\/span>\r\n        <span style=\"color:blue;\">MsgBox<\/span> \"Bitte einen Filter aus der Liste waehlen.\", vbExclamation, \"Kein Filter gewaehlt\"\r\n        <span style=\"color:blue;\">Exit Sub<\/span>\r\n    <span style=\"color:blue;\">End If<\/span>\r\n    strAlt = Me.lstFilter.Column(1)\r\n    strNeu = <span style=\"color:blue;\">Trim<\/span>(Nz(InputBox(\"Neuer Name:\", \"Filter umbenennen\", strAlt), \"\"))\r\n    <span style=\"color:blue;\">If <\/span><span style=\"color:blue;\">Len<\/span>(strNeu) = 0 Or strNeu = strAlt<span style=\"color:blue;\"> Then<\/span> <span style=\"color:blue;\">Exit Sub<\/span>\r\n    <span style=\"color:blue;\">If <\/span>FilterExistiert(strNeu)<span style=\"color:blue;\"> Then<\/span>\r\n        <span style=\"color:blue;\">MsgBox<\/span> \"Ein Filter '\" & strNeu & \"' existiert bereits.\", vbExclamation, \"Bereits vorhanden\"\r\n        <span style=\"color:blue;\">Exit Sub<\/span>\r\n    <span style=\"color:blue;\">End If<\/span>\r\n    CurrentDb.Execute \"UPDATE tblFilter SET Filtername = '\" & <span style=\"color:blue;\">Replace<\/span>(strNeu, \"'\", \"''\") & \"', GeaendertAm = Now() \" & _\r\n        \"WHERE FilterID = \" & lngID, dbFailOnError\r\n    ListeAktualisieren\r\n    EintragMarkieren strNeu\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p><b><span style=\"color:darkgrey;\">Listing 6: Umbenennen eines Filters<\/span><\/b><\/p>\n<p>Zun&auml;chst holt sich die Prozedur &uuml;ber <b>MarkierteFilterID<\/b> die Kennung des in der Liste markierten Filters. Ist gar keiner ausgew&auml;hlt, liefert diese Funktion 0, und ein kurzer Hinweis bittet den Benutzer, zun&auml;chst einen Eintrag zu w&auml;hlen &#8211; danach ist Schluss.<\/p>\n<p>Liegt eine g&uuml;ltige Auswahl vor, merkt sich die Prozedur den bisherigen Namen und fragt &uuml;ber eine <b>InputBox<\/b> nach dem neuen. Praktischerweise steht der alte Name dabei schon als Vorschlag im Eingabefeld, sodass man ihn nur anpassen muss. Das umschlie&szlig;ende <b>Trim<\/b> entfernt versehentliche Leerzeichen am Rand. Gibt der Benutzer nichts ein oder l&auml;sst er den Namen unver&auml;ndert, bricht die Prozedur ab, denn dann gibt es nichts zu tun.<\/p>\n<p>Bevor der neue Name &uuml;bernommen wird, pr&uuml;ft <b>FilterExistiert<\/b>, ob er nicht schon von einem anderen Filter belegt ist. W&auml;re das der Fall, entst&uuml;nden zwei Filter gleichen Namens &#8211; ein Zustand, den die eindeutige Zuordnung in der Tabelle ohnehin verbietet.<\/p>\n<p>In diesem Fall erscheint ein Hinweis, und die Umbenennung unterbleibt. Erst wenn der Name frei ist, schreibt ein <b>UPDATE<\/b>-Befehl den neuen Namen in <b>tblFilter<\/b> und vermerkt zugleich &uuml;ber <b>GeaendertAm<\/b> den Zeitpunkt der &Auml;nderung.<\/p>\n<p>Zum Abschluss wird die Liste neu aufgebaut und der umbenannte Eintrag wieder markiert, damit der Benutzer sofort sieht, dass die &Auml;nderung angekommen ist.<\/p>\n<h2>Einen Filter l&ouml;schen<\/h2>\n<p>Filter, die man nicht mehr ben&ouml;tigt, lassen sich &uuml;ber <b>cmdLoeschen_Click<\/b> wieder entfernen (siehe Listing 7).<\/p>\n<pre><span style=\"color:blue;\">Private Sub <\/span>cmdLoeschen_Click()\r\n    <span style=\"color:blue;\">Dim <\/span>lngID<span style=\"color:blue;\"> As Long<\/span>\r\n    <span style=\"color:blue;\">Dim <\/span>strName<span style=\"color:blue;\"> As String<\/span>\r\n    lngID = MarkierteFilterID()\r\n    <span style=\"color:blue;\">If <\/span>lngID = 0<span style=\"color:blue;\"> Then<\/span>\r\n        <span style=\"color:blue;\">MsgBox<\/span> \"Bitte einen Filter aus der Liste waehlen.\", vbExclamation, \"Kein Filter gewaehlt\"\r\n        <span style=\"color:blue;\">Exit Sub<\/span>\r\n    <span style=\"color:blue;\">End If<\/span>\r\n    strName = Me.lstFilter.Column(1)\r\n    <span style=\"color:blue;\">If <\/span><span style=\"color:blue;\">MsgBox<\/span>(\"Filter '\" & strName & \"' wirklich loeschen?\", vbQuestion + vbYesNo, \"Loeschen\") = vbNo<span style=\"color:blue;\"> Then<\/span> <span style=\"color:blue;\">Exit Sub<\/span>\r\n    'Dank Loeschweitergabe werden die Zeilen automatisch entfernt\r\n    CurrentDb.Execute \"DELETE FROM tblFilter WHERE FilterID = \" & lngID, dbFailOnError\r\n    ListeAktualisieren\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p><b><span style=\"color:darkgrey;\">Listing 7: L&ouml;schen eines Filters<\/span><\/b><\/p>\n<p>Der Einstieg gleicht dem Umbenennen: Auch hier wird zuerst die markierte Filterkennung ermittelt, und ohne Auswahl weist ein Hinweis freundlich darauf hin, dass erst ein Eintrag zu w&auml;hlen ist.<\/p>\n<p>Weil L&ouml;schen nicht r&uuml;ckg&auml;ngig zu machen ist, fragt die Prozedur mit dem Namen des betroffenen Filters noch einmal ausdr&uuml;cklich nach.<\/p>\n<p>Erst wenn der Benutzer best&auml;tigt, geht es weiter &#8211; ein Klick auf Nein l&auml;sst alles unver&auml;ndert. Diese kleine R&uuml;ckfrage bewahrt vor &auml;rgerlichen Versehen.<\/p>\n<p>Das eigentliche L&ouml;schen ist dann erfreulich kurz: Ein einziger <b>DELETE<\/b>-Befehl entfernt den Steckbrief aus <b>tblFilter<\/b>. Um die zugeh&ouml;rigen Filterzeilen muss sich die Prozedur nicht k&uuml;mmern &#8211; dank der beim Anlegen der Tabellen eingerichteten L&ouml;schweitergabe verschwinden sie automatisch mit.<\/p>\n<p>Danach wird die Liste aktualisiert, und der gel&ouml;schte Filter ist verschwunden.<\/p>\n<h2>Von Version 3 auf Version 4 umbauen<\/h2>\n<p>Wer die dritte Fassung des Filterformulars bereits im Einsatz hat, muss nicht von vorn beginnen. Mit wenigen Handgriffen l&auml;sst sich die Speichern-Funktion nachr&uuml;sten. Die folgenden Schritte f&uuml;hren der Reihe nach durch den Umbau &#8211; am Ende steht ein Filterformular, das seine Filter dauerhaft merken kann.<\/p>\n<p><b>Schritt 1: Tabellen anlegen.<\/b> Importieren Sie das Modul <b>mdlFilterSpeichern<\/b> aus der Beispieldatenbank in Ihre Anwendung und rufen Sie im Direktfenster einmalig <b>ErstelleFilterTabellen<\/b> auf. Damit entstehen die beiden Tabellen <b>tblFilter<\/b> und <b>tblFilterZeilen<\/b> samt der Beziehung mit L&ouml;schweitergabe.<\/p>\n<p><b>Schritt 2: Verwaltungsformular &uuml;bernehmen.<\/b> Holen Sie das Formular <b>frmFilterVerwaltung<\/b> aus der Beispieldatenbank in Ihre Datenbank. Es bringt sein Klassenmodul und alle n&ouml;tigen Steuerelemente &#8211; Listenfeld und Schaltfl&auml;chen &#8211; bereits mit.<\/p>\n<p><b>Schritt 3: Neue Steuerelemente im Filterformular.<\/b> &Ouml;ffnen Sie <b>frmFilter<\/b> im Entwurf und legen Sie im Fu&szlig; eine weitere Schaltfl&auml;che mit dem Namen <b>cmdVerwalten<\/b> an; als Beschriftung bietet sich <b>Filter verwalten<\/b> an. Die 25 Wert-Kombinationsfelder aus der dritten Fassung bleiben unver&auml;ndert bestehen.<\/p>\n<p><b>Schritt 4: Modulvariable erg&auml;nzen.<\/b> F&uuml;gen Sie im Klassenmodul von <b>frmFilter<\/b> bei den &uuml;brigen Deklarationen die neue Variable <b>m_bolLadeModus<\/b> hinzu. Sie steuert sp&auml;ter, dass beim Laden keine &uuml;berfl&uuml;ssigen Leerzeilen entstehen.<\/p>\n<p><b>Schritt 5: FeldGewaehlt anpassen.<\/b> In der Prozedur <b>FeldGewaehlt<\/b> wird der Block, der automatisch die n&auml;chste Zeile einblendet, in eine Abfrage auf <b>m_bolLadeModus<\/b> gefasst. So unterbleibt dieses Einblenden, solange ein gespeicherter Filter wiederhergestellt wird. Den genauen Code zeigt der Beitrag im Abschnitt zum Lademodus.<\/p>\n<p><b>Schritt 6: Neue Prozeduren einf&uuml;gen.<\/b> Erg&auml;nzen Sie im Klassenmodul von <b>frmFilter<\/b> die Ereignisprozedur <b>cmdVerwalten_Click<\/b> sowie die &ouml;ffentlichen Routinen <b>FilterSpeichern<\/b> und <b>FilterLaden<\/b> mit ihren Hilfsprozeduren <b>DatentragendesFormularName<\/b>, <b>FilterIDErmitteln<\/b> und <b>WertWiederherstellen<\/b>. Diese Bausteine erledigen das eigentliche Speichern und Wiederherstellen.<\/p>\n<p><b>Schritt 7: Zur&uuml;cksetzen aufteilen.<\/b> Der gemeinsame Kern des Zur&uuml;cksetzens wandert in die neue Prozedur <b>FilterZuruecksetzenIntern<\/b>, die nur die Anzeige leert.<\/p>\n<p>Die bestehende Prozedur <b>cmdZuruecksetzen_Click<\/b> ruft k&uuml;nftig nur noch diesen Kern auf und sendet anschlie&szlig;end wie gehabt den leeren Filter an das aufrufende Formular.<\/p>\n<p>Auch <b>FilterLaden<\/b> greift auf diesen Kern zur&uuml;ck &#8211; allerdings ohne den leeren Filter zu senden, damit beim Laden nichts flackert.<\/p>\n<p>Nach diesen sieben Schritten ist der Umbau abgeschlossen. Ein Klick auf die neue Schaltfl&auml;che &ouml;ffnet das Verwaltungsfenster, und Filter lassen sich fortan speichern, wieder hervorholen, umbenennen und l&ouml;schen. Da keine bestehende Logik entfernt, sondern nur erg&auml;nzt wurde, arbeiten alle Funktionen der dritten Fassung unver&auml;ndert weiter.<\/p>\n<h2>Zusammenfassung<\/h2>\n<p>Unser Filterformular hat jetzt ein Ged&auml;chtnis bekommen. Einmal eingestellte Filter lassen sich unter einem Namen speichern und sp&auml;ter mit einem Doppelklick wieder hervorholen &#8211; vollst&auml;ndig aufgebaut und auf Wunsch sofort angewendet.<\/p>\n<p>Drei Dinge sind dabei besonders erw&auml;hnenswert. Erstens speichern wir die Filter nicht als fertigen Suchbefehl, sondern Zeile f&uuml;r Zeile &#8211; nur so lassen sie sich sp&auml;ter wieder vollst&auml;ndig im Formular herstellen und bearbeiten. Zweitens baut das Formular einen geladenen Filter auf, indem es dieselben Bausteine aufruft wie bei der Handeingabe, sodass sich beide gar nicht unterscheiden. Und drittens sorgt ein kleiner Schalter daf&uuml;r, dass beim Hervorholen keine leeren Zwischenzeilen entstehen.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Bis jetzt kann unser Filterformular schon eine ganze Menge: Man klickt sich seine Suchbedingungen zusammen und sieht sofort nur noch die passenden Datens&auml;tze. Doch sobald man das Formular schlie&szlig;t, ist der m&uuml;hsam eingestellte Filter wieder weg. Wer denselben Filter morgen erneut braucht, muss alles noch einmal eintippen. Das &auml;ndern wir jetzt. In diesem Teil bringen wir dem Filterformular bei, einen fertigen Filter unter einem Namen zu speichern und ihn sp&auml;ter mit einem Klick wieder hervorzuholen.<\/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":[662026,66042026,44000027],"tags":[],"class_list":["post-55001611","post","type-post","status-publish","format-standard","hentry","category-662026","category-66042026","category-Loesungen"],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v20.9 (Yoast SEO v27.9) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>Filter speichern und wieder hervorholen - 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\/Filter_speichern_und_wieder_hervorholen\/\" \/>\n<meta property=\"og:locale\" content=\"de_DE\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Filter speichern und wieder hervorholen\" \/>\n<meta property=\"og:description\" content=\"Bis jetzt kann unser Filterformular schon eine ganze Menge: Man klickt sich seine Suchbedingungen zusammen und sieht sofort nur noch die passenden Datens&auml;tze. Doch sobald man das Formular schlie&szlig;t, ist der m&uuml;hsam eingestellte Filter wieder weg. Wer denselben Filter morgen erneut braucht, muss alles noch einmal eintippen. Das &auml;ndern wir jetzt. In diesem Teil bringen wir dem Filterformular bei, einen fertigen Filter unter einem Namen zu speichern und ihn sp&auml;ter mit einem Klick wieder hervorzuholen.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/access-im-unternehmen.de\/Filter_speichern_und_wieder_hervorholen\/\" \/>\n<meta property=\"og:site_name\" content=\"Access im Unternehmen\" \/>\n<meta property=\"article:published_time\" content=\"2026-07-04T19:26:59+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=\"23\u00a0Minuten\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Filter_speichern_und_wieder_hervorholen\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Filter_speichern_und_wieder_hervorholen\\\/\"},\"author\":{\"name\":\"Andr\u00e9 Minhorst\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#\\\/schema\\\/person\\\/13395c4bcd7d7963efe33be9c584d93f\"},\"headline\":\"Filter speichern und wieder hervorholen\",\"datePublished\":\"2026-07-04T19:26:59+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Filter_speichern_und_wieder_hervorholen\\\/\"},\"wordCount\":3614,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#organization\"},\"articleSection\":[\"2026\",\"4\\\/2026\",\"L\u00f6sungen\"],\"inLanguage\":\"de\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/access-im-unternehmen.de\\\/Filter_speichern_und_wieder_hervorholen\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Filter_speichern_und_wieder_hervorholen\\\/\",\"url\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Filter_speichern_und_wieder_hervorholen\\\/\",\"name\":\"Filter speichern und wieder hervorholen - Access im Unternehmen\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#website\"},\"datePublished\":\"2026-07-04T19:26:59+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Filter_speichern_und_wieder_hervorholen\\\/#breadcrumb\"},\"inLanguage\":\"de\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/access-im-unternehmen.de\\\/Filter_speichern_und_wieder_hervorholen\\\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Filter_speichern_und_wieder_hervorholen\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/access-im-unternehmen.de\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Filter speichern und wieder hervorholen\"}]},{\"@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":"Filter speichern und wieder hervorholen - 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\/Filter_speichern_und_wieder_hervorholen\/","og_locale":"de_DE","og_type":"article","og_title":"Filter speichern und wieder hervorholen","og_description":"Bis jetzt kann unser Filterformular schon eine ganze Menge: Man klickt sich seine Suchbedingungen zusammen und sieht sofort nur noch die passenden Datens&auml;tze. Doch sobald man das Formular schlie&szlig;t, ist der m&uuml;hsam eingestellte Filter wieder weg. Wer denselben Filter morgen erneut braucht, muss alles noch einmal eintippen. Das &auml;ndern wir jetzt. In diesem Teil bringen wir dem Filterformular bei, einen fertigen Filter unter einem Namen zu speichern und ihn sp&auml;ter mit einem Klick wieder hervorzuholen.","og_url":"https:\/\/access-im-unternehmen.de\/Filter_speichern_und_wieder_hervorholen\/","og_site_name":"Access im Unternehmen","article_published_time":"2026-07-04T19:26:59+00:00","author":"Andr\u00e9 Minhorst","twitter_card":"summary_large_image","twitter_misc":{"Verfasst von":"Andr\u00e9 Minhorst","Gesch\u00e4tzte Lesezeit":"23\u00a0Minuten"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/access-im-unternehmen.de\/Filter_speichern_und_wieder_hervorholen\/#article","isPartOf":{"@id":"https:\/\/access-im-unternehmen.de\/Filter_speichern_und_wieder_hervorholen\/"},"author":{"name":"Andr\u00e9 Minhorst","@id":"https:\/\/access-im-unternehmen.de\/#\/schema\/person\/13395c4bcd7d7963efe33be9c584d93f"},"headline":"Filter speichern und wieder hervorholen","datePublished":"2026-07-04T19:26:59+00:00","mainEntityOfPage":{"@id":"https:\/\/access-im-unternehmen.de\/Filter_speichern_und_wieder_hervorholen\/"},"wordCount":3614,"commentCount":0,"publisher":{"@id":"https:\/\/access-im-unternehmen.de\/#organization"},"articleSection":["2026","4\/2026","L\u00f6sungen"],"inLanguage":"de","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/access-im-unternehmen.de\/Filter_speichern_und_wieder_hervorholen\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/access-im-unternehmen.de\/Filter_speichern_und_wieder_hervorholen\/","url":"https:\/\/access-im-unternehmen.de\/Filter_speichern_und_wieder_hervorholen\/","name":"Filter speichern und wieder hervorholen - Access im Unternehmen","isPartOf":{"@id":"https:\/\/access-im-unternehmen.de\/#website"},"datePublished":"2026-07-04T19:26:59+00:00","breadcrumb":{"@id":"https:\/\/access-im-unternehmen.de\/Filter_speichern_und_wieder_hervorholen\/#breadcrumb"},"inLanguage":"de","potentialAction":[{"@type":"ReadAction","target":["https:\/\/access-im-unternehmen.de\/Filter_speichern_und_wieder_hervorholen\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/access-im-unternehmen.de\/Filter_speichern_und_wieder_hervorholen\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/access-im-unternehmen.de\/"},{"@type":"ListItem","position":2,"name":"Filter speichern und wieder hervorholen"}]},{"@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\/55001611","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=55001611"}],"version-history":[{"count":0,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/posts\/55001611\/revisions"}],"wp:attachment":[{"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/media?parent=55001611"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/categories?post=55001611"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/tags?post=55001611"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}