Sie haben eine Reihe von Optionen. Das Beste hängt von einer ganzen Reihe von Überlegungen ab, die Sie in Ihrer Frage nicht erwähnt haben. Ich werde eine sehr kurze Übersicht der Optionen zur Verfügung stellen, um zu vermeiden, dass dies "zu breit" wird. Es liegt an Ihnen, Ihre Wahl zu treffen und die Details herauszufinden. Wenn Sie nicht weiterkommen, können Sie eine neue, spezifischere Frage stellen.
Mit Locate
Eine Lösung Locate
beteiligt ist nur möglich, wenn Ihr Dataset vom selben Feld sortiert Sie suchen auf.
Offensichtlich ist Ihr Suchwert kein eindeutiger Schlüssel. Ich vermute also, dass Sie versuchen, die letzte Zeile zu finden, die mit dem Suchschlüssel in Daten übereinstimmt, die nach einem anderen eindeutigen Feld sortiert sind. (Ansonsten ist das Konzept von letzten bedeutungslos.)
Also ist es sehr wahrscheinlich, dass dies nicht für Sie geeignet ist; es sei denn, Ihre Daten werden nach einem zusammengesetzten Schlüssel Ihres Suchfeldes gefolgt von einem eindeutigen Schlüssel sortiert.
Der Ansatz ist einfach: Navigieren Sie vorwärts, bis Sie eine Zeile gefunden haben, in der der Suchwert nicht übereinstimmt, und rücken Sie dann um eine Zeile zurück.
if not DataSet.Locate(SearchField, SearchValue, []) then
{ handle not found case as desired }
else
begin
while (not DataSet.Eof) and (DataSet.FieldByName(SearchField).Value = SearchValue) do
DataSet.Next;
{ Watch out for case that last row in dataset matches search value }
if (DataSet.FieldByName(SearchField).Value <> SearchValue) then
DataSet.Prior;
end;
Implementieren Sie Ihre eigene Suche
Dies ist geradlinig und wird immer funktionieren. Aber es ist ineffizient, mit O (n) Komplexität. Also nicht für große Datensätze empfohlen.
DataSet.Last;
while (not DataSet.Bof) and (DataSet.FieldByName(SearchField).Value <> SearchValue) do
DataSet.Prior;
HINWEIS: Um das Verhalten von Locate
widerzuspiegeln es ratsam wäre, diese Methode zu verbessern, den Fall zu behandeln, in denen ein Spiel überhaupt nicht zu finden ist. In diesem Fall sollte der aktive Datensatz nicht versehentlich als Nebeneffekt der Suche geändert werden.
Verwenden Filterung
Offensichtlich ist diese Lösung hängt davon ab, ob die Datenmenge Filterung an den Rest des Codes geeignet ist. Aber es ist eine ziemlich einfache Option, und abhängig von Faktoren, die über den Rahmen dieser Antwort hinausgehen, kann es leistungsfähiger als die vorherige Option sein.
DataSet.Filtered := False;
{ The next line may be a little tricky.
Ensure the filter string is appropriate for the data-types involved. }
DataSet.Filter := '<string of the form SearchField = SearchValue>';
DataSet.Filtered := True;
DataSet.Last;
Siehe Dokumentation auf der Filter Eigenschaft.
HINWEIS: Es kann ratsam sein, Vorsichtsmaßnahmen zu ergreifen gegen die Filter redundant einstellen.
Verwenden Sie eine Master-Detail-Beziehung
Diese Option enthalten ist, weil Ihre Frage Code die search stammt aus dem aktiven Datensatz eines anderen Datensatzes anzeigt. Sie verwenden ADO, diese Option steht Ihnen also zur Verfügung.
DataSet.MasterSource := <Appropriate DataSource>;
DataSet.MasterFields := SearchField;
DataSet.Last;
siehe Dokumentation auf master-detail relationships und auf ADO MasterFields.
Offload die Arbeit mit dem RDBMS
Schließlich ist es eine Überlegung wert, eine gespeicherte Prozedur unter Verwendung der Informationen, die Sie direkt aus der Datenbank benötigen. Der Vorteil ist, dass der Server verfügbare Indizes nutzen kann und das Potenzial hat, die performanteste Option bereitzustellen. Auch hier hängt vieles von den Einzelheiten Ihrer Bewerbung ab.
Eine Abfrage in den folgenden Zeilen kann die Basis Ihrer gespeicherten Prozedur bilden.
Dann rufen Sie Ihre gespeicherte Prozedur, und verwenden Sie ihr Ergebnis, um die gewünschte Zeile zu finden.
DataSet.Locate(UniqueField, RowKey, []);
HINWEIS: Vergessen Sie nicht, um die gespeicherte Prozedur zu prüfen NULL
Rückkehr, wenn keine Zeilen mit search existieren.
Allgemeiner Haftungsausschluss
All oben genannte Code ist extrem kurz und nur zur Veranschaulichung. In vielen Fällen ist zusätzlicher Code für eine stabile Implementierung erforderlich.
Zum Beispiel Möglicherweise müssen Sie DisableControls
aktivieren und sie erneut aktivieren.
HINWEIS: Es ist sehr wichtig, mit dem oben bewusst zu sein, die tatsächlichen der Daten in Ihrer Datensätze zu bestellen. Wenn dies nicht berücksichtigt wird, kann dies zu einem falschen Verhalten führen. Auch die letzte Option kann eine schlechter als erwartete Leistung aufweisen, wenn Ihr Dataset nicht nach UniqueKey sortiert ist.
Mit einer Schleife, mit 'Next', bis Sie den ersten nicht übereinstimmenden Datensatz und dann ein' Prior' zu einem zurück zu erreichen. Vergessen Sie nicht, beim Looping auch nach "not Eof" zu suchen, um eine Endlosschleife zu vermeiden. Oder fügen Sie eine zweite Spalte zu Ihrem 'Locate'-Aufruf hinzu, um die Suche genauer zu machen, damit sie mit der Zeile übereinstimmt, die Sie wirklich finden möchten. –
Tatsächlich besteht das Kriterium darin, einen bestimmten Wert in einem bestimmten Feld zu haben, dann ist der letzte hinzugefügte Datensatz das, was wir brauchen (d. H. Das letzte in den ado.locate-Ergebnissen). –
"der letzte Datensatz hinzugefügt" Seien Sie vorsichtig, der letzte Datensatz, der dem Datensatz hinzugefügt wird, ist nicht unbedingt der am Ende Ihrer '.Next'-Schleife; ob dies der Fall ist oder nicht, hängt davon ab, ob der Datensatz nach Einfügereihenfolge geordnet ist. – MartynA