{"id":55000440,"date":"2007-02-01T00:00:00","date_gmt":"2021-02-11T21:08:41","guid":{"rendered":"http:\/\/access-im-unternehmen.aix-dev.de\/aiu\/?p=440"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-30T00:00:00","slug":"Universelle_Volltextsuche","status":"publish","type":"post","link":"https:\/\/access-im-unternehmen.de\/Universelle_Volltextsuche\/","title":{"rendered":"Universelle Volltextsuche"},"content":{"rendered":"<p><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/vg09.met.vgwort.de\/na\/2eae004a3a244737a93b50bff44beea5\" width=\"1\" height=\"1\" alt=\"\"><\/p>\n<p><b>Erst nach Fertigstellung eines Datenbankprojekts f&auml;llt Ihrem Auftraggeber pl&ouml;tzlich noch ein, dass er noch ein unentbehrliches Feature ben&ouml;tigt: Er will alle Tabellen der Datenbank global nach bestimmten Stichw&ouml;rtern durchsuchen k&ouml;nnen, etwa indem er den Namen &#8222;Meyer&#8220; in ein Suchfeld eingibt und schnell s&auml;mtliche Vorkommen in einer Ergebnisliste erh&auml;lt. Hieraus will er die entsprechenden Stellen anschlie&szlig;end aufrufen. Einfach, denken Sie, und signalisieren Ihrem Kunden: &#8222;O.K., alles kein Problem!&#8220; Doch bei n&auml;herer Betrachtung f&auml;llt Ihnen auf, dass es da mehr zu bedenken gibt, als zun&auml;chst vermutet &#8230;<\/b><\/p>\n<\/p><\/div>\n<div class=\"story\">\n<p><b>Schwache Leistung<\/b><\/p>\n<p>Die Idee, die Sie vielleicht haben, ist, einfach alle Tabellen der Datenbank anhand der <b>TableDefs<\/b>-Auflistung zu ermitteln, jede mit einem Recordset zu &ouml;ffnen und in allen Feldern nach dem Begriff zu suchen. Welche Felder der Tabellen in die Suche mit einbezogen werden sollen, entscheidet der Datentyp: Nur Textfelder m&uuml;ssen nach den W&uuml;nschen des Auftraggebers durchsucht werden und diese ergeben sich aus den <b>Type<\/b>-Eigenschaften der <b>Field<\/b>-Objekte des Recordsets. Sie d&uuml;rfen den DAO-Typ <b>dbText <\/b>oder <b>dbMemo <\/b>aufweisen. Der Inhalt der so gefilterten Felder wird dann Datensatz f&uuml;r Datensatz ausgelesen. Dabei wird mit der VBA-Funktion <b>InStr() <\/b>ermittelt, ob darin der Suchbegriff vorkommt.<\/p>\n<p>Das w&uuml;rde sicherlich funktionieren, doch dann kommen Ihnen berechtigte Zweifel, ob diese Art der Suche nicht mit Performance-Schwierigkeiten zu k&auml;mpfen h&auml;tte. Schlie&szlig;lich m&uuml;sste die Anwendung alle Datens&auml;tze aller Textfelder aller Tabellen durchlaufen, was bei dem erwarteten Datenaufkommen und der Tatsache, dass viele Benutzer auf die Datenbank zugreifen werden, nicht zu einem Resultat f&uuml;hrt, dem man das Pr&auml;dikat &#8222;schnell&#8220; anheften k&ouml;nnte. Ein Produkt mit schlechter Performance m&ouml;chten Sie aber nicht abliefern und deshalb muss eine andere L&ouml;sung her.<\/p>\n<p><b>Suchmaschine<\/b><\/p>\n<p>Suchmaschinen wie Google suchen ja auch nicht jeweils im gesamten Terabyte-schweren Bestand von Webseiten, die ihre Robots aus dem Netz gefischt haben, wenn Sie einen Suchbegriff eingeben.<\/p>\n<p>Stattdessen besitzen sie einen eindeutigen Index aller Begriffe, die irgendwo auf den Seiten vorkommen. Etwas &auml;hnliches sollte auch unsere Volltextsuche enthalten. In Bild 1 sehen Sie einen Vorschlag f&uuml;r den Aufbau der zum Volltextindex geh&ouml;renden Tabellen.<\/p>\n<div class=\"abbildungrahmen\">\n            <img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2007_01\/Volltextindex-web-images\/relations_opt.jpeg\" alt=\"relations.tif\" \/>\n        <\/div>\n<div class=\"abbildung\">\n<p><b><span style=\"color:darkgrey\">Bild 1: Tabellenaufbau des Volltextsuchindex<\/span><\/b><\/p>\n<\/p><\/div>\n<p>Die Angelegenheit teilt sich in zwei Vorg&auml;nge auf: Zuerst werden alle Tabellen der Datenbank ermittelt und iher Namen sowie Prim&auml;rschl&uuml;sselnamen in der Tabelle <b>tblFulltextTables <\/b>abgelegt.<\/p>\n<p>Au&szlig;erdem wird die Tabelle <b>tblFulltextFields <\/b>mit den zu den Tabellen geh&ouml;renden Feldnamen gef&uuml;llt &#8211; aber nur f&uuml;r jene Felder, die Texte enthalten. Diese beiden Tabellen stellen die Grundlage f&uuml;r die anschlie&szlig;ende Indizierung dar. Die Tabellen enthalten zus&auml;tzlich je ein <b>Boolean<\/b>-Feld namens <b>bScan<\/b>, das mitteilt, ob die Tabelle oder das Feld &uuml;berhaupt f&uuml;r die Indizierung relevant sind.<\/p>\n<p>Nur wenn <b>bScan <\/b>den Wert <b>True <\/b>hat, wird das Feld oder die Tabelle in die Indizierung mit einbezogen.<\/p>\n<p>Im zweiten Schritt werden dann die Feldinhalte der nun ermittelten Textfelder ausgelesen, in Worte gesplittet und diese werden in die Tabelle <b>tblFulltextWords <\/b>aufgenommen.<\/p>\n<p>Dabei ist das Feld <b>Word <\/b>eindeutig indiziert, sodass jeder Begriff nur einmal in der Tabelle vorkommen kann. <b>ID <\/b>ist ein Autowert. Die wichtigste Tabelle des Systems ist nun <b>tblFulltextFind<\/b>. Dort werden die folgenden Informationen zusammengefasst: <\/p>\n<ul>\n<li class=\"aufz-hlung\"><b>IDWord<\/b>: enth&auml;lt einen Verweis auf ein Wort der Tabelle <b>tblFulltextWords<\/b><\/li>\n<li class=\"aufz-hlung\"><b>IDTable<\/b>: enth&auml;lt einen Verweis auf einen der in <b>tblFulltextTables <\/b>enthaltenen Tabellennamen<\/li>\n<li class=\"aufz-hlung\"><b>IDField<\/b>: enth&auml;lt einen Verweis auf ein Feld der in <b>IDTable <\/b>gespeicherten Tabelle<\/li>\n<li class=\"aufz-hlung\"><b>IDRecord<\/b>: der Wert des Prim&auml;rschl&uuml;ssels, der zu dem Datensatz geh&ouml;rt, in dem der Text mit dem Suchbegriff steht<\/li>\n<\/ul>\n<p>Das macht auch schon eines deutlich: Um einen Feldinhalt wiederzufinden, ist es praktisch unumg&auml;nglich, dass die Tabellen einen eindeutigen Prim&auml;rschl&uuml;ssel aufweisen. Ohne diesen kann ein Datensatz sp&auml;ter nicht identifiziert werden. Sie sollten es sich daher zur Angewohnheit machen, jede auch noch so kleine Tabelle mit einem Prim&auml;rschl&uuml;ssel zu versehen. Das l&auml;sst sich auch noch nachtr&auml;glich erledigen, indem Sie Tabellen ohne Schl&uuml;ssel ein zus&auml;tzliches Autowert-Feld spendieren.<\/p>\n<p><b>Suchen<\/b><\/p>\n<p>Wie erfolgt nun die Suche nach einem Begriff Zun&auml;chst schaut die Anwendung im Feld <b>Word <\/b>der Tabelle <b>tblFulltextWords <\/b>nach, ob der Begriff vorhanden ist. Falls nicht, kommt also das Wort nirgendwo vor. Falls ja, wird die Tabelle <b>tblFulltextFind <\/b>zu Rate gezogen und nach Datens&auml;tzen gefiltert, die den richtigen Wert f&uuml;r <b>IDWord <\/b>enthalten. Und schon haben wir die Ergebnisliste mit Datens&auml;tzen, die auf Tabellen, Felder und Prim&auml;rschl&uuml;ssel verweisen.<\/p>\n<p>Da geschieht also nicht viel und das genau ist der Vorteil der indizierten Volltextsuche. Sie l&auml;uft schnell ab. Das Suchen ist einfach, das Indizieren allerdings relativ aufw&auml;ndig und Zeit raubend.<\/p>\n<p><b>Modul zur Volltextindizierung<\/b><\/p>\n<p>Ich erspare Ihnen, die Routinen zur Indizierung selbst zu programmieren. Im Modul <b>mdlVolltextindex <\/b>der Beispieldatenbank finden Sie alles Notwendige. Die Erl&auml;uterung einzelner Code-Stellen folgt weiter unten. Die Datenbank enth&auml;lt neben den notwendigen Tabellen zur Indizierung (siehe Bild 1) als Beispiel noch die Tabellen aus der S&uuml;dsturm-Datenbank [1] sowie ein Suchformular <b>frmVolltextsuche <\/b>(siehe Bild 3), das die Funktionalit&auml;t demonstrieren soll.<\/p>\n<p>Das Formular enth&auml;lt eine Schaltfl&auml;che <b>Suchindex neu aufbauen<\/b>, deren Bet&auml;tigung die Routinen zur Neuindizierung aller Tabellen der Datenbank anst&ouml;&szlig;t. Dabei wird in einem Zwischenschritt die Tabelle <b>tblFulltextTables <\/b>ge&ouml;ffnet, die mit der als Unterdatenblatt eingeblendeten Tabelle <b>tblFulltextFields <\/b>verkn&uuml;pft ist. Das gibt Ihnen die Gelegenheit, f&uuml;r jede Tabelle und jedes Feld festzulegen, ob es bei der Indizierung ber&uuml;cksichtigt werden soll.<\/p>\n<p>Dazu m&uuml;ssen H&auml;kchen in die <b>Verwenden<\/b>-Checkboxen gesetzt werden (siehe Bild 2).<\/p>\n<div class=\"abbildungrahmen\">\n            <img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2007_01\/Volltextindex-web-images\/datenblatt_opt.jpeg\" alt=\"datenblatt.tif\" \/>\n        <\/div>\n<div class=\"abbildung\">\n<p><b><span style=\"color:darkgrey\">Bild 2: Tabellen und Felder mit Textinhalten<\/span><\/b><\/p>\n<\/p><\/div>\n<p>Ich w&uuml;rde hier anregen, das Feld <b>PLZ <\/b>zu deaktivieren, denn es macht wenig Sinn, Postleitzahlen in eine Volltextsuche zu integrieren.<\/p>\n<p>Nach dem Schlie&szlig;en der Tabelle f&auml;hrt die Routine automatisch fort und indiziert den gesamten Datenbestand.<\/p>\n<p>Sie meldet sich nach Vollzug schlie&szlig;lich mit einer Ausgabe der ben&ouml;tigten Zeit. Das wird ungef&auml;hr eine Sekunde dauern.In Datenbanken mit Zigtausenden von Datens&auml;tzen wird die Sache allerdings anders aussehen. Hier kann die Indizierung ohne Weiteres mehrere Minuten beanspruchen.<\/p>\n<p>Nach der Indizierung k&ouml;nnen Sie einen Suchbegriff in das Formular eingeben, auf <b>Suchen!<\/b> klicken und Sie erhalten eine Ergebnisliste wie in Bild 3.<\/p>\n<div class=\"abbildung\">\n            <img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2007_01\/Volltextindex-web-images\/formular_opt.jpeg\" alt=\"formular.tif\" \/>\n        <\/div>\n<div class=\"abbildung\">\n<p><b><span style=\"color:darkgrey\">Bild 3: Suchformular der Beispieldatenbank<\/span><\/b><\/p>\n<\/p><\/div>\n<p><!--30percent--><\/p>\n<p>Ein Doppelklick auf einen Eintrag &ouml;ffnet dann das entsprechende Formular und markiert au&szlig;erdem das Textfeld, in dem der Begriff enthalten ist.<\/p>\n<p>Die Spalte &#8222;Inhalt&#8220; der Ergebnisliste enth&auml;lt &uuml;brigens nur einen Ausschnitt des Textinhalts, falls dieser l&auml;nger als 50 Zeichen sein sollte.<\/p>\n<p><b>Behind the curtain<\/b><\/p>\n<p>Schauen wir uns auszugsweise an, wie der Code des Moduls <b>mdlVolltextindex <\/b>gestrickt ist.<\/p>\n<p><b>ScanMyTables<\/b><\/p>\n<p>Diese Prozedur listet die Tabellen und Felder auf, die in die Volltextsuche einbezogen werden k&ouml;nnen, und speichert das Ergebnis in den Tabellen <b>tblFulltextTables <\/b>und <b>tblFulltextFields<\/b>. Dazu wird die <b>TableDefs<\/b>-Auflistung der Datenbank enumeriert:<\/p>\n<pre>Dim dbs As Database\r\nDim tdf As TableDef\r\nSet dbs = CurrentDb\r\nFor Each tdf In dbs.TableDefs\r\n     tdf.MacheIrgendWas\r\nNext tdf<\/pre>\n<p>Welche Tabellen und Felder f&uuml;r die Indizierung in Frage kommen, h&auml;ngt von drei Bedingungen ab:<\/p>\n<ul>\n<li class=\"aufz-hlung\">Wenn Systemtabellen wie <b>MSysAccessObjects<\/b> ausgeschlossen werden sollen, kann die Prozedur bei Aufruf der Parameter <b>OmitSysTables <\/b>auf <b>True <\/b>gesetzt werden.<\/li>\n<li class=\"aufz-hlung\">Zul&auml;ssige Tabellen m&uuml;ssen einen Prim&auml;rschl&uuml;ssel aufweisen.<\/li>\n<li class=\"aufz-hlung\">Die Felder d&uuml;rfen vom Datentyp <b>Text <\/b>oder <b>Memo <\/b>sein.<\/li>\n<\/ul>\n<p>Ob eine Tabelle eine Systemtabelle ist, l&auml;sst sich anhand ihrer <b>Attributes<\/b>-Eigenschaft feststellen:<\/p>\n<pre>If (tdf.Attributes AND dbSystemObject) = 0 Then \r\n ...<\/pre>\n<p>Hier wird der Wert von <b>Attributes<\/b> mit dem Bit-Operator <b>AND <\/b>und der Konstanten <b>dbSystemObject <\/b>verkn&uuml;pft. Heraus kommt also die Kombination beider Bit-Werte, die <b>0<\/b> betr&auml;gt, wenn die Werte nicht &uuml;bereinstimmen &#8211; es handelt sich dann nicht um eine Systemtabelle.<\/p>\n<p>Nicht ganz so einfach ist zu ermitteln, wie der Prim&auml;rschl&uuml;ssel einer Tabelle lautet. Es gibt keine entsprechende Eigenschaft eines <b>TableDefs<\/b>-Objekts. Stattdessen enth&auml;lt es eine <b>Indexes<\/b>-Auflistung, die durchlaufen werden muss, wobei Sie jeden einzelnen enthaltenen Index auf die Eigenschaft <b>Primary <\/b>&uuml;berpr&uuml;fen m&uuml;ssen: <\/p>\n<pre>Dim Index As DAO.Index\r\nDim bIndex As Boolean\r\nFor Each idx In tdf.Indexes\r\n     If idx.Primary = True Then\r\n         bIndex = True\r\n         Exit For\r\n     End If\r\nNext idx\r\nIf bIndex Then\r\n    ...<\/pre>\n<p>Wenn die <b>Primary<\/b>-Eigenschaft den Wert <b>True <\/b>hat, dann handelt es sich bei dem Index um den Prim&auml;rschl&uuml;ssel und die Schleife wird verlassen. Davor wird noch das Flag <b>bIndex <\/b>auf <b>True <\/b>gesetzt, damit der weitere Code wei&szlig;, dass &uuml;berhaupt ein Primarschl&uuml;ssel gefunden wurde. Nur, wenn das der Fall ist, darf die Tabelle in die Indizierung mit aufgenommen werden.<\/p>\n<p>Den Namen des Index erh&auml;lt man &uuml;brigens &uuml;ber seine <b>Fields<\/b>-Auflistung. Es ist ihr erstes Feld:<\/p>\n<pre>Prim&auml;rIndexName = idx.Fields(0).Name<\/pre>\n<p>Schlie&szlig;lich m&uuml;ssen noch alle Felder aussortiert werden, die nicht den Datentyp <b>Text<\/b> oder <b>Memo<\/b> haben. F&uuml;r jede Tabelle wird dazu eine innere Schleife f&uuml;r die <b>Fields<\/b>-Auflistung durchlaufen:<\/p>\n<pre>Dim fld As DAO.Field\r\nFor Each fld In tdf.Fields\r\n     If fld.Type = dbText Or fld.Type = dbMemo Then\r\n         ...\r\n     End If\r\nNext fld<\/pre>\n<p>Die Informationen &uuml;ber die Tabellennamen (<b>tdf.Name<\/b>), Feldnamen (<b>fld.Name<\/b>) und Prim&auml;r-schl&uuml;ssel werden in den Schleifen &uuml;ber Recordsets in die Tabellen <b>tblFulltextTables <\/b>und <b>tblFulltextFields <\/b>geschrieben. Damit ist der erste &#8211; und einfachere (!) &#8211; Schritt der Indizierung bew&auml;ltigt.<\/p>\n<p><b>CreateFulltextWords<\/b><\/p>\n<p>Diese Prozedur &uuml;bernimmt die eigentliche Aufgabe: das Erstellen des Wortindex (<b>tblFulltextWords<\/b>) und der Verweise auf Fundstellen in den Tabellen (<b>tblFulltextFind<\/b>).<\/p>\n<p>Man kann ihr zwei Parameter &uuml;bergeben: <b>Minwordlength <\/b>gibt an, wie lang ein Wort mindes-tens sein muss, damit es indiziert werden kann.<\/p>\n<p>Es ist sicher nachvollziehbar, dass ein Begriff, der aus nur zwei Zeichen besteht (etwa &#8222;da&#8220;), nicht unbedingt in den Index aufgenommen werden muss. Es g&auml;be zu viele Fundstellen, was den Index unn&ouml;tig aufbl&auml;hen w&uuml;rde.<\/p>\n<p>Der Vorgabewert ist deshalb auf vier Zeichen eingestellt. Das Pendant zu diesem Parameter ist <b>maxwordlength<\/b>, in dem die maximal erlaubte Wortl&auml;nge &uuml;bergeben werden kann. Dieser Parameter ist weniger kritisch, denn je l&auml;nger ein Wort ist, desto seltener kommt es &uuml;blicherweise vor. Der Vorgabewert ist 40 Zeichen.<\/p>\n<p>Die Prozedur durchl&auml;uft nun alle Datens&auml;tze eines Recordsets auf Basis der Abfrage <b>qry_FulltextTablesFields<\/b>, die die zu durchsuchenden Tabellen und Felder kombiniert. Das Ergebnis der Abfrage sieht etwa wie in Bild 4 aus.<\/p>\n<div class=\"abbildungrahmen\">\n            <img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2007_01\/Volltextindex-web-images\/qry_opt.jpeg\" alt=\"qry.tif\" \/>\n        <\/div>\n<div class=\"abbildung\">\n<p><b><span style=\"color:darkgrey\">Bild 4: Datens&auml;tze der Tabellen tblFulltextTables und tblFulltextFields in einer Abfrage zusammengefasst<\/span><\/b><\/p>\n<\/p><\/div>\n<p>Aus den Feldern dieser Abfrage werden wiederum in der Datensatzschleife dynamisch SQL-Strings erzeugt.<\/p>\n<p>Pro Tabellenname entsteht daraus ein Ausdruck, der den zu indizierenden Feldern entspricht &#8211; etwa so:<\/p>\n<pre>SELECT [ArtikelID],[Artikelname],[Liefereinheit] FROM [tblArtikel]<\/pre>\n<p>Neben den Textfeldern <b>Artikelname <\/b>und <b>Liefereinheit <\/b>enth&auml;lt der SQL-String auch den Pri-m&auml;rschl&uuml;ssel <b>ArtikelID<\/b>, der ben&ouml;tigt wird, damit die Fundstellen anschlie&szlig;end eindeutig identifiziert werden k&ouml;nnen.<\/p>\n<p>Dieser SQL-String wird zur Weiterverarbeitung an die Prozedur <b>ScanWordsSQL <\/b>&uuml;bergeben. Man h&auml;tte diese Routine auch innerhalb der Schleife von <b>CreateFulltextIndex() <\/b>unterbringen k&ouml;nnen. Sie w&auml;re dann aber wahrhaft zu einem Unget&uuml;m von verschachtelten Schleifen und Einr&uuml;ckungen geworden. Der besseren Strukturierung wegen wurde dieser Teil also in eine separate Prozedur ausgelagert.<\/p>\n<p><b>ScanWordsSQL<\/b><\/p>\n<p>Diese Routine durchl&auml;uft nun alle Datens&auml;tze eines Recordsets, das auf dem SQL-String aufbaut, und liest dabei alle Textfeldinhalte aus:<\/p>\n<pre>Set rstText = dbs.OpenRecordset(sSQL)\r\nn = rstText.Fields.Count\r\nDo While Not rstText.EOF\r\n     For i = 1 To n - 1\r\n         Set fld = rstText.Fields(i)\r\n         sText = Nz(fld.Value)\r\n         If Len(sText) &gt; 0 Then\r\n             arrText = SplitMult(sText)<\/pre>\n<p>Der Feldinhalt steht nun jeweils in der String-Variablen <b>sText<\/b>.<\/p>\n<p>Wie aber erh&auml;lt man aus diesem String die einzelnen W&ouml;rter <\/p>\n<p>Ab VBA 6 steht zum Trennen einzelner W&ouml;rter eines Strings die Funktion <b>Split() <\/b>zur Verf&uuml;gung, der man als Parameter ein bestimmtes Trennzeichen &uuml;bergeben kann. Als Ergebnis erh&auml;lt man ein Array mit den einzelnen W&ouml;rtern.<\/p>\n<p>Nur reicht das f&uuml;r unseren Fall leider nicht aus. Wenn das Leerzeichen als Trenner benutzt wird, dann wird etwa aus &#8222;ein h&uuml;bscher, netter Code-Teil.&#8220; die Folge &#8222;ein&#8220;, &#8222;h&uuml;bscher,&#8220;, &#8222;netter&#8220;, &#8222;Code-Teil.&#8220; Die einzelnen W&ouml;rter sind nicht korrekt, weil sie teilweise Satzzeichen eingebaut haben. <\/p>\n<p>Aus &#8222;Code-Teil.&#8220; soll &#8222;Code&#8220;, &#8222;Teil&#8220; werden. Um solche Trennungen zu realisieren, brauchen Sie eine zus&auml;tzliche Hilfsfunktion, die in der Prozedur <b>SplitMult() <\/b>ausprogrammiert ist.<\/p>\n<p>Sie trennt die Begriffe anhand einer Liste von Trennzeichen, die in der String-Variablen <b>DelimitChars <\/b>untergebracht ist. Im Modul wird diese Variable so gef&uuml;llt:<\/p>\n<pre>DelimitChars = &quot; ,;.:!&lt;&gt;\/()[]{}\\+*=&apos;&quot; &amp; _\r\n vbCr &amp; vbLf &amp; vbTab &amp; Chr$(34) &amp; Chr$(11)<\/pre>\n<p>Nachdem sich die W&ouml;rter des Textfelds nun im String-Array <b>arrText <\/b>befinden, werden sie der Tabelle <b>tblFulltextWords <\/b>hinzugef&uuml;gt &#8211; aber nur, wenn sie sich noch nicht darin befinden. Deshalb wird per <b>Recordset.FindFirst <\/b>erst nachgeschaut, ob ein Begriff bereits existiert.<\/p>\n<p>Egal, ob dieser neu hinzugef&uuml;gt wurde oder auch nicht, wird anschlie&szlig;end die ID des Wortes festgestellt, die damit einem neuen Datensatz der Tabelle <b>tblFulltextFind <\/b>zugewiesen werden kann, f&uuml;r den Sie jetzt alle Informationen zusammen haben:<\/p>\n<ul>\n<li class=\"aufz-hlung\">Die ID der Tabelle (<b>IDTable<\/b>), die der Prozedur bereits als Parameter &uuml;bergeben wird,<\/li>\n<li class=\"aufz-hlung\">die Nummer des Feldes (<b>i <\/b>der Schleife),<\/li>\n<li class=\"aufz-hlung\">die ID des Wortes und<\/li>\n<li class=\"aufz-hlung\">der Wert des Prim&auml;rschl&uuml;ssels (<b>IDRecord<\/b>) der durchsuchten Tabelle.<\/li>\n<\/ul>\n<p>Den Prim&auml;rschl&uuml;ssel erhalten Sie &uuml;ber <b>rstText.Fields(0).Value<\/b>, weil im <b>SELECT<\/b>-Statement des SQL-Strings <b>sSQL <\/b>das Prim&auml;rschl&uuml;sselfeld (<b>&gt; ArtikelID<\/b>) immer an die erste Stelle gesetzt ist. <\/p>\n<p>Da es sein kann, dass ein Suchbegriff mehrmals in einem Textinhalt vorkommt, es aber wenig n&uuml;tzlich ist, mehrfach auf dieses Feld zu verweisen, k&ouml;nnte man die Tabelle <b>tblFulltextFind <\/b>mit einem eindeutigen zusammengesetzten Index versehen, der alle ihre Felder enthielte.<\/p>\n<p>Hier gilt es allerdings abzuw&auml;gen: Da die Tabelle sehr viele Datens&auml;tze enth&auml;lt, w&uuml;rde eine solche Indizierung stark auf Kosten der Performance beim Aufbau des Volltextindex gehen.<\/p>\n<p>Und die Wahrscheinlichkeit, dass ein Suchbegriff zwei- oder mehrmals in einem Textinhalt vorkommt, ist so gro&szlig; auch wieder nicht. In der Beispieldatenbank ist die Tabelle <b>tblFulltextFind <\/b>daher nicht mit einem zusammengesetzten Index ausgestattet.<\/p>\n<p><b>FindWord<\/b><\/p>\n<p>Nach aufgebautem Wortindex k&ouml;nnen Sie mit dem Formular <b>frmVolltextsuche <\/b>und der Proze-dur <b>FindWord <\/b>schlie&szlig;lich nach Begriffen suchen. Je nach Suchoption &#8211; ganzes Wort, Wortanfang oder Teil &#8211; wird ein anderes SQL-Statement auf Basis der Tabelle <b>tblFulltextWords <\/b>generiert. Soll der Begriff als Teil eines Wortes vorkommen, dann sieht das Statement so aus:<\/p>\n<pre>&quot;SELECT ID FROM tblFulltextWords WHERE Word LIKE &quot;&apos;*&quot; &amp; sWord &amp; &quot;*&apos;&quot;<\/pre>\n<p>Die IDs der passenden W&ouml;rter werden dann in einer Schleife weiterverarbeitet, wobei f&uuml;r jede ID wiederum ein Recordset auf die Tabelle <b>tblFulltextFind <\/b>ge&ouml;ffnet wird, das nach dieser Wort-ID gefiltert ist.<\/p>\n<p>Dessen Datens&auml;tze werden durchlaufen und &uuml;ber die bereits erw&auml;hnte Abfrage <b>qry_FulltextTablesFields <\/b>werden die zu den gelieferten Feld- und Tabellen-IDs geh&ouml;rigen Namen ermittelt. Damit im Ergebnislistenfeld auch noch ein Teil der Fundstelle angezeigt werden kann, wird mit <b>Dlookup <\/b>jeweils der Feldinhalt ausgelesen. <\/p>\n<p>Es sprengte den Rahmen, wollte man die Prozedur genauer erl&auml;utern, denn sie ist reichlich komplex. Ein Hinweis sollte jedoch nicht fehlen: Die Ergebnisse werden dem Listenfeld als Werteliste &uuml;bergeben.<\/p>\n<p>Dieser String darf aber nicht mehr als 2.048 Zeichen lang sein. Wenn diese Limitierung und damit die Zahl der m&ouml;glichen Fundstellen aufgehoben werden sollte, dann m&uuml;sste man die Ergebniszeilen in eine tempor&auml;re Tabelle schreiben, die dann als Ergebnisunterformular verwendet werden k&ouml;nnte. <\/p>\n<p><b>Unzul&auml;nglichkeiten<\/b><\/p>\n<p>Die hier vorgestellte L&ouml;sung hat einige Nachteile, die sich durch zus&auml;tzliche Programmierung beheben lie&szlig;en:<\/p>\n<ul>\n<li class=\"aufz-hlung\">Man kann nur nach einem Begriff suchen, nicht nach einer Kombination mehrerer Begriffe. Sie k&ouml;nnen nach &#8222;Studium&#8220; suchen oder nach &#8222;Oxford&#8220;, nicht aber nach &#8222;Studium + Oxford&#8220;, was Textstellen finden sollte, die beide Begriffe enthalten. Dazu m&uuml;sste ein SQL-String im Suchformular dynamisch zusammengestellt werden, der im W&ouml;rter-Recordset beide Begriffe findet. Beide Begriffe k&auml;men dann in einem Feld vor, wenn sowohl die IDs mindestens zweier Datens&auml;tze der Tabelle <b>tblFulltextFind <\/b>&uuml;bereinstimmten sowie auch die Wort-IDs. Die Routine m&uuml;sste dazu deutlich erweitert werden.<\/li>\n<li class=\"aufz-hlung\">Der Suchindex ist immer auf dem Stand des letzten Tabellen-Scans. Wenn neue Datens&auml;tze mit Texten in die Datenbank eingegeben, ver&auml;ndert oder andere gel&ouml;scht werden, dann reflektiert sich dies nicht im Suchindex. Wenn der Suchindex st&auml;ndig aktualisiert werden soll, muss das Modul <b>mdlFulltextindex <\/b>mit zus&auml;tzlichen Funktionen ausgestattet werden, mit denen W&ouml;rter zum Index hinzugef&uuml;gt oder gel&ouml;scht werden k&ouml;nnen. Au&szlig;erdem m&uuml;sste jedes Textfeld der Eingabeformulare mit einer Ereignisprozedur <b>Nach Aktualisieren <\/b>ausgestattet werden, die den Feldinhalt an die Indizierroutinen &uuml;bergibt. Das L&ouml;schen von Datens&auml;tzen m&uuml;sste ebenfalls abgefangen und dabei ermittelt werden, welche Text-Tabellenfelder betroffen sind, damit gegebenenfalls Begriffe aus dem Index entfernt werden k&ouml;nnen. Der Aufwand f&uuml;r all dies w&auml;re erheblich.<\/li>\n<li class=\"aufz-hlung\">Die Suche findet zwar Datens&auml;tze in Tabellen der Datenbank, die den Begriff enthalten, und zeigt diese an. In der Realit&auml;t werden Sie aber dem Anwender keine Tabellen zu Gesicht kommen lassen, sondern m&ouml;glichst ausschlie&szlig;lich Formulare. Welches Formular verwendet nun aber eine gefundene Tabelle Per Code l&auml;sst sich das kaum ermitteln. Deshalb w&auml;re zus&auml;tzlich eine Hilfstabelle einzubinden, die die Namen der Tabellen des Suchindex und ihre Felder mit Formular- und Steuerelementnamen verkn&uuml;pft. Dann kann der Suchroutine mitgeteilt werden, welches Formular zu &ouml;ffnen ist und welches Steuerelement markiert wird, wenn der gefundene Datensatz dem Anwender auf den Schirm gebracht werden soll.<\/li>\n<\/ul>\n<p><b>Zusammenfassung<\/b><\/p>\n<p>Ein Volltextindex erm&ouml;glicht es sehr schnell, beliebige Begriffe im gesamten Datenbestand einer Datenbank zu finden. Der Programmieraufwand daf&uuml;r ist, wie Sie gesehen haben, nicht unerheblich. Dabei pr&auml;sentieren die dargestellten Routinen lediglich das Notwendigste.<\/p>\n<p>Immerhin haben Sie nun ansatzweise eine Vorstellung davon, wie professionelle Suchmaschinen zu Werke gehen. Wenn Sie die Limitierungen der vorgestellten L&ouml;sung billigen, dann k&ouml;nnen Sie das Modul <b>mdlVolltextindex <\/b>sowie die vier zugeh&ouml;rigen Tabellen sofort in Ihrer Datenbank einsetzen.<\/p>\n<p class=\"zwischen-berschriftquellen\">Quellen<\/p>\n<p class=\"quellen\">[1] S&uuml;dsturm &#8211; die bessere Beispieldatenbank, Ausgabe 6\/2006, Shortlink 411<\/p>\n<h3>Downloads zu diesem Beitrag<\/h3>\n<p>Enthaltene Beispieldateien:<\/p>\n<p>volltext.mdb<\/p>\n<p><a href=\"..\/fileadmin\/beispiele\/9EAFEE45-C530-47B8-8441-36AAE194FB93\/aiu_440.zip\">Download<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Erst nach Fertigstellung eines Datenbankprojekts f&auml;llt Ihrem Auftraggeber pl&ouml;tzlich noch ein, dass er noch ein unentbehrliches Feature ben&ouml;tigt: Er will alle Tabellen der Datenbank global nach bestimmten Stichw&ouml;rtern durchsuchen k&ouml;nnen, etwa indem er den Namen &#8222;Meyer&#8220; in ein Suchfeld eingibt und schnell s&auml;mtliche Vorkommen in einer Ergebnisliste erh&auml;lt. Hieraus will er die entsprechenden Stellen anschlie&szlig;end aufrufen. Einfach, denken Sie, und signalisieren Ihrem Kunden: &#8222;O.K., alles kein Problem!&#8220; Doch bei n&auml;herer Betrachtung f&auml;llt Ihnen auf, dass es da mehr zu bedenken gibt, als zun&auml;chst vermutet &#8230;<\/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":[66012007,662007,44000036,44000027],"tags":[],"class_list":["post-55000440","post","type-post","status-publish","format-standard","hentry","category-66012007","category-662007","category-Daten_suchen_sortieren_gruppieren","category-Loesungen"],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v20.9 (Yoast SEO v27.3) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>Universelle Volltextsuche - 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\/Universelle_Volltextsuche\/\" \/>\n<meta property=\"og:locale\" content=\"de_DE\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Universelle Volltextsuche\" \/>\n<meta property=\"og:description\" content=\"Erst nach Fertigstellung eines Datenbankprojekts f&auml;llt Ihrem Auftraggeber pl&ouml;tzlich noch ein, dass er noch ein unentbehrliches Feature ben&ouml;tigt: Er will alle Tabellen der Datenbank global nach bestimmten Stichw&ouml;rtern durchsuchen k&ouml;nnen, etwa indem er den Namen &quot;Meyer&quot; in ein Suchfeld eingibt und schnell s&auml;mtliche Vorkommen in einer Ergebnisliste erh&auml;lt. Hieraus will er die entsprechenden Stellen anschlie&szlig;end aufrufen. Einfach, denken Sie, und signalisieren Ihrem Kunden: &quot;O.K., alles kein Problem!&quot; Doch bei n&auml;herer Betrachtung f&auml;llt Ihnen auf, dass es da mehr zu bedenken gibt, als zun&auml;chst vermutet ...\" \/>\n<meta property=\"og:url\" content=\"https:\/\/access-im-unternehmen.de\/Universelle_Volltextsuche\/\" \/>\n<meta property=\"og:site_name\" content=\"Access im Unternehmen\" \/>\n<meta property=\"article:published_time\" content=\"2021-02-11T21:08:41+00:00\" \/>\n<meta property=\"og:image\" content=\"http:\/\/vg09.met.vgwort.de\/na\/2eae004a3a244737a93b50bff44beea5\" \/>\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=\"16\u00a0Minuten\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Universelle_Volltextsuche\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Universelle_Volltextsuche\\\/\"},\"author\":{\"name\":\"Andr\u00e9 Minhorst\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#\\\/schema\\\/person\\\/13395c4bcd7d7963efe33be9c584d93f\"},\"headline\":\"Universelle Volltextsuche\",\"datePublished\":\"2021-02-11T21:08:41+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Universelle_Volltextsuche\\\/\"},\"wordCount\":3009,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Universelle_Volltextsuche\\\/#primaryimage\"},\"thumbnailUrl\":\"http:\\\/\\\/vg09.met.vgwort.de\\\/na\\\/2eae004a3a244737a93b50bff44beea5\",\"articleSection\":[\"1\\\/2007\",\"2007\",\"Daten suchen, sortieren, gruppieren\",\"L\u00f6sungen\"],\"inLanguage\":\"de\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/access-im-unternehmen.de\\\/Universelle_Volltextsuche\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Universelle_Volltextsuche\\\/\",\"url\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Universelle_Volltextsuche\\\/\",\"name\":\"Universelle Volltextsuche - Access im Unternehmen\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Universelle_Volltextsuche\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Universelle_Volltextsuche\\\/#primaryimage\"},\"thumbnailUrl\":\"http:\\\/\\\/vg09.met.vgwort.de\\\/na\\\/2eae004a3a244737a93b50bff44beea5\",\"datePublished\":\"2021-02-11T21:08:41+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Universelle_Volltextsuche\\\/#breadcrumb\"},\"inLanguage\":\"de\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/access-im-unternehmen.de\\\/Universelle_Volltextsuche\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"de\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Universelle_Volltextsuche\\\/#primaryimage\",\"url\":\"http:\\\/\\\/vg09.met.vgwort.de\\\/na\\\/2eae004a3a244737a93b50bff44beea5\",\"contentUrl\":\"http:\\\/\\\/vg09.met.vgwort.de\\\/na\\\/2eae004a3a244737a93b50bff44beea5\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Universelle_Volltextsuche\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/access-im-unternehmen.de\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Universelle Volltextsuche\"}]},{\"@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":"Universelle Volltextsuche - 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\/Universelle_Volltextsuche\/","og_locale":"de_DE","og_type":"article","og_title":"Universelle Volltextsuche","og_description":"Erst nach Fertigstellung eines Datenbankprojekts f&auml;llt Ihrem Auftraggeber pl&ouml;tzlich noch ein, dass er noch ein unentbehrliches Feature ben&ouml;tigt: Er will alle Tabellen der Datenbank global nach bestimmten Stichw&ouml;rtern durchsuchen k&ouml;nnen, etwa indem er den Namen \"Meyer\" in ein Suchfeld eingibt und schnell s&auml;mtliche Vorkommen in einer Ergebnisliste erh&auml;lt. Hieraus will er die entsprechenden Stellen anschlie&szlig;end aufrufen. Einfach, denken Sie, und signalisieren Ihrem Kunden: \"O.K., alles kein Problem!\" Doch bei n&auml;herer Betrachtung f&auml;llt Ihnen auf, dass es da mehr zu bedenken gibt, als zun&auml;chst vermutet ...","og_url":"https:\/\/access-im-unternehmen.de\/Universelle_Volltextsuche\/","og_site_name":"Access im Unternehmen","article_published_time":"2021-02-11T21:08:41+00:00","og_image":[{"url":"http:\/\/vg09.met.vgwort.de\/na\/2eae004a3a244737a93b50bff44beea5","type":"","width":"","height":""}],"author":"Andr\u00e9 Minhorst","twitter_card":"summary_large_image","twitter_misc":{"Verfasst von":"Andr\u00e9 Minhorst","Gesch\u00e4tzte Lesezeit":"16\u00a0Minuten"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/access-im-unternehmen.de\/Universelle_Volltextsuche\/#article","isPartOf":{"@id":"https:\/\/access-im-unternehmen.de\/Universelle_Volltextsuche\/"},"author":{"name":"Andr\u00e9 Minhorst","@id":"https:\/\/access-im-unternehmen.de\/#\/schema\/person\/13395c4bcd7d7963efe33be9c584d93f"},"headline":"Universelle Volltextsuche","datePublished":"2021-02-11T21:08:41+00:00","mainEntityOfPage":{"@id":"https:\/\/access-im-unternehmen.de\/Universelle_Volltextsuche\/"},"wordCount":3009,"commentCount":0,"publisher":{"@id":"https:\/\/access-im-unternehmen.de\/#organization"},"image":{"@id":"https:\/\/access-im-unternehmen.de\/Universelle_Volltextsuche\/#primaryimage"},"thumbnailUrl":"http:\/\/vg09.met.vgwort.de\/na\/2eae004a3a244737a93b50bff44beea5","articleSection":["1\/2007","2007","Daten suchen, sortieren, gruppieren","L\u00f6sungen"],"inLanguage":"de","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/access-im-unternehmen.de\/Universelle_Volltextsuche\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/access-im-unternehmen.de\/Universelle_Volltextsuche\/","url":"https:\/\/access-im-unternehmen.de\/Universelle_Volltextsuche\/","name":"Universelle Volltextsuche - Access im Unternehmen","isPartOf":{"@id":"https:\/\/access-im-unternehmen.de\/#website"},"primaryImageOfPage":{"@id":"https:\/\/access-im-unternehmen.de\/Universelle_Volltextsuche\/#primaryimage"},"image":{"@id":"https:\/\/access-im-unternehmen.de\/Universelle_Volltextsuche\/#primaryimage"},"thumbnailUrl":"http:\/\/vg09.met.vgwort.de\/na\/2eae004a3a244737a93b50bff44beea5","datePublished":"2021-02-11T21:08:41+00:00","breadcrumb":{"@id":"https:\/\/access-im-unternehmen.de\/Universelle_Volltextsuche\/#breadcrumb"},"inLanguage":"de","potentialAction":[{"@type":"ReadAction","target":["https:\/\/access-im-unternehmen.de\/Universelle_Volltextsuche\/"]}]},{"@type":"ImageObject","inLanguage":"de","@id":"https:\/\/access-im-unternehmen.de\/Universelle_Volltextsuche\/#primaryimage","url":"http:\/\/vg09.met.vgwort.de\/na\/2eae004a3a244737a93b50bff44beea5","contentUrl":"http:\/\/vg09.met.vgwort.de\/na\/2eae004a3a244737a93b50bff44beea5"},{"@type":"BreadcrumbList","@id":"https:\/\/access-im-unternehmen.de\/Universelle_Volltextsuche\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/access-im-unternehmen.de\/"},{"@type":"ListItem","position":2,"name":"Universelle Volltextsuche"}]},{"@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\/55000440","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=55000440"}],"version-history":[{"count":0,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/posts\/55000440\/revisions"}],"wp:attachment":[{"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/media?parent=55000440"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/categories?post=55000440"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/tags?post=55000440"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}