Access-o-Mania

Access-Forum (Deutsch/German) => Access Programmierung => Thema gestartet von: KonradR am September 19, 2024, 16:27:06

Titel: Aufforderung für Parametereingabe für Anhang
Beitrag von: KonradR am September 19, 2024, 16:27:06
Hallo liebe Accessfreunde,

ich habe eine Accesdatenbank mit einer Abfrage und einem Formular erstellt, dass auf dieser Abfrage beruht.
Nun habe ich im Formular ein ungebundenes Textfeld eingefügt und möchte, je nach dem was ich Textfeld eingebe, dass im Formular nach dem Inhalt gefiltert wird. Es mir also nur die Datensätze anzeigt, die den entsprechend eingegebenen Text im Textfeld enthalten. Das habe ich so gelöst:
Private Sub txtSuchen_Change()
Dim SQL As String
Dim strSuchtext As String

strSuchtext = Forms("frm010Kommunikation").Controls("txtSuchen").Text

SQL = "SELECT * FROM qryVorgangFirmaAnsprechpartner WHERE tblVorgang.VorgaInhalt LIKE """ & "*" & strSuchtext & "*" & """"

'Debug.Print SQL

Forms("frm010Kommunikation").Controls("sfrmVorgang").Form.RecordSource = SQL
Forms("frm010Kommunikation").Controls("sfrmVorgang").Requery
End Sub


Mein Problem aktuell ist, dass folgende Aufforderung auftaucht, sobald ich ein Zeichen in das Textfeld eingebe:
Screenshot 2024-09-19 161412.png

Hier ist noch ein Bildschirmfoto von der Abfrage:
Screenshot 2024-09-19 161541.png


Es scheint also ein Problem mit dem Anhang zu sein. Habt ihr da Idee, wo ich hier näher bei der Fehlersuche ansetzen kann? Aktuell habe ich, außer das es mit dem Anhang zu tun hat, keine Idee.
Schon im Voraus vielen Dank.
Titel: Re: Aufforderung für Parametereingabe für Anhang
Beitrag von: Beaker s.a. am September 19, 2024, 16:59:38
Hallo Konrad,

Ich bin mir zwar nicht ganz sicher, aber ich denke, dass du dich
in der WHERE-Klausel auch auf die Query beziehen musst
SQL = "SELECT * FROM qryVorgangFirmaAnsprechpartner WHERE qryVorgangFirmaAnsprechpartner.VorgaInhalt LIKE """ & "*" & strSuchtext & "*" & """"Wenn es in der Query das Feld "VorgaInhalt" nicht gibt, musst du
die Query und die Table über ein geeignetes Feld joinen, um mit dem
Feld aus der Table zu filtern.

gruss ekkehard
Titel: Re: Aufforderung für Parametereingabe für Anhang
Beitrag von: Bitsqueezer am September 19, 2024, 17:02:03
Hallo,

Du liebst es maximal umständlich, hm?... ;)

Versuch's mal so:
Private Sub txtSuchen_Change()
    Dim strSQL      As String
    Dim strSuchtext As String

    strSuchtext = Me.txtSuchen.Text

    strSQL = "SELECT qVFA.* FROM qryVorgangFirmaAnsprechpartner AS qVFA " & _
             " WHERE qVFA.VorgaInhalt LIKE '*" & strSuchtext & "*'"

    'Debug.Print strSQL

    With Me.sfrmVorgang.Form
        .RecordSource = strSQL
        .Requery
    End With
End Sub

Du kannst nicht auf den Prefix "tblVorgang" zugreifen, da Du Daten aus einer Abfrage beziehst, es existiert also nur der Name der Query, den man dazu mit einem Alias abkürzt.

Gruß

Christian
Titel: Re: Aufforderung für Parametereingabe für Anhang
Beitrag von: Knobbi38 am September 19, 2024, 20:34:07
Es wäre natürlich hilfreich, wenn man den SQL-Code von "qryVorgangFirmaAnsprechpartner" kennen würde, da das bemängelte Feld ein MultiValueField ist.

Außerdem ist es sicherlich einfacher und besser, die Filter-Eigenschaft des Formulars zu verwenden, als ständig die Recordsource neu zu setzen.

Gruß Ulrich
 

Titel: Re: Aufforderung für Parametereingabe für Anhang
Beitrag von: KonradR am September 20, 2024, 08:57:56
Hallo  Beaker s.a.,

vielen Dank für deine Antwort.
Deinen Kode:
Zitat von: Beaker s.a. am September 19, 2024, 16:59:38SQL = "SELECT * FROM qryVorgangFirmaAnsprechpartner WHERE qryVorgangFirmaAnsprechpartner.VorgaInhalt LIKE """ & "*" & strSuchtext & "*" & """"

Habe ich probiert. Das funktioniert leider auch nicht und ergibt die gleiche Fehlermeldung.

Zitat von: Beaker s.a. am September 19, 2024, 16:59:38Wenn es in der Query das Feld "VorgaInhalt" nicht gibt
Das Feld gibt es tatsächlich.

Titel: Re: Aufforderung für Parametereingabe für Anhang
Beitrag von: KonradR am September 20, 2024, 09:04:51
Hallo Bitsqueezer,

Zitat von: Bitsqueezer am September 19, 2024, 17:02:03Du liebst es maximal umständlich, hm?... ;)
Ich denke schon. Ich denke wahrscheinlich noch nicht genug VBA.
Zitat von: Bitsqueezer am September 19, 2024, 17:02:03Versuch's mal so:
Code [Auswählen] Erweitern
Private Sub txtSuchen_Change()
    Dim strSQL      As String
    Dim strSuchtext As String

    strSuchtext = Me.txtSuchen.Text

    strSQL = "SELECT qVFA.* FROM qryVorgangFirmaAnsprechpartner AS qVFA " & _
             " WHERE qVFA.VorgaInhalt LIKE '*" & strSuchtext & "*'"

    'Debug.Print strSQL

    With Me.sfrmVorgang.Form
        .RecordSource = strSQL
        .Requery
    End With
End Sub
Das funktioniert leider auch nicht. Dein Vorschlag hat mich aber auf die Idee gebracht, den SQL-Code der Abfrage in den VBA-Editor zu kopieren. Das sieht dann so aus:
Private Sub txtSuchen_Change()
Dim SQL As String
Dim strSuchtext As String

'strSuchtext = Forms("frm010Kommunikation").Controls("txtSuchen").Text
strSuchtext = Me.txtSuchen.Text

'SQL = "SELECT * FROM qryVorgangFirmaAnsprechpartner WHERE qryVorgangFirmaAnsprechpartner.VorgaInhalt LIKE """ & "*" & strSuchtext & "*" & """"
'strSQL = "SELECT qVFA.* FROM qryVorgangFirmaAnsprechpartner AS qVFA WHERE qVFA.VorgaInhalt LIKE '*" & strSuchtext & "*'"
SQL = "SELECT tblVorgang.VorgaID, tblVorgang.VorgaProjeIDRef, tblVorgang.VorgaDatum, tblVorgang.VorgaZeit, tblVorgang.VorgaKontaArtIDRef, " & _
        "tblVorgang.VorgaKoOrtIDRef, tblVorgang.VorgaGewerkIDRef, tblVorgang.VorgaThema, tblVorgang.VorgaInhalt, tblVorgang.VorgaAnsprEinsIDRef, " & _
        "tblVorgang.VorgaAnsprZweiIDRef, tblKontakt.KontaFirmaIDRef, tblKontakt.KontaAnspaIDRef, tblKontakt_1.KontaFirmaIDRef, tblKontakt_1.KontaAnspaIDRef, " & _
        "tblVorgang.VorgaAnhang, tblVorgang.VorgaAnhang.FileName FROM tblKontakt INNER JOIN (tblVorgang INNER JOIN tblKontakt AS tblKontakt_1 " & _
        "ON tblVorgang.VorgaAnsprZweiIDRef = tblKontakt_1.KontaID) ON tblKontakt.KontaID = tblVorgang.VorgaAnsprEinsIDRef WHERE " & _
        "(((tblVorgang.VorgaThema) Like '*" & strSuchtext & "*'" & "))ORDER BY tblVorgang.VorgaID;"

Debug.Print SQL

With Me.sfrmVorgang.Form
        .RecordSource = strSQL
        .Requery
    End With
End Sub


Das funktioniert dann. Ich weis zwar nicht warum. Aber es geht. Habt ihr da evtl eine Idee?

Titel: Re: Aufforderung für Parametereingabe für Anhang
Beitrag von: KonradR am September 20, 2024, 09:09:18
Hallo  knobbi38,

Zitat von: knobbi38 am September 19, 2024, 20:34:07Es wäre natürlich hilfreich, wenn man den SQL-Code von "qryVorgangFirmaAnsprechpartner" kennen würde, da das bemängelte Feld ein MultiValueField ist.
Den SQL-Code habe ich in meiner letzten Nachricht beigefügt.

Zitat von: knobbi38 am September 19, 2024, 20:34:07Außerdem ist es sicherlich einfacher und besser, die Filter-Eigenschaft des Formulars zu verwenden, als ständig die Recordsource neu zu setzen.
Ok. Was konkret, im Code und evtl. in der Rechengeschwindigkeit und anderen Dingen, die ich jetzt nicht sehe, macht es denn einfacher und besser als die Recordsetsource ständig neu zu setzen?
Titel: Re: Aufforderung für Parametereingabe für Anhang
Beitrag von: Bitsqueezer am September 20, 2024, 10:38:57
Hallo,

mal abgesehen davon, daß es so nicht funktionieren kann, da Du aus "strSQL" wieder "SQL" gemacht hast (sollte man vermeiden wg. Konflikt mit bestehenden namen wie QueryDef.SQL) und unten als RecordSource immer noch strSQL zuweist...

Du hast einfach nur den SQL-Code übernommen, ohne mal entsprechend Aliase zu vergeben, was den Code schon mal immens kürzt. Auch fügst Du das "ORDER BY" wieder als getrennten String hinzu - warum? Am Ende soll alles in einem String landen.

Bei Attachment-Fields könnte ich mir ebenfalls Probleme vorstellen. Ich würde sie, genau wie Multi Valued Fields (die Ulrich anführte, was es hier aber nicht ist), unbedingt vermeiden. Einerseits ist es wieder so eine "Access-Spezialkonstruktion", die nur mit Problemen behaftet ist, andererseits sollte man grundsätzlich keine Dateien in der Datenbank speichern, da es die Datenbankdatei sehr schnell stark anwachsen läßt, die 2GB-Grenze ist dann schnell erreicht. Besser nur Pfad-/Dateiname speichern und die Datei im Dateisystem belassen.

Da das Feld "VorgaThema" ja in der Originalabfrage drin war (wenn Du es nicht hier im SQL-Code hinzugefügt hast), sollte die Abfrage auch wie vorgeschlagen funktionieren. Natürlich nur, wenn Du nicht weiterhin nach "tblVorgang.VorgaThema" abgefragt hast in der LIKE-Klausel. Wegen der Besonderheit des Feldtyps kann ich das aber nicht genau sagen, ich nutze solche Access-Kapriolen nicht.

Gruß

Christian
Titel: Re: Aufforderung für Parametereingabe für Anhang
Beitrag von: Knobbi38 am September 20, 2024, 11:28:33
@Bitsqueezer
du hast natürlich recht, ich meinte eigentlich auch ein Attachment-Field und kein MVF, welche im Prinzip aber beide auf dem gleiche DAO.Field2 Objekt beruhen, nur mit unterschiedlichen Typ-Angaben.

Hallo,
ob die Verwendung der Filter-Property Performancevorteile bringt, kann ich dir nicht sagen, aber zumindest überläßt du dem Formular selber die interne optimale weitere Verarbeitung der Daten inkl. des Caches.
Unabhängig davon sollte nach der Zuweisung einer neuen Recordsource kein weiteres Requery notwendig sein.



Titel: Re: Aufforderung für Parametereingabe für Anhang
Beitrag von: Beaker s.a. am September 20, 2024, 12:08:07
Hallo Konrad,
Warum es eigentlich so nicht gehen dürfte hat Christian schon erklärt.
Mit der richtigen Variablen funzt das auch.

@christian
Ich hatte in meiner Antwort bewusst auf den Alias verzichtet, um es Konrad
einfacher zu machen es zu verstehen. Denn, wie man an seinem Code sieht, hat/
hätte er den Sinn eines solchen eh nicht verstanden.
@Konrad
Das mit dem Alias solltest du aber lernen. Und zusammen mit einer ordentlichen
Formatierung des SQL-Strings wirst du sehen, wie einfach die dann zu lesen und
zu analysieren sind.
Zitatob die Verwendung der Filter-Property Performancevorteile bringt, kann ich dir nicht sagen
Ich jetzt auch nicht. Aber das Change-Ereignis ist da m.E. unglücklich gewählt.
Bei jedem eingegebenen Zeichen wird die RecordSource neu berechnet
(inkl. autom. Requery) und dann explizit noch mal aktualisiert, - das kann
dauern. Das passiert beim Filtern aber auch
Me.Filter = "VorgaInhalt LIKE '*" & strSuchtext & "*'"
Me.FilterOn = True    'autom. Requery
'das nachfolgende ist somit obsolet (s. Hinweis von Ulrich)
Ich würde das Ereignis "After_Update" bevorzugen bzw. gleich ein Kombi in
Erwägung ziehen.

gruss ekkehard
Titel: Re: Aufforderung für Parametereingabe für Anhang
Beitrag von: KonradR am September 20, 2024, 15:29:17
Hallo Bitsqueezer,

Zitat von: Bitsqueezer am September 20, 2024, 10:38:57mal abgesehen davon, daß es so nicht funktionieren kann, da Du aus "strSQL" wieder "SQL" gemacht hast (sollte man vermeiden wg. Konflikt mit bestehenden namen wie QueryDef.SQL) und unten als RecordSource immer noch strSQL zuweist...
Stimmt absolut. Ich hatte dein With-Klausel hier eingefügt, aber ein meinem Kode keine With-Klausel. Daher ist auch noch dein Variablenvorschlag mit "strSQL" drin. Ich hatte meine Konstruktion mit controls... gelassen und wollte da einfach keine Angriffsfläche bieten

Zitat von: Bitsqueezer am September 20, 2024, 10:38:57Du hast einfach nur den SQL-Code übernommen, ohne mal entsprechend Aliase zu vergeben, was den Code schon mal immens kürzt. Auch fügst Du das "ORDER BY" wieder als getrennten String hinzu - warum? Am Ende soll alles in einem String landen.
Den SQL-Code habe ich einfach ungekürzt übernommen, weil das einfach ist und ich die Version mit den Aliasen noch nicht kannte. In Zukunft werde ich damit arbeiten. Das "ORDER BY" als getrennten String hinzufügen ist unnötig. Das habe ich behoben.

Zitat von: Bitsqueezer am September 20, 2024, 10:38:57andererseits sollte man grundsätzlich keine Dateien in der Datenbank speichern, da es die Datenbankdatei sehr schnell stark anwachsen läßt, die 2GB-Grenze ist dann schnell erreicht. Besser nur Pfad-/Dateiname speichern und die Datei im Dateisystem belassen.
Danke für den Hinweis. Das schaue ich mir als nächstes an.

Zitat von: Bitsqueezer am September 20, 2024, 10:38:57Da das Feld "VorgaThema" ja in der Originalabfrage drin war (wenn Du es nicht hier im SQL-Code hinzugefügt hast), sollte die Abfrage auch wie vorgeschlagen funktionieren. Natürlich nur, wenn Du nicht weiterhin nach "tblVorgang.VorgaThema" abgefragt hast in der LIKE-Klausel. Wegen der Besonderheit des Feldtyps kann ich das aber nicht genau sagen
Danke. Durch deine Antwort habe ich herausgefunden, dass ich nach "VorgaThema" und nicht nach "VorgaInhalt" gefiltert habe, was ich eigentlich wollte. Das habe ich nun auch behoben.



Titel: Re: Aufforderung für Parametereingabe für Anhang
Beitrag von: KonradR am September 20, 2024, 15:30:33
Zitat von: knobbi38 am September 20, 2024, 11:28:33Unabhängig davon sollte nach der Zuweisung einer neuen Recordsource kein weiteres Requery notwendig sein.
Danke. Dann werde ich es mal ohne das Requery probieren.
Titel: Re: Aufforderung für Parametereingabe für Anhang
Beitrag von: KonradR am September 20, 2024, 15:36:41
Zitat von: Beaker s.a. am September 20, 2024, 12:08:07Ich jetzt auch nicht. Aber das Change-Ereignis ist da m.E. unglücklich gewählt.
Danke, aber es soll ja bei jedem Tastaturanschlag die Auswirkung auf die Filterung der Datensätze sichtbar sein, so dass ich immer sehen kann ab wann welche Datensätze verschwinden, bzw. wieder auftauchen. Damit kann ich das gewünschte Stichwort schneller finden.
Titel: Re: Aufforderung für Parametereingabe für Anhang
Beitrag von: MzKlMu am September 20, 2024, 17:07:58
Hallo,
ZitatDamit kann ich das gewünschte Stichwort schneller finden.
Da wäre ein Kombifeld mit den Stichworten als Datenherkunft aber deutlich einfacher.
Zum einen zeigt dann das Kombi nur Stichworte an die es auch gibt und zum anderen aktualisiert sich die Auswahl eines Kombis bei jedem Tastendruck automatisch (ohne Programmierung/VBA). Du bist dann sehr schnell und einfach beim gewünschten Stichwort.
Titel: Re: Aufforderung für Parametereingabe für Anhang
Beitrag von: Bitsqueezer am September 20, 2024, 21:46:01
Hallo,

@Beaker: Ich hatte Dich auch gar nicht gemeint... :)
@Ulrich: War mir schon klar, daß Du das weißt und es nur ein Flüchtigkeitsfehler war..:)

Filter: Naja, es gibt keine absolute Regel dafür, da Access das je nach Backend anders handhabt. Tatsächlich kann es performanter sein, komplett neu abzufragen, was definitiv den Vorteil hat, daß der User den Filter, den man per VBA setzt, nicht selbst herausnehmen kann, z.B. über die Datensatznavigation durch Klick auf "Gefiltert". Beim manuellen Herausnehmen des Filters bekommt VBA das erst mal nicht mit, was dann zu Unstimmigkeiten mit dem Code führen kann. Per "Form_ApplyFilter" kann man das abfangen, muß aber alles extra programmiert werden. Wenn man die RecordSource ändert, existieren die anderen Datensätze ganz einfach gar nicht und entsprechend weniger Daten werden auch übertragen. Wenn man filtert, muß das Recordset zumindest alle Daten enthalten, um es filtern zu können (mit ggf. einer Vorauswahl). Man kann nicht filtern, was nie im Recordset war. Entsprechend kann eine Neuabfrage schneller sein, wenn dadurch weniger Daten übertragen werden müssen.

Das relativiert sich allerdings, wenn man das in einem Change-Event macht. Die Verlockung ist natürlich groß, aber es geht enorm auf die Performance, weil mit JEDEM eingegebenen Zeichen wieder neu gesucht wird. Da hier auch noch mit LIKE und "*" davor und danach gesucht wird, kann auch kein Index verwendet werden, also ist Tablescan angesagt.
Der Weg von Klaus ist auch machbar - einfach eine Kombobox, die verhält sich bereits so, mit jedem Zeichen ein Autocomplete, ohne zusätzliche Abfragen. Auch hier muß man aber bedenken, daß eine große Anzahl Einträge zu Problemen führen kann. Die Kombobox kann nicht unendlich viele Einträge aufnehmen. Die Kombobox hat außerdem den Nachteil, immer das erste gefundene zu verwenden, wenn man tippt. Wenn man 2 Einträge mit "Meier" in einer Namensliste vorliegen hat, mit je einer anderen PersonenID, dann gibt die Kombobox bei Tastatureingabe nur den ersten wieder, Den nächsten muß man dann aus der Dropdownliste explizit auswählen. Außerdem funktioniert die Suche nur "ab Anfang", also nicht mit Namen mittendrin in einem Text.

Es gibt auch andere Varianten, z.B. erst nach der Eingabe des 3. Zeichens die Suche zu starten.

Ich würde allerdings auch besser "AfterUpdate" verwenden, weil dann einfach nur einmal gesucht wird. Der User kann trotzdem Zwischenergebnisse holen, wenn er will, indem er einfach weniger eingibt.

ZitatIch hatte meine Konstruktion mit controls... gelassen und wollte da einfach keine Angriffsfläche bieten
Meistens macht es mehr Sinn, den echten Code zu zeigen, statt "für's Forum" etwas abzuspecken oder total zu verändern. Probleme lassen sich dann auch erkennen.
Die Konstruktion mit Controls und Forms hat den Nachteil, daß sie nicht compilersicher ist. Der Compiler prüft keine Namen in Anführungszeichen. Bei der Schreibweise mit "Me." bekommst Du bereits von IntelliSense Unterstützung und der Compiler überprüft danach auch noch, ob Du einen Schreibfehler in Controlnamen hast. Abgesehen von dem deutlich kürzeren und einfacher lesbaren Code.

SQL-Text im Code: Wo immer machbar, solltest Du das vermeiden. Bei Access ist es nicht problematisch, da Access immer nur einen SQL-Befehl ausführen kann. Solltest Du jemals einen DB-Server als Backend verwenden, ist ein Suchfeld, dessen Eingabe in einen SQL-String eingebaut wird, gefundenes Fressen für Hacker, Stichwort "SQL-Injection". Man beendet den SQL-Befehl mit ";" und fügt dann einen neuen hintendran.Mal so als einfaches Beispiel.

Ganz nebenbei ist so ein SQL-Code in VBA dann auch schwierig zu debuggen.

Es ist daher besser, parametrisierte Abfragen zu verwenden oder Abfragen, die sich Vergleichswerte selbst aus dem Formular holen.
Auch hier gibt es wieder den Nachteil, wenn man Formular/Controlreferenzen direkt in eine Abfrage einfügt. Die Abfrage läuft dann nur, solange das Formular geöffnet ist. Das kann man wiederum vermeiden, indem man eine Public Function in einem Standardmodul einsetzen, die dann für das Holen der Eingabewerte verantwortlich ist, die wiederum testen kann, ob ein Formular geladen ist und das Feld Inhalt hat usw.

Es gibt immer viele Möglichkeiten...

Gruß

Christian
Titel: Re: Aufforderung für Parametereingabe für Anhang
Beitrag von: Knobbi38 am September 20, 2024, 23:19:43
@christian:

Wie immer ein paar tolle Hinweise, aber zwei kleine Anmerkungen hätte ich noch:

1. Wenn man in einem Formular die AllowFilters-Eigenschaft auf FALSE setzt, kann ein Anwender nicht mehr einen per VBA gesetzten Filter manuell ändern oder löschen; das gefiltert worden ist, wird auch nicht mehr angezeigt. Es muß dann auch nichts mehr extra programmiert werden.

2.
ZitatWenn man die RecordSource ändert, existieren die anderen Datensätze ganz einfach gar nicht und entsprechend weniger Daten werden auch übertragen. Wenn man filtert, muß das Recordset zumindest alle Daten enthalten, um es filtern zu können (mit ggf. einer Vorauswahl). Man kann nicht filtern, was nie im Recordset war. Entsprechend kann eine Neuabfrage schneller sein, wenn dadurch weniger Daten übertragen werden müssen.
Wenn man die Recordsource ändert, müssen immer alle DS übertragen werden, erst dann kann lokal entschieden werden, welche DS relevant sind und dann wird damit der Cache gefüllt. Wenn ich mich recht erinnere, werden dabei aber nicht blind alle Daten eines DS sofort geladen, sondern nur relevante Daten. Die vollständigen Daten werden dann später asynchron nachgeladen. Ohne es jetzt aber genau zu wissen nehme ich mal an, daß Access eine Filterbedingung ähnlich wie eine Where-Condition abarbeitet, möglicherweise dabei aber mit Hilfe des Caches etwas mehr optimieren kann. Beim Setzen einer neuen Recordsource muß zwangsläufig der Cache ungültig gemacht werden.

Vielleicht hat jemand ja mal so etwas auf der Verbindungsebene aufgezeichnet und kann hier näheres dazu berichten?

Insgesamt stimme ich dir aber zu. So eine dynamische Suchfunktion belastet die Datenverbindung enorm.

Als Ergänzung vielleicht noch eine andere Möglichkeit:
Um so etwas umzusetzen habe ich einfach mal die zu durchsuchenden Datenfelder komplett in ein Array geladen, per Quicksort sortiert und dann in eine Listbox geladen. Mit dem Change-Event wird dann per Binarysearch lokal in dieser Listbox gesucht und entsprechend positioniert, so daß man das Suchergebnis inklusive dem "Trefferumfeld" sehen kann. Wenn die Daten relativ wenig verändert werden, funktioniert das auch bei sehr "langsamen" Verbindungen selbst bei einer größeren Anzahl von DS ( > 30.000 ) sehr effizient.

Gruß Ulrich



Titel: Re: Aufforderung für Parametereingabe für Anhang
Beitrag von: Beaker s.a. am September 21, 2024, 11:35:57
Hallo Christian,

Hatte ich auch nicht so verstanden. Meine Einlassung sollte mehr
so eine Einleitung für den Hinweis an Konrad sein.

gruss ekkehard
Titel: Re: Aufforderung für Parametereingabe für Anhang
Beitrag von: KonradR am September 22, 2024, 06:37:01
Hallo MzKlMu,

Zitat von: MzKlMu am September 20, 2024, 17:07:58Da wäre ein Kombifeld mit den Stichworten als Datenherkunft aber deutlich einfacher.
Vielleicht. Nur ist ein Kombinationsfeld deutlich kleiner als ein Textfeld (Zumindest im Normalfall). Ich will ja nach einem Ganzen Text suchen, in dem der gesuchte Wortschnippsel enthalten ist. Was ich in der Datenbank hinterlege, sind ja Gesprächsnotizen und die beschränken sich ja nicht auf einzelne Wörter sondern auf ein paar Sätze. Wenn ich nach einem Stichwort suche, will ich natürlich die Worte drumherum sehen um den Kontext und die Relevant besser erkennen zu können. Das geht mit einem Kombinationsfeld, dass nach meinem dafürhalten nur für das anzeigen einzelner Wörter oder Zahlen gedacht ist, nur bedingt.
Titel: Re: Aufforderung für Parametereingabe für Anhang
Beitrag von: KonradR am September 22, 2024, 07:03:35
Hallo Bitsqueezer,

Zitat von: Bitsqueezer am September 20, 2024, 21:46:01Filter: Naja, es gibt keine absolute Regel dafür, da Access das je nach Backend anders handhabt. Tatsächlich kann es performanter sein, komplett neu abzufragen, was definitiv den Vorteil hat, daß der User den Filter, den man per VBA setzt, nicht selbst herausnehmen kann, z.B. über die Datensatznavigation durch Klick auf "Gefiltert". Beim manuellen Herausnehmen des Filters bekommt VBA das erst mal nicht mit, was dann zu Unstimmigkeiten mit dem Code führen kann.
Du meinst, einen SQL-String in VBA zu erstellen und dann der Recordsource Eigenschaft des Steuerelements zuzuweisen?

Zitat von: Bitsqueezer am September 20, 2024, 21:46:01Per "Form_ApplyFilter" kann man das abfangen, muß aber alles extra programmiert werden. Wenn man die RecordSource ändert, existieren die anderen Datensätze ganz einfach gar nicht und entsprechend weniger Daten werden auch übertragen.
Das heißt, ich kann nur mit "Form_ApplyFilter" das manuelle Ändern des Filters durch den Nutzer unterbinden und sonst nicht?

Zitat von: Bitsqueezer am September 20, 2024, 21:46:01also ist Tablescan angesagt
Tablescan heißt ja, dass alle bzw. die meißten Daten einer Tabelle durchsucht werden. Es wird doch aber nur in einem Feld eines jeden Datensatzes gesucht. Das ist, meiner Ansicht nach nicht die ganze Tabelle.

Zitat von: Bitsqueezer am September 20, 2024, 21:46:01Die Kombobox hat außerdem den Nachteil, immer das erste gefundene zu verwenden, wenn man tippt. Wenn man 2 Einträge mit "Meier" in einer Namensliste vorliegen hat, mit je einer anderen PersonenID, dann gibt die Kombobox bei Tastatureingabe nur den ersten wieder, Den nächsten muß man dann aus der Dropdownliste explizit auswählen. Außerdem funktioniert die Suche nur "ab Anfang", also nicht mit Namen mittendrin in einem Text.
Aus diesem Grund will ich sie ja auch nicht verwenden. Vielen Dank. Da waren auch für mich neue Sachen dabei.

Zitat von: Bitsqueezer am September 20, 2024, 21:46:01Es gibt auch andere Varianten, z.B. erst nach der Eingabe des 3. Zeichens die Suche zu starten.
Ja, dass ist möglich. Aber ich will schon ab dem 1. Zeichen mit der Suche beginnen und sehen, wie sich das auf die Ergebnisauswahl auswirkt.

Zitat von: Bitsqueezer am September 20, 2024, 21:46:01Ich würde allerdings auch besser "AfterUpdate" verwenden, weil dann einfach nur einmal gesucht wird. Der User kann trotzdem Zwischenergebnisse holen, wenn er will, indem er einfach weniger eingibt.
Dann sehe ich aber die Änderung im Filter immer erst, wenn ich das komplette Wort eingeben habe. Wenn es für ein Wort keine Ergebenisse gibt, darf ich dann iterativ die Buchstabenfolge meiner Eingabe reduzieren, bis ich Ergebnisse erhalte. Das finde ich umständlich in der Benutzung und verlängert den Suchprozess. Dass der VBA-Code länger braucht um durchzulaufen ist eine andere Sache. Wenn noch nicht so viele Daten enthalten sind, merke ich das als Benutzer ja nicht.

Zitat von: Bitsqueezer am September 20, 2024, 21:46:01Meistens macht es mehr Sinn, den echten Code zu zeigen, statt "für's Forum" etwas abzuspecken oder total zu verändern. Probleme lassen sich dann auch erkennen.
Danke für den Hinweis.
Beim nächsten Mal setze ich den Code ein, den ich auch im VBE eingearbeitet habe.

Zitat von: Bitsqueezer am September 20, 2024, 21:46:01Die Konstruktion mit Controls und Forms hat den Nachteil, daß sie nicht compilersicher ist. Der Compiler prüft keine Namen in Anführungszeichen. Bei der Schreibweise mit "Me." bekommst Du bereits von IntelliSense Unterstützung und der Compiler überprüft danach auch noch, ob Du einen Schreibfehler in Controlnamen hast. Abgesehen von dem deutlich kürzeren und einfacher lesbaren Code.
Macht Sinn. Ich hatte diese Variante gewählt, weil ich mit Copy+Paste die Namen der Steuerelement in die "" eingefügt hatte und sich für mich durch den Codeaufbau einer klarer Pfad ergibt, welches Formular von welchem Unterformularsteuerelement jetzt angewählt ist. Die Fehlerquote erhöht sich natürlich.

Zitat von: Bitsqueezer am September 20, 2024, 21:46:01SQL-Text im Code: Wo immer machbar, solltest Du das vermeiden. Bei Access ist es nicht problematisch, da Access immer nur einen SQL-Befehl ausführen kann. Solltest Du jemals einen DB-Server als Backend verwenden, ist ein Suchfeld, dessen Eingabe in einen SQL-String eingebaut wird, gefundenes Fressen für Hacker, Stichwort "SQL-Injection". Man beendet den SQL-Befehl mit ";" und fügt dann einen neuen hintendran.Mal so als einfaches Beispiel.
Wieder was gelernt. Vielen Dank.

Zitat von: Bitsqueezer am September 20, 2024, 21:46:01Ganz nebenbei ist so ein SQL-Code in VBA dann auch schwierig zu debuggen.
Absolut. Nur manchmal brauchts ihn halt. Was ich gelernt habe, ist SQL schneller als VBA, weil es ja die interne Sprache von Access als Datenbank ist und ich damit auf Access's Kernkompetenz zurückgreife.

Zitat von: Bitsqueezer am September 20, 2024, 21:46:01Es ist daher besser, parametrisierte Abfragen zu verwenden oder Abfragen, die sich Vergleichswerte selbst aus dem Formular holen.
Das ist auf jeden Fall sicherer. Da bin ich auch gerade dran. Vielen Dank für den Tip.
Titel: Re: Aufforderung für Parametereingabe für Anhang
Beitrag von: KonradR am September 22, 2024, 07:09:19
Hallo knobbi38,
Zitat von: knobbi38 am September 20, 2024, 23:19:43Um so etwas umzusetzen habe ich einfach mal die zu durchsuchenden Datenfelder komplett in ein Array geladen, per Quicksort sortiert und dann in eine Listbox geladen. Mit dem Change-Event wird dann per Binarysearch lokal in dieser Listbox gesucht und entsprechend positioniert, so daß man das Suchergebnis inklusive dem "Trefferumfeld" sehen kann. Wenn die Daten relativ wenig verändert werden, funktioniert das auch bei sehr "langsamen" Verbindungen selbst bei einer größeren Anzahl von DS ( > 30.000 ) sehr effizient.
Danke für den Tip. Damit werde ich mich mal beschäftigen.
Titel: Re: Aufforderung für Parametereingabe für Anhang
Beitrag von: Bitsqueezer am September 22, 2024, 20:56:37
Hallo,

@Ulrich:
ZitatWenn man in einem Formular die AllowFilters-Eigenschaft auf FALSE setzt, kann ein Anwender nicht mehr einen per VBA gesetzten Filter manuell ändern oder löschen

Das geht natürlich, was allerdings auch die Usability eines Formulares einschränkt, da der User dann auch keine eigenen Filter verwenden kann. Hat man die RecordSource gesetzt, kann der User zusätzlich eigene Filter darauf verwenden. Alles eben eine Frage dessen, was man erreichen will.

ZitatWenn man die Recordsource ändert, müssen immer alle DS übertragen werden, erst dann kann lokal entschieden werden, welche DS relevant sind

Ja, im Fall eines Access-Backends stimmt das natürlich. Sorry dafür, ich denke halt bei Backend immer an SQL Server (bzw. DB-Server im Allgemeinen), weil ich grundsätzlich Access-Backends ablehne. :)
Zumindest besteht in diesem Fall kein Unterschied zwischen Filter und RecordSource, weil dann ja immer alle Datensätze geladen werden müssen.

@KonradR :
ZitatDu meinst, einen SQL-String in VBA zu erstellen und dann der Recordsource Eigenschaft des Steuerelements zuzuweisen?
Nein, es ging ja um die RecordSource des Formulares, zumindest nach Deinem Eingangspost. Aber das war damit gemeint, ja.

ZitatDas heißt, ich kann nur mit "Form_ApplyFilter" das manuelle Ändern des Filters durch den Nutzer unterbinden und sonst nicht?
Ja, oder mit AllowFilters, wie Ulrich angemerkt hat.

ZitatTablescan heißt ja, dass alle bzw. die meißten Daten einer Tabelle durchsucht werden. Es wird doch aber nur in einem Feld eines jeden Datensatzes gesucht. Das ist, meiner Ansicht nach nicht die ganze Tabelle.
Natürlich, es ist nur das betreffende Feld. Es ändert aber nichts daran, daß die gesamte Tabelle gelesen werden muß, das ist ein Tablescan. Bei der Suche in einem Index wird die Tabelle selbst nicht angerührt bzw. erst, wenn die gefundenen Datensätze geladen werden sollen. Das ist dann entweder ein Indexscan oder ein Indexseek.

Ich empfehle übrigens, auf "SELECT *" zu verzichten und grundsätzlich immer die Liste der wirklich benötigten Felder anzugeben, selbst wenn alle benötigt werden. Bei einer späteren Änderung der Tabelle werden dann keine unnötigen Daten übertragen. Ein Tool wie das kostenlose V-Tools mit Total Deep Search hilft sehr gut, Namen, die selbst die Auto-Namensanpassung nicht findet, zu finden und anzupassen.

ZitatDann sehe ich aber die Änderung im Filter immer erst, wenn ich das komplette Wort eingeben habe. Wenn es für ein Wort keine Ergebenisse gibt, darf ich dann iterativ die Buchstabenfolge meiner Eingabe reduzieren, bis ich Ergebnisse erhalte. Das finde ich umständlich in der Benutzung und verlängert den Suchprozess. Dass der VBA-Code länger braucht um durchzulaufen ist eine andere Sache. Wenn noch nicht so viele Daten enthalten sind, merke ich das als Benutzer ja nicht.

Bei solchen Dingen würde ich Usability bei den Großen abschauen. Google oder andere Suchmaschinen etwa haben mit irrsinig großen Datenbeständen zu tun. Du bekommst während der Eingabe trotzdem keine Suchergebnisse angezeigt, stattdessen erhältst Du zum einen Vorschläge aus eigenen vergangenen Suchen (z.T. natürlich auch vom Browser), zum anderen die häufigsten Suchen anderer Besucher, in denen Deine Suchwörter vorkommen.
Was spricht dagegen, es ebenso zu machen? Die Anzahl Datensätze in einer "vergangene Suchen"-Tabelle wird eher gering sein. Da kann man dann mit Change-EVent leben. Keine Suchmaschine käme klar, wenn etliche User mit jedem eingegebenen Zeichen sofort alle Ergebnisse aus dem Internet gelistet bekämen.

Du könntest Dir auch meine "BestMatchV3"-Demodatenbank anschauen, bei der in komplexen Texten gesucht werden kann, indem man einfach frei Wörter eingibt. Dabei werden dann Punkte vergeben, wie oft welches Wort in welchem Ergebnis gefunden wurde und von wievielen der eingegebenen Wörter. Damit kann man dann sehr schnell das gewünschte wiederfinden, schon daher, weil man eben mehr als ein Wort eingeben kann.
Findest Du auf meiner Downloadseite unter www.ccedv.de .

ZitatAbsolut. Nur manchmal brauchts ihn halt. Was ich gelernt habe, ist SQL schneller als VBA, weil es ja die interne Sprache von Access als Datenbank ist und ich damit auf Access's Kernkompetenz zurückgreife.

Definitiv, man sollte SQL immer VBA vorziehen, wo immer es machbar ist - keine Frage!
Falsch ist dagegen zu glauben, daß man dazu SQL-Strings in VBA einbauen müßte. In den meisten Fällen kann man auf eine gespeicherte Abfrage zurückgreifen. Und wenn man dynamische Parameter braucht, dann klickt man im Abfragedesigner einfach mal auf "Parameter" in der Ribbon-Leiste und erstellt (dazu auch noch) Parameter, die Datentypen haben.
Deren Namen kann man dann einfach in der Abfrage (mit eckigen Klammern) einsetzen.
In VBA ruft man die Abfrage dann aus der Liste der QueryDefs als QueryDef-Objekt auf und dieses Objekt enthält eine "Parameters"-Collection, die je Parameter mit dem entsprechenden Namen angesprochen werden kann. Deren Wert kann man in VBA dann befüllen, was einer SQL Injection vorbeugt, da man hier den SQL-Text nicht verändert.

Natürlich gibt es auch Situationen, in denen man den SQL-Text anpassen muß, was sich "dynamisches SQL" nennt, hier muß man dann aber eben bestmöglichst verhindern, daß es zu Problemen kommt.

Gruß

Christian
Titel: Re: Aufforderung für Parametereingabe für Anhang
Beitrag von: KonradR am September 27, 2024, 04:58:32
Zitat von: Bitsqueezer am September 22, 2024, 20:56:37Keine Suchmaschine käme klar, wenn etliche User mit jedem eingegebenen Zeichen sofort alle Ergebnisse aus dem Internet gelistet bekämen.
Absolut. Meine Datenbank ist ja so klein, da ist das eher keine Problem. Wenn dass dann größer wird, kann ich ja immer noch über eine Änderung nachdenken.

Zitat von: Bitsqueezer am September 22, 2024, 20:56:37Findest Du auf meiner Downloadseite unter www.ccedv.de .
Zitat von: Bitsqueezer am September 22, 2024, 20:56:37Du könntest Dir auch meine "BestMatchV3"-Demodatenbank anschauen, bei der in komplexen Texten gesucht werden kann, indem man einfach frei Wörter eingibt.
Danke für den Tip. Wow, extrem umfangreich. Wie lange hast du schon mit Access zu tun?

Zitat von: Bitsqueezer am September 22, 2024, 20:56:37In VBA ruft man die Abfrage dann aus der Liste der QueryDefs als QueryDef-Objekt auf und dieses Objekt enthält eine "Parameters"-Collection, die je Parameter mit dem entsprechenden Namen angesprochen werden kann. Deren Wert kann man in VBA dann befüllen, was einer SQL Injection vorbeugt, da man hier den SQL-Text nicht verändert.

Natürlich gibt es auch Situationen, in denen man den SQL-Text anpassen muß, was sich "dynamisches SQL" nenn
Danke dafür. Damit werde ich mich mal näher befassen. Ein sehr umfangreiches Thema.
Titel: Re: Aufforderung für Parametereingabe für Anhang
Beitrag von: Bitsqueezer am September 30, 2024, 14:13:15
Hallo,

ZitatWie lange hast du schon mit Access zu tun?
Seit es Access gibt... :)

Und mit Datenbanken noch länger.

Gruß

Christian