August 15, 2020, 06:43:47

Neuigkeiten:

Wenn ihr euch für eine gute Antwort bedanken möchtet, im entsprechenden Posting einfach den Knopf "sag Danke" drücken!


suche in allen tabellen nach String

Begonnen von martie01, Juli 24, 2020, 22:01:49

⏪ vorheriges - nächstes ⏩

ebs17

Demjenigen, der irgendetwas irgendwo irgendwie sucht, muss wirklich geholfen werden. Es ist ja auch viel toller, eine solche Suche  auf einen großen wirren Haufen loszulassen, statt wie ein Apotheker gezielt an einen Schrank zu gehen, darin eine Schublade, darin ein Fach zu begutachten auf Inhalt. Letzteres ist ja einfach nur langweilig, kurz und schnell.

Allemal ein Grund, eine solche Volltextsuche gleich zum Standard zu machen.

Mit freundlichem Glück Auf!

Eberhard

crystal

Hallo derArb,

dass ein Chef meist sehr wenig Verständnis für Struktur und Aufbau einer Datenbank hat, liegt daran, dass er/sie mehr verdient und sich daher mit solchen Fragen an seine Mitarbeiter wenden darf...

Der Begriff (eher wohl Begriffs-Teil) "Xylo" könnte auf "Xylophon" hinweisen oder irgendwelche Zucker. Also kann schon eingeschränkt werden, ob er im Zusammenhang mit Musik oder mit biochemischen Texten vorgekommen sein könnte.

Also kannst du eine Suche nach diesem Begriff von vornherein schon einschränken, indem du Personal-Tabellen, Auto-Flotten, Kunden-Adressen etc. ausschließt.

Wenn wir nun bei "Musik" und "Biochemie" bleiben, kannst du weiter eingrenzen, in welchen Datenbeständen dieser Text vorkommen könnte. Da die Datenbank kaum beides enthalten wird (es sei denn es handelt sich z. B. um das Text-Archiv eines Print-Mediums), kannst du weiter entscheiden, in welchen Tabellen der Begriff an welchen Stellen vorkommen könnte. Vermutlich wird es irgendein beschreibendes Textfeld sein.

So kannst du dich - evtl. nach kurzer Befragung des Chefs/der Chefin - deterministisch einer etwas konkreteren, aber gezielten Abfrage nähern und diese - "Moment kurz, Chef" - mal eben schnell formulieren und ausführen: suche im Feld "Beschreibung" der Tabelle "BioChemie" nach dem Text "*xylo*" bzw.
"select * from BioChemie where Beschreibung like '*xylo*'".

Die GESAMTE Datenbank mit all ihren Tabellen nach "Xylo" abzusuchen, ist meiner Meinung - nach wie vor - falsch und "mit Kanonen auf Spatzen" oder eher sogar "mit Kanonen auf Mücken" geschossen, einmal von der Performance abgesehen. Sicher ist es möglich, "sowas" zu realisieren, denn Access (wie auch andere Datenbanken) verwaltet Tabellen-Definitionen ja auch nur in Tabellen, auf die man zugreifen kann. Aber nicht jede Frage "eines Chefs" ist sinnvoll und muss mit "ja, kann ich machen" beantwortet werden.

Ich bin nach wie vor der Meinung, dass der Wunsch, "einen String" von "der Datenbank" finden zu lassen, eher als "Unfug" zu klassifizieren ist. Im Übrigen muss "ein Chef" auch noch befragt werden, ob der Text "Xylo" wirklich in "der Datenbank" vorkam (und wenn ja wo ungefähr) oder vielleicht bei der Morgenlektüre der Tageszeitung am Frühstückstisch oder gar im Radio.

Lange Rede, kurzer Sinn und bevor diese Diskussion ins Lächerliche oder Zynische ausartet: ich möchte dir empfehlen, ein paar wenige Abfragen vorzubereiten, mit denen du gezielt in verschiedenen Datenfeldern verschiedener, aber bestimmter Tabellen z. B. nach solch prägnanten (?) Texten wie "Xylo" suchen kannst (falls mal wieder ein Chef vorbeikommt), statt zu versuchen, EINE Abfrage auf die gesamte Datenbank "abzufeuern".

Wenn es sich bei deiner Datenbank eher um ein Textarchiv (s. o.) handeln sollte, brauchst du auch nicht "die Datenbank" nach "Xylo" befragen, sondern nur die eine Tabelle mit dem beschreibenden Feld.

Und wenn du es nicht schaffst, ein paar wenige, konkrete Abfragen vorzubereiten, hast du möglicherweise die Struktur und die inneren Zusammenhänge "der Datenbank" (noch) nicht verstanden.

Meine Kommentare sollen kein Angriff auf dich persönlich sein, ich möchte dich nur bitten, etwas mehr zielgerichtete Überlegungen anzustellen, dir über die Struktur "der Datenbank" klar zu werden und solch unpräzise Fragen "eines Chef" kritisch zu hinterfragen.

Und zur Beruhigung: dies ist dann auch mein gewollt letzter Kommentar in diesem Thread.

Grüße,
crystal

Wer Fehler in meinen Antworten findet, darf sie behalten, muss sie aber kommentieren. ;-)
Dies ist keineswegs arrogant gemeint, sondern soll nur unterstreichen, dass meine Antworten - natürlich - nicht immer fehlerfrei sind und sein können.
Devise: bitte immer erst selbst probieren!

crystal

@ebs17
Völlig richtig.
Nur sollte sich auch eine "Klartext-Suche" konkret auf Klartext-Felder einer (oder mehrerer) Tabellen beziehen und nicht auf "die Datenbank". In solchen Klartext-Feldern zu suchen, ist ein Abenteuer für sich, aber immer sinnvoller, als "alle Felder aller Tabellen" abzusuchen.
Wer Fehler in meinen Antworten findet, darf sie behalten, muss sie aber kommentieren. ;-)
Dies ist keineswegs arrogant gemeint, sondern soll nur unterstreichen, dass meine Antworten - natürlich - nicht immer fehlerfrei sind und sein können.
Devise: bitte immer erst selbst probieren!

derArb

@crystal:
Zitat....dass ein Chef meist sehr wenig Verständnis für Struktur und Aufbau einer Datenbank hat, liegt daran, dass er/sie mehr verdient und sich daher mit solchen Fragen an seine Mitarbeiter wenden darf...
Damit hast Du Dich leider disqualifiziert bei mir.
Meine Risiken, die ich in 45 Berufsjahren für meine Mitarbeiter eingegangen bin, bilden nicht eine Sekunde lang
das ab, was Du uns hier zu vermitteln versuchst.
Meine IT-Abteilungen hatten immer wieder enmpfohlen, "Datenbanken quer zu lesen".
Ich kannte und kenne auch erfahrungsmässig deren (auch Deine) Empfehlungen für weitere Vorgehensarten...
Erkläre mir mal, wie so ein "QUERLESEN" denn bei völlig unsortierten Inhalten von Tabellen brauchbare Ergebnisse in weiteren anderen Auswertungen ergeben soll.

ich erwarte keine Antwort,wie Du es schon freundlicherweise angedroht hattest.


 

martie01

Hallo ,

ist ja schon irgendwie traurig-witzig, wie es im Laufe der Runde schon gar nicht mehr um das eigentliche Thema geht.

DF6GL, ich habe deine Tipps befolgt, bekomme trotzdem die Fehlermeldung: Objektvariable oder with Blockvariable nicht festgelegt. Snopp has come across...

Wenn ich das lokal Fenster verfolge, würde ich sagen, das er die Tabelle gar nicht findet?!

Bin aber auch eben nicht der Fachmann in diesem Gebiet.

Eine Idee? :o

ebs17

Juli 29, 2020, 23:18:01 #20 Letzte Bearbeitung: Juli 29, 2020, 23:43:50 von ebs17
Zum Löschen einer Tabelle muss die Tabelle vorhanden sein.
Zum Anlegen einer Tabelle darf die Tabelle noch nicht vorhanden sein.
Ist das jeweils nicht der Fall, darf man mit einer entsprechenden Fehlermeldung rechnen.

Dem kann man begegnen, indem man per On Error Resume Next blindlings Fehler und deren Meldungen ignoriert. Man könnte aber auch vorher prüfen, ob es die Tabelle gibt. Unter dem Namen TableExists gibt es sehr wahrscheinlich entsprechende veröffentlichte Lösungen.

Wenn man dann nach Texten in Datumsfeldern oder Zahlenfeldern filtert, sollte man sich auf weitere Fehler (Datentypfehler) gefasst machen - wenn man die Sinnfrage schon übergangen hat. Auch sollte man die Nichtberücksichtigung von Systemtabellen in seine Überlegungen einbeziehen, wenn "alle" keine Worthülse ist.

Zitatdas eigentliche Thema
Die Grundidee der Hinweise ist ja - und das sollte man inhaltlich zur Kenntnis nehmen wenn nicht gar verstehen wenn nicht gar zum eigentlichen Prinzip machen - dass man in einem geordneten Laden mit eigener Übersicht nicht überall nach etwas suchen muss, sondern auf Grund der Aufgabenstellung weiß, in welcher Tabelle der normalisierten Datenbank und genauer in welchem Feld sich bestimmte Informationen befinden werden, wenn sie vorhanden sind.
Solche Standardisierung hat u.a. dazu geführt, dass wir Autos aus der Serienproduktion fahren und nicht mehr Postkutschen mit einzeln designten Rädern und Achsen.
Mit freundlichem Glück Auf!

Eberhard

derArb

ZitatSolche Standardisierung hat u.a. dazu geführt, dass wir Autos aus der Serienproduktion fahren und nicht mehr Postkutschen mit einzeln designten Rädern und Achsen.
Sie führte auch dazu, dass wir nicht Standardisiertes wegwerfen und Standardisiertes nach geplanter Nutzungszeit obsolet machen.
Komischerweise agieren inzwischen weltweite Geheimdienste wie Schrotthändler.
Sie sammeln einfach alles, um es irgendwann, wenn die Suchalgorithmen schlau genug sind, in ihre Datenbanken einarbeiten zu können.
Sie haben aber mal sicherheitshalber die Werte gesichert. Kommt dann ein Kunde und fragt nach einer Frontfensterdichtung eines Jaguar E aus dem Jahr 1968, dann antwortet der Datenspezialist, dass er leider erst
bei der Erfassung von Buchstabe "B" ist und der Lagerspezialist sagt, dass er mal in dem Bereich der
datenbankmässig noch nicht integrierten Teile einer aufgekauften Konkurrenzfirma mal nachschauen könne.
Noch viel besser und unschlagbar ist ein motivierter Lagerspezialist, der auch die etwas vernachlässigten Bereiche des Lagers kennt.
Eine grosse Hilfe für ihn wäre dann eine "querlesende" Suchroutine in dem Datenwust der übernommenen Konkurrenzfirma oder einfach noch viel besser ein fotografisch optimiertes Gedächtnis, wie es z.B. Auto-Gebrauchtteilehändler haben. Die brauchen keine Datenbank dafür.
Die wissen im Kopf, ob sie für die diversen Oldtimer oder Kutsche das passende Teil haben.
Wie sagte Theodor Fontane?: "Es ist ein weites Feld".
Praxis hits the theory.

ebs17

ZitatNoch viel besser und unschlagbar ist ein motivierter Lagerspezialist, der auch die etwas vernachlässigten Bereiche des Lagers kennt.
Der sucht aber nicht über alles, sondern holt einfach ab. Das schneller, als er den Computer einschalten würde, und das "Programm" wäre was für die Kinder zum Spielen.
Mit freundlichem Glück Auf!

Eberhard

derArb

Nein, der setzt sein Hirn ein und verlässt sich nicht stur auf irgendwelche KI-Intelligenzen etc.
Verlass doch einfach mal Dein Wolken-Kuckuksnest und erkundige Dich bei den Praktikern.

martie01

Gut, also ich habe gelernt-> Ich suche  nicht blind in ALLLEN Tabellen sondern nur in bestimmten.
Wie bekomme ich denn eine Abfrage hin, die sich auf fest definierte Tabellen bezieht?


derArb

Juli 31, 2020, 21:51:10 #25 Letzte Bearbeitung: Juli 31, 2020, 21:58:20 von derArb
Hallo,
ich würde eine LIKE-Suchroutine mit Wildcards benutzen, oder vor Auslösen des Suchvorgangs
über eine Optionsgruppe verschiedene LIKE-Suchroutinen auswählbar machen.
Ausserdem würde ich alle Codezeilen mit
On Error Resume Next erst einmal auskommentieren,
um feststellen zu können, welche Fehler da ignoriert werden sollen.
Später würde ich sie mit einer sauberen Fehlerabarbeitungsroutine ersetzen.
Auskommentieren einer VBA-Codezeile wird mittels eines einfachen Hochkommatas (shift-#) getätigt.
Der Vorteil ist, dass man komplizierte Codezeilen nicht löschen muss, sondern vorübergehend für den
Compiler einfach mal aus seinen abzuarbeitenden Codezeilen ausblenden, dem Programmierer aber seine
wertvollen Codezeilen erhalten kann.
Ich hab diese Möglichkeit benutzt, um Dir meine alt/neu Vorschläge zu unterbreiten.

ich hab den folgenden Code bei mir in einer DB mit ca. 100.000 Datensätzen getestet, was jetzt nicht unbedingt
viel ist, aber zumindest zu einem passablen Zwischenergebnis führte.
Die Suchgeschwindigkeit über alle Tabellen und dortigen Feldern ergab bei mir eine Suchzeit < 7 sek. mit einer
LiKE-Suche mit dem Prinzip "*.*"

Grundsätzlich bekommst Du damit allgemeine Datenhinweise, durch welche Du nun durch weitere Selektionen per SQL
oder dem langsameren VBA Deine Ergebnisse erzielen kannst.
Diese Hinweise sagen aber nur aus, wieviele (Ocurrence) Treffer in welcher Tabelle und einem dortigen Feld
vorhanden sind.

Option Compare Database
Option Explicit

Private Sub CreateSnoop()

    'On Error Resume Next 'alt
    'Auf Fehler warten, um ihn zu begreifen 'neu
   
    Dim db As Dao.Database
    Dim td As Dao.TableDef
    Dim F As Dao.Field
   
    Set db = CurrentDb()
    Set td = db.CreateTableDef("tblSNOOP")

    Set F = td.CreateField("Occurence", DB_LONG)
    td.Fields.Append F
    Set F = td.CreateField("Table", DB_TEXT)
    F.AllowZeroLength = True
    td.Fields.Append F
    Set F = td.CreateField("Field", DB_TEXT)
    F.AllowZeroLength = True
    td.Fields.Append F

    db.TableDefs.Append td

    db.Close

End Sub

Private Sub DeleteSnoop()

    'On Error Resume Next 'alt
    'Auf Fehler warten, um ihn zu begreifen 'neu
   
    Dim db As Dao.Database

    Set db = CurrentDb()
    db.TableDefs.Delete "tblSNOOP"

    Set db = Nothing

End Sub

Public Sub Go(SnoopFor As String)

    Call DeleteSnoop
    Call CreateSnoop
    Call Snoop(SnoopFor)

End Sub

Private Sub Snoop(SnoopFor As String)

    On Error GoTo Snoop_Err

    Dim db As Dao.Database
    Dim S As Dao.Recordset
    Dim T As Dao.Recordset
    Dim td As TableDef
    Dim L As Long
    Dim F As Long
    Dim criteria As String
    Dim occ As Long

    Set db = CurrentDb()
    'Set S = db.OpenRecordset("tblSNOOP", dbOpenDyanaset) 'alt
    Set S = db.OpenRecordset("tblSNOOP", dbOpenTable) 'neu
       
    'cycle through the tables
    For L = 0 To db.TableDefs.Count - 1

        Set td = db.TableDefs(L) 'set the table def

        If Not (td.Connect = "") Then 'is this table attached ?
       
            Set T = db.OpenRecordset(td.Name, dbOpenSnapshot) 'set the recordset

            'sTABLE.Caption = td.Name: DoEvents 'set caption

            For F = 0 To td.Fields.Count - 1 'now cycle through the fields as try to locate value

                'sFIELD.Caption = td.Fields(F).Name: DoEvents 'set caption
               
                'criteria = "CStr('' & [" & td.Fields(F).Name & "]) Like '" & SnoopFor & "'" 'alt
                criteria = "CStr('' & [" & td.Fields(F).Name & "]) Like '*" & SnoopFor & "*'" 'neu
                T.FindFirst criteria
               
                If Not (T.NoMatch) Then
                   
                    occ = 0
                    Do While Not (T.NoMatch) 'now are there any more ?
                   
                        T.FindNext criteria
                        occ = occ + 1

                    Loop

                    S.AddNew
                    S!Occurence = occ
                    S!Table = td.Name
                    S!Field = td.Fields(F).Name
                    S.Update
               
                End If

            Next F

        End If

    Next L

    T.Close
    S.Close
    Set db = Nothing

Snoop_Exit:
    DoCmd.OpenTable "tblSNOOP"
   
    Exit Sub

Snoop_Err:
    MsgBox Error$ & " : Snoop has come across an unforseen problem. Please contact the developer.", 16, "Message"
    Resume Snoop_Exit

    Exit Sub

End Sub

crystal

August 01, 2020, 21:27:35 #26 Letzte Bearbeitung: August 02, 2020, 01:42:03 von crystal
Habe mich entschlossen, den Eintrag zu löschen.
Wer Fehler in meinen Antworten findet, darf sie behalten, muss sie aber kommentieren. ;-)
Dies ist keineswegs arrogant gemeint, sondern soll nur unterstreichen, dass meine Antworten - natürlich - nicht immer fehlerfrei sind und sein können.
Devise: bitte immer erst selbst probieren!

derArb

Hallo martie01,
ZitatDein Zitat in PN: ...Ich habe den Code in ein allg. Modul kopiert und aufgerufen.
Er löscht die Tabelle, erstellt eine Neue, macht dann jedoch Laufzeitfehler 91 und steigt bei T.close aus.
If Not (td.Connect = "") Then 'is this table attached ?Das funktioniert m.E. nur mit verknüpften Tabellen aus einem Backend kommend.
So ist es zumindest bei mir.
Sollte Deine DB nicht aufgeteilt sein in Frontend und Backend, dann ersetze das mit
If Left$(td.Name, 4) <> "Msys" Then 'neue Version - is this table attached ?In #11 gibt es noch einen Flüchtigkeitsfehler.
Es darf nicht heissen
Set S = db.OpenRecordset("tblSNOOP", dbOpenDyanaset) sondern
Set S = db.OpenRecordset("tblSNOOP", dbOpenDynaset)Das hatte ich nicht gleich erkannt und auf das langsamere dbOpenTable geändert.
Du kannst mir ja in PN antworten. Nur solltest Du da auch meine PN an Dich lesen.

Ganz allgemein finde ich diese Suchroutine für das gezielte Auffinden von Daten nicht so optimal.
Erstens bläht das dauernde Löschen und Neuerstellen von Tabellen per Code die DB sehr schnell auf
und sie muss immer wieder komprimiert/repariert werden, um den "Datenmüll" zu entfernen und
zweitens fehlt eine 2. Coderoutine, um gezielt zu einem dieser vielen gefundenen Datensätze springen zu können.
Ich würde das mit 2 Listenfeldern lösen.
Listenfeld_1 zeigt die gefundenen Tabellen und Tabellenfelder auf. Nicht gruppiert und nicht als Anzahl.
Listenfeld_2 zeigt bei Click auf einen Datensatz in Listenfeld_1 die dazugehörigen detaillierten Datensätze an.
Die auszuwerten dürfte dann ja dann kein Problem mehr bedeuten.


martie01

Hy,
super, genau , das war es   ;D

jetzt funktioniert es...
Danke vielmals.....