TStringList的对象自动更改

时间:2016-08-28 07:24:18

标签: delphi

我创建了两个stringList BookmarkedFields和BookmarkedRecord

BookmarkedFields它包含数据集的列名 BookmarkedRecord就像field:fieldValue   字段是BookmarkedFields的列名   fieldValue是根据列

的值

以下是将记录保存在stringList中作为列和列的记录值的过程。

procedure TBkmrgString.GetIQBookmark(ADataset: TDataset);
var
  I : integer;
begin
  ADataset.GetFieldNames(BookmarkedFields);
  for I := 0 to BookmarkedFields.Count - 1 do
  begin
    BookmarkedRecord.AddObject(BookmarkedFields[I], ADataset.FieldByName(BookmarkedFields[I]));
  end;
end;

我尝试将已经存储在stringlist中的记录发现到数据集中。 但是当开始定位到数据集中时,stringlist中的值会自动获得更改,并显示数据集中指向的值。 stringlist的对象,它会自动被更改。

procedure TBkmrgString.GotoIQBookmark(ADataset: TDataset);
var
 I : Integer;
 a : string;
begin
  ADataset.DisableControls;
  ADataset.First;
  while not ADataset.Eof do
  begin
    I := 0;
    while (I < BookmarkedFields.Count) and
          (ADataset.FieldByName(BookmarkedFields[ I ]).Value =  TField(BookmarkedRecord.Objects[ I ]).Value) do
    begin
      I := I + 1;
    end;
    if I = BookmarkedFields.Count then
      Break
    else
      ADataset.Next;
  end;
  ADataset.EnableControls;
end;

如何解决这种情况,我如何在存储的字符串列表中保留该值,不想自动更改stringlist的对象。

2 个答案:

答案 0 :(得分:2)

您没有在stringlist中存储字段值。这段代码

BookmarkedRecord.AddObject(BookmarkedFields[I], ADataset.FieldByName(BookmarkedFields[I]));

TField对象添加到TStringList。场,不记录。 TField对象不存储值。它指向字段,每次调用它时,将返回数据集中当前记录的值。不记得&#34;只记得当前。

如果你需要记住价值,你可以这样做:

BookmarkedRecord.AddObject(BookmarkedFields[I], TObject(ADataset.FieldByName(BookmarkedFields[I]).AsInteger));

此示例适用于整数字段。

答案 1 :(得分:1)

假设您有一个StringList,其中包含一个或多个这样的条目

  

FieldNameN = FieldValueN

显然,这比使用两个单独的TStringLists简单得多。然后,以下代码将定位数据集记录 匹配这些字段名/值对。它使用四个实用程序函数进行转换 将StringList的内容放入要传递给数据集的参数中 找到功能。这些实用程序功能对于通用工具箱来说是相当冗长但有用的补充。 HeadOfTailOf对于解析名称/值对非常有用。 MakeFieldNameList' and {MakeFieldValueList {1}} TDataSet.Locate`。

are useful for constructing the arguments to be passed to

实用程序功能

function LocateUsingStrings(ADataSet : TDataSet; Strings : TStrings) : Boolean;
var
  FieldNames : String;
  FieldValues : Variant;
begin
  FieldNames := MakeFieldNameList(Strings);
  FieldValues := MakeFieldValueList(Strings);
  Result := ADataSet.Locate(FieldNames, FieldValues, []);
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  if LocateUsingStrings(MyDataSet, Memo1.Lines) then
    Caption := 'found'
  else
    Caption := 'Not found';
end;

如果你真的必须将你的字段值编码为StringList中的对象,那么代码可以很容易地适应它。

顺便说一句,function HeadOf(const Input : String; const Delim : String) : String; // With Input 'Name=Value', returns Name var P : integer; begin P := Pos(Delim, Input); if P > 0 then Result := Copy(Input, 1, Pred(P)) else Result := Input; end; function TailOf(const Input : String; const Delim : String) : String; // With Input 'Name=Value', returns Value var P1, P2, Len : Integer; begin P2 := MaxInt; Len := Length(Input); P1 := Pos(Delim, Input); if P1 > 0 then begin P2 := P1 + Length(Delim); if P2 <= Len then Result := Copy(Input, P2, Len) else Result := Input; end else Result := ''; end; function MakeFieldNameList(Strings : TStrings) : String; var i : Integer; begin // Trim off leading and trailing blank lines Strings.Text := Trim(Strings.Text); Result := ''; for i := 0 to Strings.Count - 1 do begin if Result <> '' then Result := Result + ';'; Result := Result + HeadOf(Strings[i], '='); end; end; function MakeFieldValueList(Strings : TStrings) : Variant; var i : Integer; Value : String; begin // Trim off leading and trailing blank lines Strings.Text := Trim(Strings.Text); if Strings.Count = 1 then begin Value := TailOf(Strings[0], '='); Result := Value; end else begin Result := VarArrayCreate([0, Strings.Count -1], varVariant); for i := 0 to Strings.Count - 1 do begin Value := TailOf(Strings[i], '='); Result[i] := Value; end; end; end; MakeFieldNameListMakeFieldValueList函数有一个TStrings输入参数而不是TStringList参数,因此它们不限于TStringlists。

顺便说一下,Locate确实一般需要关键字段,如果你的意思是字段 桌子上的索引。