Results 1 to 10 of 10

Thread: loop in loop probleem

  1. #1

    loop in loop probleem

    Ik zit ernstig te puzzelen hoe ik dit probleem kan verhelpen, probeer te voorkomen dat er een dubbele waarde naar de database wordt geschreven. Ik wil graag dat de toe te voegen data eerst wordt gecheckt of het primaire veld al bestaat (Id : String). Als hij bestaat moet hij gewoon worden overgeslagen en doorgaan met de evt volgende record.
    Ik wil graag meerdere records toevoegen, en ze moeten allemaal gecontroleerd worden.
    Mogelijk zien jullie wat ik kan verbeteren in mijn code.

    Code:
    procedure TForm1.btnToDatabaseClick(Sender: TObject);
    
    
    var I, MarkerAdd, position : Integer;
       KksId, KksOmschrijving, KksLokatie : String;
    begin
     CtrlMemo.Lines.Add('records in database : ' + IntToStr(FDTable1.RecordCount));
    
     for I := 0 to FinalFile.Count-1 do
         begin
    
            while not FDTable1.Eof do
             begin
              MarkerAdd := 0;
              KksId := FinalFile[I];
              KksId := AnsiUpperCase(KksId);
              position := AnsiPos(';', KksId);
              delete(KksId, position, KksId.Length);
              KksOmschrijving := FinalFile[I];
              KksOmschrijving := AnsiUpperCase(KksOmschrijving);
              delete(KksOmschrijving, 1, position);
              if KksId = FDTable1.FieldByName('Id').AsString then
                begin
                  MarkerAdd :=  FDTable1.RecNo + 1;  //anders kan de dubble ook in de 1ste record zitten
                  showmessage('dubbel joh');
                end;
               { else
                 begin
                   //ff nix
                 end;   }
              FDTable1.Next;
             //end;
             if MarkerAdd = 0  then
               begin
                fdqDoInsert.Close;
                   fdqDoInsert.SQL.Text := 'INSERT INTO ToKks(Id, Omschrijving, Lokatie) VALUES('+QuotedStr(KksId)+','+QuotedStr(KksOmschrijving)+','+QuotedStr('nader te bepalen')+')';
                   fdqDoInsert.ExecSQL;
                   CtrlMemo.Lines.Add(KksId);
                   FDTable1.Next;
               end;
             //FDTable1.Next;
             end;
    
         end;
    
     UpdateGrid; //aparte procedure bepaal autosize collum en refresh stringgrid
     CtrlMemo.Lines.Add('records in database : ' + IntToStr(FDTable1.RecordCount));
    end;

  2. #2
    Senior Member Delphiwizard's Avatar
    Join Date
    Dec 2006
    Location
    België
    Posts
    160
    Sowieso denk ik dat er een fout in de logica zit, er wordt in de for loop net voor de while not eof geen First uitgevoerd, maw na de eerste loop blijft je dataset op Eof staan denk ik.

    for I := 0 to FinalFile.Count-1 do
    begin
    FDTable1.First;
    while not FDTable1.Eof do

  3. #3
    Senior Member Delphiwizard's Avatar
    Join Date
    Dec 2006
    Location
    België
    Posts
    160
    Ik zou een andere logica gebruiken, voorbeeld:

    - Gebruik Disablecontrols en enablecontrols in een try...finally
    - Gebruik de Dataset lookup method om te zoeken als de waarde reeds bestaat ipv een while not eof uit te voeren
    Zie http://docwiki.embarcadero.com/RADSt...n/Using_Lookup

    Delphi Code:
    1. Try
    2.    FBTable1.DisableControls;
    3.    for I := 0 to FinalFile.Count-1 do
    4.    begin
    5.       Id := FDTable1.Lookup();
    6.       if Id = NULL then
    7.       //Waarde zit nog niet in de tabel, toevoegen
    8.         FDTable1.Insert......;
    9.    end;
    10. Finally
    11.    UpdateGrid; //aparte procedure bepaal autosize collum en refresh stringgrid
    12.    CtrlMemo.Lines.Add('records in database : ' + IntToStr(FDTable1.RecordCount));
    13.    FBTable1.EnableControls;
    14. end;

  4. #4
    FDTable1.First gaf geen verbetering.......

    voor wat betreft de Lookup functie gaat mijn kennis nog niet ver genoeg, ben even aan het zoeken hoe deze precies werkt, dit onderzoek loopt nog. Wel bedankt voor je antwoord.

  5. #5
    Senior Member Delphiwizard's Avatar
    Join Date
    Dec 2006
    Location
    België
    Posts
    160
    Lookup doet hetzelfde als locate zonder effectief in de dataset dat record te gaan selecteren, perfect om op te zoeken als een bepaalde waarde in een bepaald veld in een tabel reeds bestaat.
    Dat is , denk ik, precies wat je nodig hebt, voor elke waarde in FinalFile kijken als het er reeds in zit, en indien niet toevoegen in de tabel.

    Voorbeeld FDTable1.Lookup(Veld, ZoekWaarde, ReturnVeld); en retourneert de waarde in aan Variant of Variant Array.
    In jouw code zou dit, vermoed ik, FDTable1.Lookup('ID', KksId, 'ID'); moeten zijn, nadat je uiteraard eerst je KksId hebt bepaald adhv de waarden in je FinalFile lijst.

    Gaat ook sneller uiteraard dan die FdTable1.Eof loop.

  6. #6
    Senior Member Delphiwizard's Avatar
    Join Date
    Dec 2006
    Location
    België
    Posts
    160
    Als je even uitlegt wat er precies in FinalFile zit dan maak ik je een uitgewerkt voorbeeld, FinalFile is een Stringlist met 'Id; Omschrijving; Locatie', klopt dit?

  7. #7
    Senior Member Delphiwizard's Avatar
    Join Date
    Dec 2006
    Location
    België
    Posts
    160
    Delphi Code:
    1. procedure TForm1.Button1Click(Sender: TObject);
    2. Var List: TStringList;
    3.     i:Integer;
    4.     Splitted: TArray<String>;
    5.     LookupValue: Variant;
    6. begin
    7.   Try
    8.     List := TStringList.Create;
    9.     List.Add('1;Oms1;Loc1');
    10.     List.Add('2;Oms2;Loc2');
    11.     List.Add('3;Oms3;Loc3');
    12.     List.Add('4;Oms4;Loc4');
    13.     List.Add('5;Oms5;Loc5');
    14.     List.Add('6;Oms6;Loc6');
    15.  
    16.     Try
    17.       FBTable1.DisableControls;
    18.  
    19.       for i := 0 to List.Count -1 do
    20.       begin
    21.         Splitted := List[i].Split([';']);
    22.         FDTable1.Refresh;
    23.         LookupValue := FDTable1.Lookup('ID', Splitted[0], 'ID');
    24.         if LookupValue = NULL  then
    25.         Begin
    26.           FDTable1.Insert;
    27.           FDTable1.FieldByName('ID').AsString := Splitted[0];
    28.           FDTable1.FieldByName('Omschrijving').AsString := Splitted[1];
    29.           FDTable1.FieldByName('Lokatie').AsString := Splitted[2];
    30.           FDTable1.post;
    31.         End;
    32.       end;
    33.     Finally
    34.       FBTable1.EnableControls;
    35.       UpdateGrid; //aparte procedure bepaal autosize collum en refresh stringgrid
    36.       CtrlMemo.Lines.Add('records in database : ' + IntToStr(FDTable1.RecordCount));
    37.     End;
    38.  
    39.   Finally
    40.     List.Free;
    41.   End;
    42. end;

    Zoiets zou het denk ik moeten doen, in dit voorbeeld heb ik uiteraard mijn stringlist nog moeten creëren en opbouwen.
    Ik gebruik de String helper function Split om de waarden tussen de ';' delimiter op te delen.
    Hopelijk heb je hier iets aan?

  8. #8
    Wouw..... Super man, je code werkt als een trein. En bedankt voor je heldere uitleg (was al aan het kijken hoe de lookup nu werkte maar kwam er zo vlug niet achter).
    De FinalFile is inderdaad een TStringlist. (met uiteraard kks, omschrijving en lokatie).
    Harstikke bedankt Delphiwizard.

  9. #9
    Senior Member Delphiwizard's Avatar
    Join Date
    Dec 2006
    Location
    België
    Posts
    160
    En die Split helper functie maakt het ook wat eenvoudiger om de strings op te splitsen, en je hebt nu geen aparte insert query meer nodig
    Probeer je ook eens zonder de FDTable1.Refresh? Want ik denk dat deze eigenlijk niet nodig is.

    Graag gedaan no problemo

  10. #10
    Quote Originally Posted by Delphiwizard View Post
    Probeer je ook eens zonder de FDTable1.Refresh? Want ik denk dat deze eigenlijk niet nodig is.
    Als je FDTable1.Resfresh weglaat dan wordt de datum en tijd van de database niet aangepast (gewijzigd / lastmodified). Heb hem wel achterin de loop gezet zodat hij het al gebruikt als de loop is beëindigd.

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •