Reputation: 165
I am created two stringList BookmarkedFields and BookmarkedRecord
BookmarkedFields
it contains column name of the dataset
BookmarkedRecord
it like field:fieldValue
field is column name from BookmarkedFields
fieldValue is value according to column
Here is procedure to stored the record in the stringList as column and column's value for record.
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;
I try to find that record already stored in stringlist into the dataset. But when start locating into dataset the value in stringlist automatically gets change and it shows the value which is pointed in dataset. Object of stringlist which is automatically get changed.
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;
How to tackle from this situation, How did I persists the value in stringlist that stored, Don't want to be automatically changed object of stringlist.
Upvotes: 1
Views: 464
Reputation: 30745
Suppose you have a StringList containing one or more entries like this
FieldNameN=FieldValueN
Obviously, this is much simpler than using two separate TStringLists. Then, the following code will locate the dataset record
matching these fieldname/value pairs. It uses four utility functions to convert
the contents of the StringList into the arguments to be passed the the dataset's
Locate function. These utility functions are quite lengthy but useful additions to a general purpose toolbox. HeadOf
and TailOf
are useful for parsing Name/Value pairs. MakeFieldNameList' and
MakeFieldValueListare useful for constructing the arguments to be passed to
TDataSet.Locate`.
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;
The utility functions are
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;
If you really must encode your field values as Objects in your StringList, the code could readily be adapted to that.
Btw, the MakeFieldNameList
, MakeFieldValueList
and LocateUsingStrings
functions have a TStrings input parameter rather than a TStringList one so that they aren't restricted to TStringlists.
Btw, Locate does not in general require keyfields, if you mean fields in an index on the table.
Upvotes: 1
Reputation: 1866
You are not storing field value in stringlist. This code
BookmarkedRecord.AddObject(BookmarkedFields[I], ADataset.FieldByName(BookmarkedFields[I]));
adds TField
object to TStringList
. Field, not record. TField object is not storing value. It points to field, and every time you call it, value of current record in dataset will be returned. Not "remembered", only current.
If you need to remember value, you can do something like this:
BookmarkedRecord.AddObject(BookmarkedFields[I], TObject(ADataset.FieldByName(BookmarkedFields[I]).AsInteger));
This example is applicable for integer field.
Upvotes: 2