Search code examples
delphilistviewdelphi-xe5

Register and delete ITEM access database - Delphi


I am sending to the database, items of a ListView, after sending have to delete the item sent.

Signing up is performed normally, but my problem is time to delete the items. Which generates the following error:

access violation at address 0073F82E in module "project1.exe". Read OF address 00000008

What I have to do to not generate this error. Because it only occurs when I try to delete the files (Registration in the database normally occur until some item generates this error).

if LstbxDados.Items.Count <= 0 then begin
    exit;
end;

//try
    ADOConnection1.Connected := true;
    try

       with ADOCommand1 do begin
           CommandText  := 'INSERT INTO IP (ti_ip, url_ip, ima_ip, desc_ip,id_ip, data_ip, cat_ip,cad_ip) VALUES ( :a, :b, :c, :d, :e, :f, :g, NOW() )';
           for I := 0 to LstbxDados.Items.Count - 1 do begin
              parameters.parambyname('a').value := Trim(LstbxDados.Items.Item[i].SubItems[0]);
              parameters.parambyname('b').value := Trim(LstbxDados.Items.Item[i].SubItems[1]);
              parameters.parambyname('c').value := Trim(LstbxDados.Items.Item[i].SubItems[2]);
              parameters.parambyname('d').value := Trim(LstbxDados.Items.Item[i].SubItems[3]);
              parameters.parambyname('e').value := Trim(LstbxDados.Items.Item[i].SubItems[4]);
              if Trim(LstbxDados.Items.Item[i].SubItems[5]) <> '' then begin
                  parameters.parambyname('f').value := StrTodate(Trim(LstbxDados.Items.Item[i].SubItems[5]));
              end else begin
                  parameters.parambyname('f').value := null;
              end;
              parameters.parambyname('g').value := Trim(LstbxDados.Items.Item[i].SubItems[6]);
              Execute;
              LstbxDados.Items.Delete(i);
           end;
       end;
    finally
        ADOConnection1.Connected := false;
    end;
//except
//    respostas(9);
//end;

Solution

  • As explained in comments, this happens because you're deleting the Items in a loop which assumes (because of

    for I := 0 to LstbxDados.Items.Count - 1 do
    

    ) that the Items.Count remains constant, whereas in fact it goes down by one each time you delete an Item. So the Item which was number [Count -1] first time around the loop, no longer is by the time it's its turn to be deleted, because there are then fewer Items than the initial value of Count - 1.

    Solution: Use

    for I := LstbxDados.Items.Count - 1 downto 0 do
    

    Btw, my first thought was to use a while loop:

    while LstbxDados.Items.Count > 0 do begin
    

    but see @TLama's comment and be careful about your Items array indexing if you do it that way.