Vamos usar variants para incrementar nossos for in, para isso vamos acrescentar recursos como métodos e propriedades,e invés de nosso enumerador retornar um índice ele retornará uma variant assim podemos acessar suas propriedades, usando da seguinte maneira:
data.First_Name
Além disso, precisamos criar uma class que herde TInvokeableVariantType e sobrescrever alguns métodos.
type
TVarDataRecordType = class(TInvokeableVariantType)
public
procedure Clear(var V: TVarData); override;
procedure Copy(var Dest: TVarData; const Source: TVarData; const Indirect: Boolean); override;
function GetProperty(var Dest: TVarData; const V: TVarData; const Name: string): Boolean; override;
function SetProperty(const V: TVarData; const Name: string; const Value: TVarData): Boolean; override;
end;
type
TVarDataRecordData = packed record
VType: TVarType;
Reserved1, Reserved2, Reserved3: Word;
DataSet: TDataSet;
Reserved4: LongInt;
end;
Agora precisaremos de uma variável global para uma instância de TVarDataRecordType, é uma função retornando o VarType dessa instância e outra função a criação de uma variant desse tipo.
var
VarDataRecordType: TVarDataRecordType = nil;
function VarDataRecord: TVarType;
begin
result := VarDataRecordType.VarType;
end;
function VarDataRecordCreate(ADataSet: TDataSet): Variant;
begin
VarClear(result);
TVarDataRecordData(result).VType := VarDataRecord;
TVarDataRecordData(result).DataSet := ADataSet;
end;
function TVarDataRecordType.GetProperty(var Dest: TVarData; const V: TVarData; const Name: string): Boolean;
var
fld: TField;
begin
fld := TVarDataRecordData(V).DataSet.FindField(Name);
result := (fld <> nil);
if result then
Variant(dest) := fld.Value;
end;
function TVarDataRecordType.SetProperty(const V: TVarData; const Name: string; const Value: TVarData): Boolean;
var
fld: TField;
begin
fld := TVarDataRecordData(V).DataSet.FindField(Name);
result := (fld <> nil);
if result then begin
TVarDataRecordData(V).DataSet.Edit;
fld.Value := Variant(Value);
end;
end;
function TDataSetHelper.GetCurrentRec: Variant; begin Result := VarDataRecordCreate(Self); end; É isso, agora podemos escrever o nosso código da seguinte maneira:
for Employee in QuEmployee do begin
S := Trim(Format('%s %s', [Employee.First_Name, Employee.Last_Name]));
if Employee.Hire_Date < EncodeDate(1991, 1, 1) then
S := '*' + S;
MemOutput.Lines.Add(S);
end;
for Employee in QuEmployee do begin
s := Employee.First_Name;
Employee.First_Name := Employee.Last_Name;
Employee.Last_Name := s;
end;