[Gelöst] Unklarheit bei Befehlen FINDSET, FINDFIRST, etc.

11. Juli 2006 10:44

Mit Version 4.0 SP2 stehen ja neue Befehle für das Recordhandling zur Verfügung. Schrieb man bisher

Code:
IF Record.FIND('-') THEN REPEAT


so sollte man aus Performancegründen neu folgenden Code benutzen

Code:
IF Record.FINDSET THEN REPEAT


FINDFIRST und FINDLAST kommen dann zum Einsatz, wenn man jeweils nur genau den ersten, bzw. den letzten Record benötigt.

Meine Frage nun:
Weiss jemand, wie der Ersatz lautet für FIND('plus'):

Code:
IF Record.FIND('plus') THEN REPEAT
UNTIL  Record.next(-1) = 0


Ich habe nichts gefunden beim Befehl FINDSET, das es ermöglichen würde, rückwärts durch die Records zu laufen.

Weiss da jemand etwas dazu?

(Das plus-zeichen wird seltsamerweise vom Editor verschluckt, deshalb das ausgeschriebene Wort 'plus')
Zuletzt geändert von rotsch am 11. Juli 2006 20:17, insgesamt 1-mal geändert.

11. Juli 2006 13:27

Hi,

Zum FINDSET(FALSE,FALSE) eine Anmerkung. Mann soll es nur verwenden wenn man weniger als die eingestellten (meist 500) Datensätze hat. Sonst soll man FIND('-') oder FIND(true) verwenden. Diese beiden scheinen im Prinzip das selbe zu machen.

11. Juli 2006 16:11

FINDLAST ist der SQL-optimierte FIND('+') - Ersatz. Über rec.Next(-1) kann man dann rückwärts laufen. Vorher rec.ASCENDING(False) und vorwärts laufen sollte aber zum gleichen Ergebnis führen.

FINDSET hat bei richtig gesetzten Parametern eine bessere Performance wenn normale oder Primärschlüsselfelder geändert werden sollen.

Verfügbar sind die neuen Befehle schon seit 4.0 SP1.

11. Juli 2006 17:09

Nun mit dem FindLast muss ich Dir etwas wiedersprechen, denn es ersetzt FIND('+') nur wenn man eben nicht über die Datenmenge laufen möchte sondern nur den letzten DS will.
Denn er selectiert mit einem SQL Befehl bei dem nur ein DS selectiert wird. Genau das selbe gilt für FindFirst.

Code:
Rec.FindFirst;
Repeat
Until Rec.Next = 0;


ist als eben nicht zu empfehlen.

Man darf bei der Programmierung nicht einfach alle Find('-') mit FindFirst ersetzten.

Genauso wie man nicht alle:
Code:
Rec.Find('-');
Repeat
Until Rec.Next = 0;

durch ein FindSet ersezten kann.

11. Juli 2006 18:07

Die Unterlagen von Microsoft bei der Vorstellung von 4.0 SP1 sagen allerdings aus, Find('-') und Find('+') generell durch FINDFIRST und FINDLAST ersetzen, wenn nur ein Datensatz benötigt wird. Der Native Server übersetzt diese ohnehin wieder in die alten Befehle zurück. Der FINDSET holt gleich alle gefilterten Sätze in den Cache, dadurch kann der SQL -Server sie erheblich schneller modifizieren. Es ist eine Abfrage ohne Cursor, für die geringere Serverressourcen erforderlich sind.
Ich hoffe, dass bei Version 5 der SQL-Server dann optimal läuft, denn der native Server wird diese Version wohl nicht mehr erleben.

Re: Unklarheit bei neuen Befehlen FINDSET, FINDFIRST, etc.

11. Juli 2006 18:34

rotsch hat geschrieben:Ich habe nichts gefunden beim Befehl FINDSET, das es ermöglichen würde, rückwärts durch die Records zu laufen.


Mach vorher einfach ein ascending(false) und dann den findset
anschließend kannst du dann einfach mit next durch die Tabelle rutschen.
Da rückwärts sortiert ist, entspricht das dann dem von hinten nach vorne gehen bei normaler Sortierung.

Ooops: Sehe gerade, dass Kowa schon sinngemäß das gleiche geschrieben hatte :oops:

11. Juli 2006 20:16

Danke für die vielen Hinweise und Antworten.

Ich denke, die Variante ASCENDING(FASLE) dürfte die Lösung sein.


Anmerkung zu FINDFIRST/FINDLAST:
Ich habe zur Sicherheit nochmals die Hilfe konsultiert.

Das steht:

FINDFIRST
This function should be used instead of FIND('-') when you only need the first record.

FINDLAST
This function should be used instead of FIND('+') when you only need the last record.

6. September 2007 11:58

Kowa hat geschrieben:Vorher rec.ASCENDING(False) und vorwärts laufen sollte aber zum gleichen Ergebnis führen.


Da muss ich leider widersprechen. Habs eben probiert und Navision hat mich zu Laufzeit verprügelt ;-)

6. September 2007 18:48

Natalie hat geschrieben:
Kowa hat geschrieben:Vorher rec.ASCENDING(False) und vorwärts laufen sollte aber zum gleichen Ergebnis führen.


Da muss ich leider widersprechen. Habs eben probiert und Navision hat mich zu Laufzeit verprügelt ;-)


Inwiefern verprügelt ?
Der folgende Code läuft bei mir vom letzten Artikel bis zum ersten ( zumindest mit dem Native Server)

Code:
Item.RESET;
Item.ASCENDING(FALSE);
Item.FINDFIRST;
REPEAT
  IF CONFIRM(STRSUBSTNO('Artikelnr. %1 : Abbrechen ?',Item."No.")) THEN
    EXIT;
UNTIL Item.NEXT =0;

6. September 2007 19:02

Iiiiiih!
Du verwendest FINDFIRST + REPEAT.
Das soll man aus performancetechnischen Gründen unbedingt unterlassen. Steht auch so in der Onlinehilfe drin.

Richtig ist FINDSET + REPEAT. Und genau dabei knallt es, wenn du auf deine Weise die Sortierreihenfolge änderst - siehe Onlinehilfe!

6. September 2007 19:59

Das FINDFIRST beim SQL Server bei mehr als einem Datensatz von der Perfomance nicht optimal ist, ist sicherlich richtig ( seht ja auch schon in Rogers erstem Beitrag :wink:), aber funktionieren tut es. Ob die Performanceeinbuße wirklich ein Problem ist , hängt ja auch davon ab, wieviele Datensätze (in welcher Größe) dann überhaupt verarbeitet werden.

Auch in den neuesten 5.0 Standardobjekten wird an etlichen Stellen sogar immer noch mit FIND('-')/FIND('+') und anschließendem REPEAT gearbeitet z. B. in Codeunit 442 und 444 beim Verarbeiten der Anzahlungspuffertabellen.
So ganz einig scheinen sie sich in Dänemark auch nicht zu sein. :-)

FINDSET vs. FIND('-')

26. Mai 2008 15:55

Kleines Update, weil erst seit 5.0 so explizit in die Schulungsunterlagen aufgenommen und von dort entnommen:

FIND('-') ist keineswegs unnötig geworden.
Wir unterstellen einen Schleifendurchlauf a la FIND/FINDSET -> REPEAT ... UNTIL.

1. Die Records werden nicht innerhalb der Schleife geändert.
a) <= 500 durchlaufene Datensätze: FINDSET(FALSE);
b) > 500: FIND('-');

2. Records sollen innerhalb der Schleife geändert werden:
a) <= 500: LOCKTABLE; FINDSET(FALSE); !!!!!!!!!!
b) > 500: FINDSET(TRUE);

Edit: 500 ist kein fester Wert, sondern kann eingesehen werden unter Datei -> Datenbank ändern -> Registerkarte "Erweitert" -> Datensatzmenge
Wurde ab 2009 SP1 verkleinert auf 50!

Re: [Gelöst] Unklarheit bei Befehlen FINDSET, FINDFIRST, etc

18. April 2023 08:54

Nach 15 Jahren etwas neues, ab AL 11.x für BC 22.x den (schon länger funktionslosen) Parameter UpdateKey nicht mehr verwenden: RECORD.FINDSET(ForModify,UpdateKey), sonst Warnung "depecrated". Das in der Doku erwähnte "future release" ist also da :-) .
https://learn.microsoft.com/en-us/dynamics365/business-central/dev-itpro/developer/methods-auto/record/record-findset-method#remarks