[Access] - Wie kann man mit einer Schaltfäche im Formular prüfen ob Wert in Tabelle vorhanden ist?

5 Antworten

Stehen die Tabellen tblGegenstand und tblOptionen in einer 1:n-Beziehung? Oder warum sonst teilst Du das in mehrere Tabellen?

Und was hast Du unten nun stehen, das da:
Eintrag = Nz(DLookup("zugehörigesG", "tblGegenstand", "NameUGS = " & Me!GegenstandName), "")
oder das da:
Eintrag = Nz(DLookup("zugehörigesG", "tblGegenstand","NameUGS = '" & Me!GegenstandName & "'"))

Wobei ich nicht weiß, wofür Du ein DLookup auf das eine Feld machst und das Kriterium auf ein anderes Feld setzt...
In meinen Augen ist DLookup für Dich hier nicht sinnvoll.

Beantworte das mal, auch das erste oben, dann kann man weitersehen.


ChrisFragtGern 
Beitragsersteller
 22.11.2018, 19:46

Hey sorry fürs lange nicht antworten. Also ein Gegenstand hat viele Optionen, das heißt doch 1:n Beziehung oder?

Und zur zweiten Frage, das ist der Code:

Eintrag = Nz(DLookup("zugehörigesG", "tblGegenstand", "NameUGS = '" & Me!GegenstandName & "'"))

Ich hoffe ich finde am Wochenende etwas Zeit dafür, dann werde ich mich auf jeden Fall nochmal melden.

0

Also zu diesem Kommentar von Dir hatte ich schon geantwortet:

Eigentlich will ich ja nur prüfen ob der Eintrag schon vorhanden ist, damit ich mir einen anderes Feld aus diesem Eintrag (Der Feldname ist: "zugehörigesG") in einer Variable abspeichern kann.

Jetzt schreib doch mal genau:
Soll Dein Formular die Inhalte der Tabelle anzeigen?

Wenn nein, was soll Dein Formular überhaupt können/nützen außer dieser Prüfung auf vorhandenen Einträge?

Und wenn ja, als Einzelansicht jedes Datensatzes oder als Liste? Und dann soll das von Dir genannte Feld ein zuätzliches (ungebundenes) Feld in diesem Formular sein? Und was soll das Formular tun, wenn der Eintrag gefunden wurde, und was, wenn er nicht gefunden wurde?

P.S.:
Ich habe den Eindruck, Deine Vorgehensweise ist gar nicht die beste, Du solltest statt eines Eingabefeldes plus Prüfung per Code lieber ein Kombinationsfeld benutzen, das auf genau das Feld schaut, in dem Du auf Vorhandensein prüfen möchtest...

Woher ich das weiß:eigene Erfahrung

ChrisFragtGern 
Beitragsersteller
 16.11.2018, 13:45

Ja du hast Recht. Ist jetzt alles etwas unübersichtlich geworden. ALso noch mal von vorn. Ich möchte dass der Nutzer über das Formularfeld einen Namen suchen kann. In einer Tabelle sind viele Namen aufgelistet, es kann auch sein, dass ein Name mehrfach vorkommt. Nun möchte ich von jedem Tabelleneintrag in dem der Name enthalten ist einen bestimmten anderen Wert wissen.

Als Beispiel:

Der User gibt in mein Formular "Bohrer" ein (Formularfeld heißt "GegenstandName") und bestätigt es mit dem Button. Dann wird in der Tabelle (tblGegenstand) im Feld (NameUGS) nach "Bohrer" gesucht. Ein weiteres Feld in der Tabelle (tblGegenstand) ist "Optionen". Ich möchte jetzt von allen Einträgen mit Namen "Bohrer" die Ergebnisse aus dem Feld "Option" in einem Formular für den User darstellen.

Dieser soll dann im Formular die Optionen an und abwählen können. Z.B. über ein Kontrollfeld (Das mit dem Haken)

Wie oben erwähnt bin ich der totale Anfänger und habe keine Ahnung wie ich da ran gehen soll.

0
ChrisFragtGern 
Beitragsersteller
 16.11.2018, 13:54
@ChrisFragtGern

Ah sorry hab noch was vergessen, in tblGegenstand steht nur die ID der zugehörigen Option. Die Optionen selber sind in einer weiteren Tabelle (tblOptionen)

0
micmen  16.11.2018, 14:00
@ChrisFragtGern

Oha, also dann solltest Du aber komplett anders vorgehen...
Dann sollte Dein Formular ein Listenformular sein, das auf diese Tabelle schaut, und das Eingabefeld sollte eine Filterfunktion ausführen: Sobald man auf den Button klickt, sollte das Formular alle Datensätze anzeigen, bei denen im Feld NameUGS der eingegebene String steht (aber vorsicht: dann werden nur die gefunden, die exakt gleich geschrieben sind!).
Wird da was gefunden, also zeigt das Formular dann noch mindestens einen Datensatz, kann man in den Feldern, die das Formular enthält (z.B. Deine "Optionen") Änderungen vornehmen.

Dann wäre nur noch zu klären:
Soll das Formular auch beim Öffnen gleich was anzeigen, oder soll es "leer sein"?
Und was soll gemacht werden, wenn der eingegebene Begriff nicht gefunden wird: Soll dann (evtl. nach Rückfrage mit einer MsgBox) ein Datensatz neu angelegt werden, der in NameUGS den eingegebenen Begriff eingetragen hat?

0
ChrisFragtGern 
Beitragsersteller
 16.11.2018, 14:20
@micmen

Alles klar. Dann beschäftige ich mich erstmal damit. Beim Öffnen soll das Formular nur nach dem Namen fragen den der Nutzer dann angeben soll. Wenn keiner gefunden wird, habe ich mir bis jetzt noch nichts überlegt, aber wär nicht schlecht, wenn der dann angelegt wird.

Wie erstellt man ein Listenformular?

0
ChrisFragtGern 
Beitragsersteller
 16.11.2018, 14:25
@ChrisFragtGern

Also wenn ich jetzt das Standard Formular für meine Tabelle erstelle, dann werden mir ja einfach alle Datensätze angezeigt. Aber Am Anfang soll ja eigentlich erstmal die Aufforderung an den User stehen.

0
ChrisFragtGern 
Beitragsersteller
 16.11.2018, 14:32
@ChrisFragtGern

Und selbst wenn ich die dann Filter, habe ich zwar evtl nur die Datensätze nachdem der User sucht. Aber ich will ja nicht die Datensätze aufgelistet bekommen, sondern die zugehörigen Optionen, die aber in einer anderen Tabelle stehen. Also in der Tabelle wo ich nach NameUGS suche steht z.B. nur die ID der Option, die dann in der Tabelle Option zu finden ist und die möchte ich auflisten.

0

Um dem Button einen Code zu geben, musst du das Formular im Entwurfsmodus öffnen und dann das Eigenschaftenfenster des Buttons öffnen (entweder ist das Eigenschaftenfenster schon geöffnet, dann musst du nur den Button anklicken oder du machst halt einen Rechtsklick auf den Button und dann auf "Eigenschaften...")

Da kannst du dem Button erstmal einen sinnvollen Namen geben (auf dem Reiter "Andere") und dann kannst du auf den Reiter "Ereignis" gehen und dort einen Doppelklick in das Feld "Beim Klicken" rein machen. Dadurch erscheint dort "[Ereignisprozedur]". Mit dem "..." Button in der gleichen Zeile öffnest du dann das VBA-Fenster, wo du Code eingeben kannst.

Für den Button steht dann schon automatisch ein Code-Schnipsel drin, der etwa so aussieht:

Private Sub btnSuche_Click()

End Sub

Da kannst du dann z.B. deinen Code oben benutzen, um zu schauen, ob der Eintrag schon vorhanden ist. Statt dCount finde ich die Funktion dLookup sinnvoller. Die zählt nämlich nicht, wie oft der Eintrag vorhanden ist, sondern gibt dir den ersten Eintrag zurück, auf den der Filter zutrifft.

Hier allerdings ein kleiner Erfahrungswert von mir: Sobald du einer der beiden Funktionen mehr als einen Filter gibst, werden sie unheimlich langsam (also so, dass du teilweise minutenlang warten musst, bis du ein Ergebnis kriegst), daher würde ich dir empfehlen, das gleich als SQL-Abfrage einzubauen:

Private Sub btnSuche_Click()
Dim db As Database
Dim rs As Recordset

Set db = CurrentDb
Set rs = db.OpenRecordset("SELECT Name FROM TableTest WHERE Name = """ & Me.Formularfeld & """")

If rs.RecordCount > 0 Then
  MsgBox "Eintrag schon vorhanden!"
End If
End Sub

Für das eigentliche Grundproblem, was du lösen willst, nämlich dass der Eintrag nicht mehrmals in der Tabelle stehen soll, gibt es aber eine bessere Lösung. Du kannst nämlich in der Tabelle einfach einstellen, dass der Wert nur einmal vorkommen darf. Dafür öffnest du die Tabelle in der Entwurfsansicht und stellst für das Feld die Option "Indiziert: Ja (ohne Duplikate)" ein.


micmen  16.11.2018, 12:24
Nur so eine Idee:
Du verwendest "Me.Formularfeld" mit dem Punkt. Das ist recht praktisch beim Erstellen des Codes, aber hinterher sollte man solche Punkte durch Ausrufungszeichen ersetzen, genau DAS soll nämlich Geschwindigkeitseinbußen bringen. Ich weiß zwar nicht, ob das der Grund für "minuten"lange Bearbeitungszeiten sein kann, aber ich persönlich halte mich immer an diese Regel, nach Fertigstellung einer Funktion oder Prozedur nur Ausrufungszeichen stehen zu lassen.
 
Warum wird mir mein ganzer Text hier ohne automatischen Zeilenumbruch angezeigt???
Ist das bei Euch auch so oder liegt das an meinem Browser?
0
daCypher  16.11.2018, 14:09
@micmen

Ich hab noch nie probiert, ob es mit dem Punkt oder mit dem Ausrufezeichen schneller ist. Soweit ich weiß, ist der Unterschied, dass VBA beim Punkt sofort prüft, ob das Objekt vorhanden ist und beim Ausrufezeichen erst während der Ausführung prüft, ob es das Objekt gibt. Theoretisch müsste es also mit Punkt schneller sein.

Bei DLookup ist es aber unabhängig von Punkt oder Ausrufezeichen. Sobald man auf mehr als ein Feld filtert, dauert es ewig. Mit der SQL-Version kann man auf so viele Felder filtern, wie man will.

0
ChrisFragtGern 
Beitragsersteller
 16.11.2018, 12:45

Also aufgrund eurer Tipps heißt mein FormularFeld jetzt "GegenstandName", die Tabelle "tblGegenstand" und das Feld in der Tabelle "NameUGS"

Set rs = db.OpenRecordset("SELECT NameUGS FROM tblGegenstand WHERE NameUGS = """ & Me!GegenstandName & """")

Bekomme den Fehler: "Es wurden 1 Parameter erwähnt aber zu wenig Parameter übergeben"

0
ChrisFragtGern 
Beitragsersteller
 16.11.2018, 12:49

Falls ein gleicher Eintrag gefunden wird, möchte ich dann später mit einem anderem Feld aus diesem Eintrag weiterarbeiten. Deswegen prüfe ich überhaupt nur, ob dieser schon vorhanden ist.

0
ChrisFragtGern 
Beitragsersteller
 16.11.2018, 13:09

Eigentlich will ich ja nur prüfen ob der Eintrag schon vorhanden ist, damit ich mir einen anderes Feld aus diesem Eintrag (Der Feldname ist: "zugehörigesG") in einer Variable abspeichern kann.

Bin da bis jetzt soweit gekommen;

Dim Eintrag As String
Eintrag = Nz(DLookup("zugehörigesG", "tblGegenstand", "NameUGS = Me!GegenstandName"), "")

Syntaxfehler (Fehlender Operator) in Abfrageausdruck 'zugehörigesG'

0
micmen  16.11.2018, 13:26
@ChrisFragtGern

also bei:
WHERE NameUGS = """ & Me!GegenstandName & """")
hast Du hinten ein " zu viel und bei:
"NameUGS = Me!GegenstandName"
hast Du das Objekt mit in den String genommen, das sollte so aussehen:
"NameUGS = " & Me!GegenstandName
Rest ist mir jetzt zu unübersichtlich: Wie ist der Stand?

0
ChrisFragtGern 
Beitragsersteller
 16.11.2018, 13:35
@micmen

Wenn ich den oberen Fehler bearbeite kommt "Erwartet Listentrennzeichen oder )

und beim unterem Fehler sagt er mir nach Bearbeitung immer noch "Syntaxfehler (Fehlender Operator) in Abfrageausdruck 'zugehörigesG'"

Set rs = db.OpenRecordset("SELECT NameUGS FROM tblGegenstand WHERE NameUGS = """ & Me!GegenstandName & """)
Eintrag = Nz(DLookup("zugehörigesG", "tblGegenstand", "NameUGS = " & Me!GegenstandName), "")
0
micmen  16.11.2018, 13:50
@ChrisFragtGern
Ja, da hast Du in beiden Fehler:
WHERE NameUGS = '" & Me!GegenstandName & "'")
"NameUGS = '" & Me!GegenstandName & "'"))

versuche es mal so...
0
ChrisFragtGern 
Beitragsersteller
 16.11.2018, 13:58
@micmen

Ok das obere funktioniert jetzt, das untere nicht. Immer noch der selbe Fehler.

0

Also zuerst mal kann man keine Module ausführen, sondern nur Prozeduren und Funktionen, die in Modulen gespeichert sind. Bei Deinem Codebeispiel fehlt die Deklaration der Funktion oder Prozedur, der Code ist anscheinend "irgendwo" in das Modul geschrieben und wird daher als (Variablen-)Deklaration behandelt.

Leider hast Du nur schwammig beschrieben, wo Dein Problem ist, an welcher Stelle ganz genau Du dann nicht mehr weitergekommen bist. So ist es schwer, Dir ab da weiterzuhelfen.

Außerdem hast Du Deine Access-Version nicht genannt.

Access hat ja Assistenten, die einem (z.B.) helfen, Schaltflächen (bzw. deren Ereignisse) mit Code zu hinterlegen. Wenn Du einfach mal eine Schaltfläche in Dein Formular einfügst, sollte wohl auch Deine Access-Version Dir irgendeine Unterstützung anbieten. Blöderweise ist es dann tatsächlich so, daß man einen unbrauchbaren Namen "zugewiesen" bekommt, der dann auch vom Code benutzt wird, also das benennst Du alles beides hinterher um (Button von Befehl1 zu VorhandenePruefen oder EintragSuchen oder ähnlich und die Prozedur entsprechend von Befehl1_Click zu MeineEigeneBezeichnung_Click).

Ansonsten ist Dein Code schon brauchbar. Hinter dem "Then" machst Du einen Zeilenumbruch, das "Cancel = True" kannst Du Dir schenken, vor dem "End IF" machst Du auch wieder einen Zeilenumbruch und zwischen der 2. und 3. Zeile (also vor dem "End If" fügst Du eine Zeile "Else" ein und danach beliebig viele Zeilen mit dem Code, der ausgeführt werden soll, wenn der Eintrag nicht gefunden wurde.

Und ich kann nur davor warnen, in VB Bezeichnungen zu verwenden, die schon eine anderweitige Bedeutung/Funktion haben! Du schreibst, Du hättest ein Feld namens "Name", das solltest Du ändern. Wenn Du nicht höllisch aufpaßt, wird evtl. mal die Name-Eigenschaft verwendet statt Deines Feldes mit dieser Bezeichnung. Gerade Name ist "gefährlich", denn eine Name-Eigenschaft haben unzählige Dinge innerhalb sowohl Access, als auch VB.


micmen  16.11.2018, 12:19

Oh, ich sehe, da war schon jemand schneller...Diese Erfahrung von wegen lange warten habe ich noch nie gemacht, auch nicht bei FE-BE-Lösungen, wo die Daten-Datenbank auf einem Netzwerkserver liegt. Also ich hätte das mit der vorgeschlagenen DCount-Variante gelassen. Recordset lohnt sich eher, wenn Du bei der Gelegenheit durch Deinen Code auch gleich Inhalte in die Tabelle schreiben lassen willst.

0

Nun, normalerweise solltest du im Entwurfsmodus deines Formulars ein Button einfügen können, dieser sollte dann per Default so aussehen wenn du ihn unter Rechtsklick Ereignis öffnest:

Private Sub Befehl1_Click()

...

End Sub

Dort könntest du deinen Code reinschreiben. Teste das mal und oder schick mal Bilder, damit, falls es nicht gelöst ist, das Problem besser zu "sehen" ist ;)


ChrisFragtGern 
Beitragsersteller
 16.11.2018, 12:31

Ah danke das hat geholfen, jetzt weiß ich wie ich den Code an den Button binde.

Meine Tabelle heißt tblGegenstand, das Formularfeld heißt GegenstandName und das Feld in der Tabelle heißt Name. Wie müsste der DCount() Befehl jetzt aussehen, damit er funktioniert?

Bei meinem oben gepostetem Code kommt immer "Laufzeitfehler 3705 Syntaxfehler (Fehlender Operator) in Abfrageausdruck 'Count(Name)'."

0