Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Wrong data moving from TListbox to TStringGrid

I am working on Delphi 7. I have one TListBox and one TStringGrid with two columns (with no fixed row or column). I have data in the TListBox as follows:

Available Elements - a123 (a123) Available Elements - a1234 (a1234) Available Elements - a12345 (a12345)

And the TStringGrid is having following data as follows:

Column1 Column2

a1 Available Elements - a1 a2 Available Elements - a12

If I select the first item in the TListbox i.e. a123 and execute following button click event procedure, then the last item data ie a12345 is getting moved into the grid.

Could anybody put the focus on what I am doing wrong in the following code. Following code moves the seleted item in the TListbox to TStringgird's two columns:

procedure TForm1.btnMoveLeftClick(Sender: TObject);
var
  sString : String;
  i : Integer;
begin
  for i := 0 to ListBox1.Items.Count - 1 do
  begin
      {-- Is this status selected? --}
      if ListBox1.Selected[i] then
      begin
        sString := Trim(ListBox1.Items[i]);

        {-- Delete selected status. --}
          ListBox1.Items.Delete (i);

        if ((grdVFormDetails.RowCount >= 1) And (Trim(grdVFormDetails.Cells[0, 0]) <> EmptyStr)) then
          grdVFormDetails.RowCount := grdVFormDetails.RowCount+1;

        grdVFormDetails.Cols[1].Add(Copy(sString, 1, Pos('(', sString) - 1));

        sString := Copy(sString, Pos('(', sString) + 1, Length(sString));
        sString := Copy(sString, Pos('(', sString) + 1, Length(sString) - 1);

        grdVFormDetails.Cols[0].Add(sString);


        break;
      end;
  end;
end;
like image 995
Vishal Tiwari Avatar asked Feb 14 '26 10:02

Vishal Tiwari


1 Answers

NEVER delete Items of TList in the FOR loop.

The issue in this line:

  ListBox1.Items.Delete (i);

The loop goes from i:=0 to 2. Item - 0 is selected and you delete it. What we got on the next repeat? i=1 but here are only 2 items left instead of 3 (all following items shifted) and i points at the last item not the second. On the next repeat when i=3 we will get "Index out of bound" error. You should delete Item only after FOR loop to avoid this issue.

procedure TForm1.btnMoveLeftClick(Sender: TObject);
var
  sString : String;
  i : Integer;
  k: integer;
begin
  k:=-1; 
  for i := 0 to ListBox1.Items.Count - 1 do
  begin
      {-- Is this status selected? --}
      if ListBox1.Selected[i] then
      begin
        sString := Trim(ListBox1.Items[i]);

        {-- Delete selected status. --}
          k:=i;         

        if ((grdVFormDetails.RowCount >= 1) And (Trim(grdVFormDetails.Cells[0, 0]) <> EmptyStr)) then
          grdVFormDetails.RowCount := grdVFormDetails.RowCount+1;

        grdVFormDetails.Cols[1].Add(Copy(sString, 1, Pos('(', sString) - 1));

        sString := Copy(sString, Pos('(', sString) + 1, Length(sString));
        sString := Copy(sString, Pos('(', sString) + 1, Length(sString) - 1);

        grdVFormDetails.Cols[0].Add(sString);


        break;
      end;
  end;
  if k>=0 then  ListBox1.Items.Delete (k);

end;
like image 174
valex Avatar answered Feb 17 '26 12:02

valex



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!