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
Com a class helper será a responsável de retornar a nossa variant adequada, para isso precisamos modificar para GetCurrent retornar uma variante invés o número do registro.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;
Para que economizamos memória, vamos criar somente uma instância depois criarmos record para armazenar os dados da variante.
type
TVarDataRecordData = packed record
VType: TVarType;
Reserved1, Reserved2, Reserved3: Word;
DataSet: TDataSet;
Reserved4: LongInt;
end;
Este nosso record é uma forma simplificada da TVarData record declarado em system.pas como só temos que armazenar uma referência ao conjunto de dados podemos manter da forma mais simples.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;
Os métodos clean e copy TVarDataRecordType são bem simples só precisa chamar os métodos TCustomVariantType. Porém agora nos métodos GetProperty
e SetProperty são aonde as coisas são feitos.
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;
Como já havia citado, agora mudamos na nossa class helper para que o getCurrentRec retorne uma variantfunction 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;
ou
for Employee in QuEmployee do begin
s := Employee.First_Name;
Employee.First_Name := Employee.Last_Name;
Employee.Last_Name := s;
end;
Com um pouco de imaginação e criatividade podemos melhorar muito o nosso trabalho no dia a dia.