moesys
Goto Top

Filtern in einem Access Formular

Hallo zusammen,

ich habe ein Formular basierend auf eine Abfrage im Access zusammengebastelt.

Nun habe ich ein Textfeld für die Eingabe eines Preises eingefügt.
Nach diesem Preis soll in der DB/Abfrage gesucht werden.
Falls dieser Preis nicht existiert soll der nächste Preis angezeigt werden.
Beispiel: Eingabe 2,10 €
Daten:
2,08 €
2,13 €
2,06 €
Hier wäre der gesuchte Preis 2,08€

Wie schreibt man sowas in VBA bzw. gibt es einen Operator oder eine Funktion die soetwas schon kann?

Vielen Dank im Voraus für eure Hilfe!!!

Content-ID: 218150

Url: https://administrator.de/contentid/218150

Ausgedruckt am: 22.11.2024 um 17:11 Uhr

SlainteMhath
SlainteMhath 30.09.2013 um 13:32:21 Uhr
Goto Top
Moin,

Versuch's doch mal mit der Funktio "dlookup" oder der .Filter Eigentschaft des Formulars.

lg,
Slainte
MoeSys
MoeSys 30.09.2013 um 14:06:00 Uhr
Goto Top
Hi Slainte,

die Filtereigenschaften des Formulars können sowas nicht und wie ich das mit "dlookup" realisieren soll wüsste ich jetzt auch nicht, aber vll stehe ich ja nur auf n Schlauch....

Nochmal zum Verständnis: ich will mich dem eingegebenen Wert annähern
d.h. wenn dieser Wert nicht drin steht soll der nächste (der dieser Eingabe am nächsten ist) genommen werden.

Schönen Gruß
Joe2011
Joe2011 30.09.2013 um 14:29:51 Uhr
Goto Top
Moin Moin,

dazu eine Frage:

was ist näher an 2,10 €: 2,09 € oder 2,11 €?

Zuerst nach oben oder unten annähern? Kaufmännische Rundung? Rundung auf wieviele Dezimalstellen (nur zum Rechnen)?

Das soll mehr eine Gedankenstütze als eine Lösung sein. Die Lösung haben bestimmt schlauere Köpfe. face-smile

Gruss


Joe
SlainteMhath
SlainteMhath 30.09.2013 um 14:41:41 Uhr
Goto Top
In etwa so:
dim p as long

p = nz(dlookup("Preis","tabelle","Preis=dein feld im formular"),0)  
if p=0 then 
  p=nz(dlookup("Preis","tabelle","Preis>dein feld im formular"),0)  
  if p=0 then
    p=nz(dlookup("Preis","tabelle","Preis<dein feld im formular"),0)  
  end if
end if
MoeSys
MoeSys 30.09.2013 um 14:46:08 Uhr
Goto Top
Hey Joe,

also wenn 2,09€ und 2,11€ rauskommt dann kommen andere Kriterien dazu, z.B. Preislistendatum etc.
2 Dezimalstellen dürfen auch nur eingegeben werden also keine Rundung ;)

Danke für deine Hinweise!!!
MoeSys
MoeSys 30.09.2013 um 14:48:37 Uhr
Goto Top
aaah OK versuche ich gleich mal... DANKE!!
MoeSys
MoeSys 30.09.2013 um 15:52:19 Uhr
Goto Top
das bekomme ich so nicht hin... der button macht gar nix (also nicht mal eine Fehlermeldung)
Was genau ist denn "Preis"? das Feld in der DB oder soll ich das einfach so stehen lassen?
SlainteMhath
SlainteMhath 01.10.2013 um 08:35:55 Uhr
Goto Top
Ja natürlich "´macht" der Button nix. Die Variable P musst du dann schon irgendwie weiterverwenden - wie musst du selber entscheiden.

Und bei dlookup hilft auch mal ein Block in die Access Hilfe oder bei google: http://www.techonthenet.com/access/functions/domain/dlookup.php
MoeSys
MoeSys 01.10.2013 um 13:53:25 Uhr
Goto Top
erstmal danke für deine tipps... wie du schon mitbekommen hast ist dies nicht mein Fachgebiet, ich bin hier der totale DAU...
Nichts desto trotz würde ich gerne nachvollziehen was du meinst..

hier mein angepasster code, vielleicht siehst du ja was ich falsch mache/verstehe.

Dim p As Long

p = Nz(DLookup("Ekp", "unerledigte_RB_Pos", "Ekp=txtEingabePreis"), 0)
If p = 0 Then
p = Nz(DLookup("Ekp", "unerledigte_RB_Pos", "Ekp>txtEingabePreis"), 0)
If p = 0 Then
p = Nz(DLookup("Ekp", "unerledigte_RB_Pos", "Ekp<txtEingabePreis"), 0)
End If
End If
'MsgBox "" & p & ""

Wie du siehst lass ich mir p zum Schluss anzeigen...
Wenn ich nun 2,11€ eingebe dann ist p = 2... obwohl die Abfrage genau diesen Wert (2,11€) enthält!!!

D.h. wenn ich das so schreibe:

Me.Form.Filter = "Ekp = " & Me!txtEingabeMenge & "
Me.Form.FilterOn = True

dann bekomme ich genau das gewünschte Ergebnis, funktioniert natürlich nur wenn dieser Wert in meiner Abfrage vorkommt...

Wie kann ich "Full Gas DAU" deine Methode so anpassen dass der gewünschte Effekt erzielt wird ;)
SlainteMhath
SlainteMhath 01.10.2013 um 13:59:03 Uhr
Goto Top
IM Doolkup muss es auch

... "Ekp<" & txtEingabePreis ...

lauten.
MoeSys
MoeSys 02.10.2013 um 10:34:17 Uhr
Goto Top
Oh ja da haste natürlich Recht, hätte ich auch drauf kommen können.
Das DLookup habe ich nun zum Laufen gebracht danke deiner Unterstützung face-smile

Leider funktioniert es damit nicht so wie ich mir das vorstelle.
wenn ich z.B. 2,10 eingebe und in der DB sind 2,11 / 2,12 etc hinterlegt dann spuckt er hierdurch:
p = Nz(DLookup("Ekp", "unerledigte_RB_Pos", "Ekp>txtEingabePreis"), 0)
den ersten Preis den er in der DB findet der größer 2,10 ist, also auch 16,50 (als Beispiel)...

Kann man ihm vll sagen dass er erst die ganze Spalte durchsuchen und nicht beim ersten Wert stehen bleiben soll?
Biber
Biber 02.10.2013 aktualisiert um 15:36:33 Uhr
Goto Top
Moin moeSys,

die Tabelle "unerledigte_RB_Pos" wird ja wahrscheinlich nach Rechnungsnummern und/oder Datum sortiert sein - und in dieser logischen Reihenfolge wird ja gesucht.

Wenn die Tabelle zumindest fachlich richtig ist, was ich nicht beurteilen kann, da ich die Tabellenstrukturen und Beziehungen nicht kenne, dann solltest du auf diese Tabelle einen View (bzw. in Access-Sprech "eine Abfrage" ) erzeugen nach dem Muster
SELECT [die Felder, die du brauchst]
from unerledigte_RB_Pos
order by EKP;
oder
SELECT distinct ekp as ekp
from unerledigte_RB_Pos
;

Speichern als "unerledigte_RB_Pos_nach_ekp" und diese Quelle in deinem DLookup() verwenden.

Grüße
Biber
MoeSys
MoeSys 02.10.2013 um 15:45:41 Uhr
Goto Top
Hey Biber,

Danke für den Hinweis!!
Genau das habe ich auch schon gemacht, ich komme dem Ganzen schon näher face-smile

Was nun immer noch ein kleines Problem ist:
Wenn ich 2,10€ suche und die Abfrage enthält folgende Werte
2,09€
2,14€
2,16€
dann bekomme ich mit dem aktuellen DLookup den Wert 2,14€ zurück und nicht 2,09€, was ja näher an 2,10€ wäre und damit richtiger...

Schönen Gruß
Biber
Biber 02.10.2013 aktualisiert um 17:39:07 Uhr
Goto Top
Moin MoeSys,

dafür ist ein DLookup nicht geeignet.

Was dein Wunsch-Statement leisten sollte, das wäre sinngemäß ja ein
SELECT Min( EKP )
FROM deineEKPAbfrage 
WHERE EKP in ( 
    (2.10 - (select min( abs(EKP - 2.10) ) FROM deineEKPAbfrage ) ) 
  , (2.10 + (select min( abs(EKP - 2.10) ) FROM deineEKPAbfrage ) )
  );

-> in diesem Beispiel taucht dein Suchwert, die "2,10€" an 4 Stellen auf - du kannst aber einen Parameter nur einmal übergeben bzw. einen übergebenen Parameter nur einmal verwenden..

Schreib ein Stück Code/VBA von Hand, die vorgefertigte DLookup-Funktion kann das nicht.
Und VBA mit zwei einzelnen abgefeuerten Statements wäre in diesem Fall auch schneller als ein um jeden Preis in ein Statement geschraubtes SQL.

Oder revidiere die Anforderungen an die Funktionalität: der nächsthöhere oder der nächstniedrigere Preis ist mit DLookup() kein Thema.
Aber der "am nächsten gelegene Preis".

Was soll denn die fachliche Aussage sein, wenn du einen "nächstgelegenen Preis" gefunden hättest bzw wieso wäre denn "2,09€" eher das einleuchtende Ergebnis als "2,14€"?

Grüße
Biber
MoeSys
MoeSys 11.10.2013 um 11:37:59 Uhr
Goto Top
Hi Biber,

der Code macht genau das was ich brauche, DANKE!!


Was soll denn die fachliche Aussage sein, wenn du einen "nächstgelegenen Preis" gefunden hättest bzw wieso
wäre denn "2,09€" eher das einleuchtende Ergebnis als "2,14€"?

einfach nur weil 2,09€ näher an 2,10€ ist...
der Hintergrund ist folgender:
Man kalkuliert Produkte/Maschinen und bietet diese an.
Die Angebote gelten relativ lange, teilweise mehrere Jahre.
Wenn der Kunde nun nach einem Jahr bestellt versucht man den damals kalkulierten Preis zu halten, obwohl sich in der Zwischenzeit die Materialpreise geändert haben.
Deshalb muss man nach dem "nächstgelegenen Material-Preis" suchen um sich dem damaligen Angebotspreis zu nähern.
Manchmal zahlt man eben auch drauf....

Schönen Gruß
MoeSys
MoeSys
MoeSys 11.10.2013 um 11:52:15 Uhr
Goto Top
Eins noch:

Wenn ich nun nach 2,05 suche und in der Abfrage sind die Werte 2,04 und 2,06 enthalten dann spuckt mir das Statement 2,04 aus. Passt ja auch soweit.
Schöner wäre es jedoch wenn ich beide Werte angezeigt bekommen könnte.

LG
MoeSys
Biber
Biber 11.10.2013 aktualisiert um 23:00:16 Uhr
Goto Top
Moin MoeSys,

ich hatte dir eine Programmlogik unterstellt, die genau einen Wert erwartet - wenn zwei Werte gleich weit entfernt vom "Wunschwert" sind, dann habe ich mit "SELECT MIN( EKP) ...." den kleineren genommen.

Weil... man spart ja, wo man kann.

Wenn du beide Werte anzeigen willst, dann einfach mit "SELECT EKP FROM..." (also ohne MIN()-Aggregatsfunktion.

Wie aber auch schon oben geschrieben - ich würde es nicht um jeden Preis in EINE SQL-Abfrage quetschen aus Performanzgründen.
Ich würde zuerst mit "SELECT. min( abs(EKP - 2.10) ) FROM deineEKPAbfrage " den kleinsten Abstand vom Wunschwert ermitteln und mit diesem Wert ein zweites Statement hinterherjagen (Statement wie oben, aber das Ergebnis von Statement1 eingesetzt).

Falls du das über irgendeinen VBA-Schnipsel machst.

Grüße
Biber
MoeSys
MoeSys 14.10.2013 um 09:38:46 Uhr
Goto Top
Hi Biber,

vielen Dank für die hilfreichen Tipps, funktioniert besten face-smile

Schönen Gruß
MoeSys