August 15, 2020, 07:47:24

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 ⏩

martie01

Hallo,

ich würde gerne in der Datenbank in allen Tabellen nach z.B. einen Namen suchen.
Es gab in der knowhow.mdb schon einmal soetwas, was jedoch bei mir nicht funktioniert.
Das hiess snoop for. Es geht in die Fehlermeldung und findet nichts.
Kann mir jemand bitte weiterhelfen?
Option Compare Database
Option Explicit


Private Sub btn_FIND_Click()

    Dim SnoopFor As String

    If Not (IsNull([SEARCH])) Then

        [lbl_SEARCH].Visible = True
        SnoopFor = [SEARCH]
        Call Go(SnoopFor)

    Else

        [SEARCH].SetFocus
        MsgBox "You must enter some search Text.", 16, "Data Snoop"

    End If

End Sub

Private Sub CreateSnoop()

    On Error Resume Next
   
    Dim db As Database
    Dim td As TableDef
    Dim F As 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
   
    Dim db As Database

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

    db.Close

End Sub

Private 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 Database
    Dim S As Recordset
    Dim T As Recordset
    Dim td As TableDef
    Dim L As Integer
    Dim F As Integer
    Dim criteria As String
    Dim occ As Long

    Set db = CurrentDb()
    Set S = db.OpenRecordset("tblSNOOP", DB_OPEN_DYNASET)
       
    '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, DB_OPEN_SNAPSHOT) '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 & "'"
                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
    db.Close

Snoop_Exit:
    DoCmd.Close A_FORM, Me.Name
    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

MzKlMu

Hallo,
mal ne Frage, wieso kann es bei dir sein, dass ein Name in mehreren Tabellen vorkommt?
Gruß
Klaus

DF6GL

Hallo,

ZitatEs geht in die Fehlermeldung

sehr informativ..

WIE lautet die Fehlermeldung und WO (bei welcher Codezeile)  tritt sie auf?

Zum Debuggen:

Haltepunkt an den Anfang des Codes setzen, mit Einzelschritt Zeile für Zeile durchlaufen und dabei die Varaiablen-Inhalte prüfen..

derArb

Hallo,
eine einfache Version ist folgende.
Es ist eine Optionsgruppe notwendig, um Like *.* oder Like .* auswählen zu können.
Die Ergebnisse werden in einem Listenfald angezeigt.

Private Sub Suchenfeld_AfterUpdate()
'Suchen über alle Tabellenfelder
' mit + kann man mehrere Suchparameter als UND-Suchkondition eingeben
' mit dem Leerzeichen kann man Suchparameter als ODER-Suchkondition eintragen
On Error GoTo Fehler
Dim varInhalt  As Variant
Dim intI       As Integer
Dim strFilter  As String
Dim strFilter1 As String
Dim intFeld    As Integer
Dim strMuster  As String
Dim strSQL, strsql1 As String
Dim strlink As String
Dim ZwischenSpeicher As String
Dim rs As DAO.Recordset
Dim strLike As String
  Einlesen = ""
'################################################################################
'######### ***** tbl_Kunde mit gewünschter Tabelle austauschen  ***** ###########
  Einlesen = "SELECT * FROM tbl_Kunde"
'################################################################################
'################################################################################
  Set rs = CurrentDb.OpenRecordset(Einlesen)
   
  If Nz(Me!Suchenfeld, "") = "" Then
    MsgBox "Kein Eintrag im Suchfeld"
    Exit Sub
  End If
 
  Select Case SuchrahmenAuswahl 'Suchmethode wechseln (Like *.* oder Like .*)
    Case 1:  strLike = "*"
    Case 2: strLike = ""
  End Select
 
  ZwischenSpeicher = Me!Suchenfeld
  Me!Suchenfeld.AllowAutoCorrect = False
  strMuster = Replace(Me!Suchenfeld, "+", " + ")
  strMuster = Replace(StrConv(strMuster, vbProperCase), "  ", " ")
   
  If Nz(Me!Suchenfeld) <> "" Then
   intFeld = rs.Fields.count
   varInhalt = Split(strMuster, " ")
   For intI = LBound(varInhalt) To UBound(varInhalt)
     If Len(varInhalt(intI)) > 0 Then
        If varInhalt(intI) = "+" Then
           strlink = " And ("
          Else
           For intFeld = 1 To rs.Fields.count
             If Len(strFilter) > 0 Then strFilter = strFilter & " Or "
                strFilter = strFilter & "[" & rs.Fields(intFeld - 1).Name _
                & "] Like '" & strLike & varInhalt(intI) & "*'"
           Next intFeld
           If Len(strFilter1) > 0 Then
              strFilter1 = strFilter1 & strlink & strFilter & ")"
              strFilter = ""
             Else
              strFilter1 = "(" & strFilter & ")"
              strFilter = ""
           End If
           strlink = " OR ("
        End If
     End If
   Next intI
   Einlesen = Einlesen & " Where " & strFilter1
   Me!LstVollsuche.RowSource = Einlesen
  End If
       
  Me!Suchenfeld = ZwischenSpeicher
  Me!Suchenfeld.SetFocus
  rs.Close
  Set rs = Nothing
exit_Fehler:
Exit Sub
Fehler:
MsgBox "Fehler. Die Abfrage ist entweder zu komplex oder ein anderer Fehler ist aufgetreten. " & vbCrLf & _
"Versuchen Sie es mal alternativ mit dem '+' Zeichen im Suchtext"
Resume exit_Fehler
End Sub

DF6GL

Juli 25, 2020, 14:37:11 #4 Letzte Bearbeitung: Juli 25, 2020, 14:51:44 von DF6GL
Hallo,

@derArb:

Schwerpunkt liegt hierauf (auch wenn's nicht ganz zu verstehen ist):

Zitatin der Datenbank in allen Tabellen nach z.B. einen Namen suchen

derArb



crystal

Juli 25, 2020, 15:26:01 #7 Letzte Bearbeitung: Juli 25, 2020, 15:39:43 von crystal
@martie01

Vermutlich hast du einfach nur die Code-Sequenz kopiert, aber im Formular die beiden Felder
Search (Textfeld) und
lbl_Search (zugehöriges Bezeichnungsfeld)
nicht angelegt, auf die sich der Code bezieht.
Hast du im Formular auch btn_FIND angelegt und im VB-Editor mal "Debuggen->Kompilieren" geklickt?
Wohinein hast du den fremden Code kopiert (sollte ein eigenes Formular sein)?

Gruß,
crystal

PS:
Der fremde Code ist eher dazu gedacht, einen String in den Tabellen zu finden, solange die Applikation sich noch in der Entwicklung befindet, NICHT jedoch für den "Produktions-Betrieb". Er schreibt die Ergebnisse in eine extra dafür angelegte Tabelle namens "tblSnoop". Ansonsten: siehe Frage von Klaus:

ZitatHallo,
mal ne Frage, wieso kann es bei dir sein, dass ein Name in mehreren Tabellen vorkommt?
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

Noch ein Nachtrag:

im Internet findet sich folgender Beitrag:

https://www.devhut.net/2011/08/18/ms-access---vba---determine-in-which-table-a-field-is-located/

Vielleicht hilft das ja auch weiter...

Gruß,
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!

martie01

Hallo,
est einmal vielen Dank für die Antworten
- ich möchte mir gerne in der Datenbank zu irgendwelchen Schnipseln wie Namen, Vorgangsnr ,.. anzeigen lassen, was die Datenbank dazu findet.
-das Makro steigt gleich am Anfang aus: Methode oder Datenobjekt nicht gefunden- >  s.FindFirst Criteria
-das Search (Textfeld) und lbl_Search (zugehöriges Bezeichnungsfeld) und extra Formular hatte ich drin ;)
-es müssen nicht ALLE Tabellen sein. Es sind halt jedoch Einige.
-der link führt ins Nevana

ich suche so etwas wie das hier: https://www.add-in-world.com/katalog/ac-globalesuche/
(P.S. funktioniert nicht für 64bit)

grüße

DF6GL

Hallo,

habe den Code mal nachgestellt, die Deklarationen korrigiert  und die Formular-Referenzen eliminiert.  Der Code tut das, was er soll: er listet in einer Tabelle die Tabellennamen und die Felder auf, in denen der Suchtext vorkommt.

Option Compare Database
Option Explicit




Private Sub CreateSnoop()

    On Error Resume Next
   
    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
   
    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)
       
    '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 & "'"
                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

-Speicher den Code in ein neues Standardmodul.
- rufe im Direktfenster die Sub auf:   

call Go ("DeinSuchText")

crystal

Sorry - korrigierter Link:

https://www.devhut.net/2011/08/18/ms-access-%e2%80%93-vba-%e2%80%93-determine-in-which-table-a-field-is-located/

Zitat- ich möchte mir gerne in der Datenbank zu irgendwelchen Schnipseln wie Namen, Vorgangsnr ,.. anzeigen lassen, was die Datenbank dazu findet.

Dieser Satz ist so natürlich falsch, nicht die Datenbank sucht und findet, sondern deine Abfrage.
Hört sich dumm an, aber ich meine: deine Datenbank kann ja selbst nichts finden, sondern du musst (genau) sagen, wonach du suchst.

Entscheident ist hier doch, dass du nicht nach Datenfeld-Namen, sondern nach deren Inhalten suchst. Da sollte es doch möglich sein, das etwas einzuschränken und genauer zu benennen.

Eine Dantenbank kann ja durchaus Dutzende von Tabellen enthalten. Suchen beziehen sich aber i d. R. immer auf sehr wenige Tabellen, z. B. "Suche nach Personen", Suche nach Kunden", "Suche nach Produkten".

Es macht m. E. überhaupt keinen Sinn, die gesamte Datenbank nach dem Text "Maria" abzusuchen (auch noch mit Wildcards und dem like-Operator), der in irgendwelchen Feldern irgendwelcher Tabellen steht. Was nutzt es dir, wenn ein solcher Suchlauf z. B. findet:
"Maria" in Feld "Vorname" in Tabelle "Mitarbeiter"
"Marienstift" in Feld "Adresse1" in Tabelle "Kunden"
"mariannengraben" in Feld "Beschreibung" in Tabelle "Geologie"
usw.

Die Antwort: Nichts und rein gar nichts.
Du findest so auch nicht (oder nicht so ohne weiteres) z. B. die Bestellungen, die für den Kunden "Marienstift" bearbeitet wurden, die Beispiel-"Such-Anfrage" an "die Datenbank" ist also - nochmal und in aller Klarheit - Unsinn.

Dein Wunsch (siehe Zitat oben) ist also grundlegend falsch und sinnlos. Er entspringt eher der Einstellung "Ich hab doch eine Datenbank, da kann ich doch auch suchen" und ist m. E. überhaupt nicht durchdacht, da sie völlig ignoriert, dass eine Datenbank eine wohl geordnete Ansammlung von Tabellen, deren Datenfeldern, Verknüpfungen, Referenzen usw. in einer ebenso wohl durchdachten Struktur ist. Es ist KEINE Ansammlung ungeordneter Daten, die nur darauf warten, "irgendwie" gefunden zu werden.

Von einer gesprochenen Aufforderung "Computer: finde Maria in der Datenbank" UND der Nennung genau der Stellen, die wir gemeint haben, sind wir noch meilenweit entfernt und die Dramaturgie solcher Sci-Fi-Film-Sequenzen verschweigt völlig all die KI, die dahinter stecken müsste, um erstmal herauszufinden, was der "Commander" da eigentlich - oder jedenfalls ungefähr - wissen will...

Du solltest dir m. E. erstmal darüber klar werden, WAS deine Datenbank in welchen Tabellen enthält und dann konkrete Such-Anfragen formulieren, um dort nach betreffenden Datensätzen (Inhalten!) zu suchen, z. B. "Finde Mitarbeiter mit Vornamen Maria" oder "Finde Bestellungen für den Kunden Marienstift".

Würdest du ein Lexikon nach dem Text "Maria" durchsuchen wollen - egal an welcher Stelle er vorkommt? Würdest du "Maria" ohne weiteren Zusatz bei google suchen?

Ich würde sogar so weit gehen, dir vorzuschlagen, deine Frage als "erledigt" zu kennzeichnen, weil sie m. E. nicht zielgerichtet ist und sein kann und sie ein grundlegendes Verständnis über den Sinn und Zweck von Datenbanken (hier genauer: relationalen Datenbanken wie Access) vermissen lässt.

Es macht ja übrigens nur wenig Sinn, z. B. die Personal-Tabelle nach Produkt XYZ zu durchsuchen; willst du "die Datenbank" nach Produkt XYZ durchsuchen, solltest du dir vorher überlegen und darüber klar werden, ob du "Produkt-Stammdaten" oder "Bestellungen" finden möchtest.

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

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,
@crystal:
ZitatDein Zitat..."die Datenbank" ist also - nochmal und in aller Klarheit - Unsinn....
Ein Chef sagt, dass er irgendwo mal den Begriff "Xylo" in der DB gelesen hat und sich aber nicht mehr erinnern kann, wo. Dem hilft sehr wohl so eine Suchmöglichkeit.