首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将错误的数据从TListbox迁移到TStringGrid

将错误的数据从TListbox迁移到TStringGrid
EN

Stack Overflow用户
提问于 2012-12-12 14:00:48
回答 4查看 418关注 0票数 3

我在Delphi7上工作,我有一个TListBox和一个有两列的TStringGrid (没有固定的行或列)。我在TListBox中有如下数据:

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

并且TStringGrid具有如下数据:

Column1 Column2

a1可用元素- a1 a2可用元素- a12

如果我选择TListbox中的第一个项目,即a123,并执行下面的按钮单击事件过程,那么最后一个项目数据,即a12345将被移动到网格中。

有人能把重点放在我在以下代码中做错了什么吗?下面的代码将TListbox中选定的项移动到TStringgird的两列中:

代码语言:javascript
复制
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;
EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2012-12-13 03:15:22

假设您想要像这样解析输入字符串:

代码语言:javascript
复制
'Some text (comment) etc. (12345)'

从输入字符串的开头到第一个开始括号(倒数第一个)包含修剪后的字符串的部分,以获得如下值:

代码语言:javascript
复制
'Some text (comment) etc.'

和输入字符串的最后一个括号中的字符串:

代码语言:javascript
复制
'12345'

如果是这样,您可以使用下面的代码。请注意,列表框中的项应以右括号终止。如果需要,您可以检查此代码的commented version或下载sample project

下面是将焦点项目从列表框移动到字符串网格的部分:

代码语言:javascript
复制
procedure TForm1.MoveLeftButtonClick(Sender: TObject);
var
  S: string;
  I: Integer;
  ItemID: string;
  ItemText: string;
begin
  if ListBox1.ItemIndex = -1 then
    Exit;

  S := ListBox1.Items[ListBox1.ItemIndex];
  for I := Length(S) - 1 downto 1 do
  begin
    if S[I] = '(' then
    begin
      ItemID := Trim(Copy(S, I + 1, Length(S) - I - 1));
      ItemText := Trim(Copy(S, 1, I - 1));
      with StringGrid1 do
      begin
        if (Cells[0, RowCount - 1] <> '') and
          (Cells[1, RowCount - 1] <> '')
        then
          RowCount := RowCount + 1;
        Cells[0, RowCount - 1] := ItemID;
        Cells[1, RowCount - 1] := ItemText;
      end;
      ListBox1.Items.Delete(ListBox1.ItemIndex);
      Break;
    end;
  end;
end;

下面是将选定行从字符串网格移动到列表框的部分:

代码语言:javascript
复制
procedure TForm1.MoveRightButtonClick(Sender: TObject);
var
  I: Integer;
  RowIndex: Integer;
begin
  RowIndex := StringGrid1.Selection.Top;
  if (StringGrid1.Cells[0, RowIndex] <> '') and
    (StringGrid1.Cells[1, RowIndex] <> '') then
  begin
    ListBox1.Items.Add(
      Trim(StringGrid1.Cells[1, RowIndex]) + ' (' +
      Trim(StringGrid1.Cells[0, RowIndex]) + ')'
    );
    for I := RowIndex to StringGrid1.RowCount - 2 do
      StringGrid1.Rows[I].Assign(StringGrid1.Rows[I + 1]);
    if StringGrid1.RowCount > 1 then
      StringGrid1.RowCount := StringGrid1.RowCount - 1
    else
    begin
      StringGrid1.Cells[0, 0] := '';
      StringGrid1.Cells[1, 0] := '';
    end;
  end;
end;
票数 1
EN

Stack Overflow用户

发布于 2012-12-12 14:38:03

从不删除TList循环中的FOR项。

这一行的问题是:

代码语言:javascript
复制
  ListBox1.Items.Delete (i);

循环从i:=0转到2。选中Item -0并将其删除。我们在下一次复习中得到了什么?i=1,但是这里只剩下2项,而不是3项(所有后面的项都被移动了),并且我指向最后一项,而不是第二项。在下一次重复执行i=3时,我们将得到“索引越界”错误。您应该只在FOR循环之后删除项,以避免此问题。

代码语言:javascript
复制
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;
票数 2
EN

Stack Overflow用户

发布于 2012-12-12 14:08:16

我目前还没有安装Delphi,但据我所知,如果ListBox1.Selectedi不会给你正确的结果。您需要首先获取项目,他们检查项目是否被选中。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13833739

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档