[Gelöst] Findset und Repeat oder nur Repeat

22. September 2010 11:59

Hallo,

ich möchte alle Customer durchlaufen und einen Haken setzen wenn etwas zutrift.

Folgender Code:
Code:
WITH Customer DO BEGIN
  RESET;
  SETCURRENTKEY("No.");
  IF FINDSET THEN BEGIN
    REPEAT
      Feldwert := FALSE;
      IF Prüfung("No.") THEN
        Feldwert := TRUE;       
      MODIFY;                 
    UNTIL NEXT = 0;
  END;
END;


Meine Frage: Muss ich RESET, FINDSET und SETCURRENTKEY verwenden oder reicht es auch aus, wenn ich folgendes mache?
Code:
WITH Customer DO
  REPEAT
    Feldwert := FALSE;
    IF Prüfung("No.") THEN
      Feldwert := TRUE;
    MODIFY;
  UNTIL NEXT = 0;


Was wäre denn die Vorbildliche Lösung?
Gruß Ralf
Zuletzt geändert von ralf5 am 22. September 2010 15:27, insgesamt 1-mal geändert.

Re: Findset und Repeat oder nur Repeat

22. September 2010 12:07

Hallo,

den SETCURRENTKEY im 1. Beispiel kannst du weglassen, ansonsten ist das O.K..
Wenn du im OnModify-Trigger noch andere Tabellen aktualisierst, oder du das Änderungsdatum des Debitors aktualisieren möchtest, dann solltest du noch MODIFY(true) verwenden.

Gruß, Fiddi

Re: Findset und Repeat oder nur Repeat

22. September 2010 12:14

Mit FINDSET(TRUE,FALSE) ist beim SQL-Server die Performance etwas besser, wenn wie hier Nicht-PK Felder modifiziert werden.
Onlinehilfe hat geschrieben:The general rules for using FINDSET are:

• FINDSET(FALSE,FALSE)- read-only. This uses no server cursors and the record set is read with a single server call.

• FINDSET(TRUE,FALSE)- is used to update non-key fields. This uses a cursor with a fetch buffer similar to FIND(‘-’).

• FINDSET(TRUE,TRUE)- is used to update key fields.

Note
This function is designed to optimize finding and updating sets. If you set any or both of the parameters to FALSE, you can still modify the records in the set but these updates will not be performed optimally.

Re: Findset und Repeat oder nur Repeat

22. September 2010 12:22

Danke schon mal für die Antworten.

Nochmal Explicit die Frage:

Brauche Ich
Code:
IF FINDSET THEN
  REPEAT
...


Oder langt auch einfach nur
Code:
REPEAT
...


Ich bekomme bei beiden Varianten das selbe Ergebnis.

Gruß
Ralf

Re: Findset und Repeat oder nur Repeat

22. September 2010 12:30

Da kann man nur mit Radio Eriwan antworten: Im Prinzip ist es schon egal, ob das ganze allerdings auf dem SQL-Server Performance- Probleme mit sich bringt müsste man testen.
Der Find????-Befehl sorgt immer für einen definierten Zustand.
Ein weiteres Problem tritt bei mir unter 2009 auf. Dort wird unter bestimmten Bedingungen ohne FIND???? keine Transaktion gestartet. Man bekommt dann ein Fehlermeldung, dass man doch bitte erst eine Transaktion starten möge bevor man Daten verändert.

Gruß, Fiddi

Re: Findset und Repeat oder nur Repeat

22. September 2010 12:34

ralf5 hat geschrieben:Danke schon mal für die Antworten.

Nochmal Explicit die Frage:

Brauche Ich
Code:
IF FINDSET THEN
  REPEAT
...


Oder langt auch einfach nur
Code:
REPEAT
...


Ich bekomme bei beiden Varianten das selbe Ergebnis.

Gruß
Ralf


Bei dir ist die Tabelle Customer ja mit Stammdaten gefüllt, daher kommt dasselbe Ergebnis raus. IF FIND... THEN sorgt dafür, dass wenn er nix findet, z.B. du wendest das aus Versehen auf einen neuen, leeren Mandanten an, er sofort aussteigt ohne in die REPEAT Schleife reinzulaufen. Das spart dann paar miliseconds :-)

Edit: wenn das IF FIND THEN nicht verwendet wird, dann gibt es einen Laufzeitfehler:
viewtopic.php?f=19&t=8341#PK

Re: Findset und Repeat oder nur Repeat

22. September 2010 14:11

Lord_British hat geschrieben:Edit: wenn das IF FIND THEN nicht verwendet wird, dann gibt es einen Laufzeitfehler:


Bei mir nicht :-)

Re: Findset und Repeat oder nur Repeat

22. September 2010 14:18

Denkfehler meinerseits :!: :!:

Wenn du die REPEAT-Schleife ohne ein FIND??? aufrufst, ist beim ersten Durchlauf normalerweise die Record- Variable nicht gefüllt (kommt auf den vorherigen Code an). Wenn du einen Record änderst, den du noch nicht gelesen hast, gibt es normalerweise eine Fehlermeldung.

Gruß, Fiddi

Re: Findset und Repeat oder nur Repeat

22. September 2010 14:34

fiddi hat geschrieben:Denkfehler meinerseits :!: :!:

Wenn du die REPEAT-Schleife ohne ein FIND??? aufrufst, ist beim ersten Durchlauf normalerweise die Record- Variable nicht gefüllt (kommt auf den vorherigen Code an). Wenn du einen Record änderst, den du noch nicht gelesen hast, gibt es normalerweise eine Fehlermeldung.

Gruß, Fiddi



Also:
- ich erstelle eine neue Codunit,
- deklariere eine Variable Customer (Subtype=Customer)
- und führe folgenden Code aus:

Code:
REPEAT
  x += 1;
  Customer."Name 2" := 'HALLO';
  Customer.MODIFY;
  Customer.NEXT;
UNTIL x = 3;


Ergebnis: Es gibt keinen Fehler und in den ersten 3 Datensätzen steht im Namen 2 HALLO drin.

Gruß
Ralf
Es gibt keinen Fehler

Re: Findset und Repeat oder nur Repeat

22. September 2010 14:57

Gleicher Code in 2009 macht Peng :-? .
Kann auch nicht funktionieren, es sei denn du hast fehlerhafter Weise einen Debitor mit "No." = '' (sprich leer). Das kommt wahrscheinlich daher, weil schon an anderer Stelle mit undefinierten Zuständen (sprich ohne FIND) gearbeitet wurde :-( .

Gruß, Fiddi

Re: Findset und Repeat oder nur Repeat

22. September 2010 15:04

@Fiddi

Ja, das stimmt ich habe einen Debitor mit No. = leer. Ich dachte das wäre standardmäßig so. :-|

Denn dieser leere Debitor dient als Vorlage wenn ich einen neuen erstelle. Sprich alles was ich in den leeren Debitor schreibe erscheint das auch bei jeder Neuanlage.

Gleich vorweg: Der leere Debitor is net von mir :-D

Gruß Ralf

Re: Findset und Repeat oder nur Repeat

22. September 2010 15:13

Es gibt im Standard die Debitorenvorlagen, die solltest du benutzen für Neuanlagen.

Dieser leere Debitor kann dir einiges an Kopfzerbrechen bereiten, da Sicherheitsprüfungen die auf eine leere Dbitorennummer prüfen u.U. nicht mehr funktionieren. Daher solltest du den schnellstmöglich loswerden. Das gilt auch für leere Datensätze (heißt leere Primärschlüssel) in anderen Tabellen.

Gruß, Fiddi

Re: Findset und Repeat oder nur Repeat

22. September 2010 15:26

Ja, da lasse ich lieber die Finger weg. Das hat unser Partner so verhackstückelt, das das nicht mehr wartbar ist. :-(

Es geht allerdings auch noch wenn das NEXT zuerst kommt, also:
REPEAT
x += 1;
Customer.NEXT;
Customer."Name 2" := 'HALLO';
Customer.MODIFY;
UNTIL x = 3;

Werde es aber doch lieber mit FIND/FINDSET machen.

Vielen Dank an alle für die Hilfe. :-D

Gruß Ralf