Delphi Can

Orjinalini görmek için tıklayınız: Record Üzerindeki Verilere Dinamik Erişim
Şu anda (Arşiv) modunu görüntülemektesiniz. Orjinal Sürümü Görüntüle internal link
Merhaba,

Projem gereği her yerde kullanabileceğim bir record yapısı kuruyorum. Bu nedenle recordlar üzerinde dinamik işlemler yapmam gerekiyor. 
Başkalarınında işine yarayacağını düşünerek http://www.delphican.com/showthread.php?tid=1433 konusuna ithafen, record üzerindeki verilere erişim ve value gönderme üzerine örnek kod ve proje aşağıdadır.

ADjok7.png

Örnek Proje Kodlar

unit RecordLib;
{****************************
 RecordLib.pas 2019
 S.B
*****************************}
interface

 uses Rtti,TypInfo;

 type
   TFieldInform = record
   FieldName  : String;
   FieldType  : String;
   FieldValue : Variant;
 end;

 type
   TRecordInfo<RecordClass:record> = class
 public
   class function  GetFieldList(const ARecord:RecordClass): TArray<TFieldInform>;
   class procedure SetFieldValue(var ARecord:RecordClass;const AFieldName:String;const AValue:Variant);
 end;

implementation

{ TRecordInfo<RecordClass> }

class function TRecordInfo<RecordClass>.GetFieldList(const ARecord: RecordClass): TArray<TFieldInform>;
var
 xContext : TRttiContext;
 xType    : TRttiType;
 xField   : TRttiField;
 xCounter : Integer;
begin
 xContext := TRttiContext.Create;
 try
   SetLength(Result,Length(xContext.GetType(TypeInfo(RecordClass)).GetFields));
   xCounter := 0;
   for xField in xContext.GetType(TypeInfo(RecordClass)).GetFields do
   begin
     xType                       := xField.FieldType;
     Result[xCounter].FieldName  := xField.Name;
     Result[xCounter].FieldType  := xField.FieldType.Name;
     Result[xCounter].FieldValue := xField.GetValue(@ARecord).AsVariant;
     xCounter                    := Succ(xCounter);
   end;
 finally
   xContext.Free;
 end;
end;

class procedure TRecordInfo<RecordClass>.SetFieldValue(var ARecord:RecordClass;const AFieldName:String;const AValue:Variant);
var
 xContext : TRttiContext;
 xType    : TRttiType;
 xField   : TRttiField;
 xValue   : TValue;
begin
 xContext := TRttiContext.Create;
 try
   for xField in xContext.GetType(TypeInfo(RecordClass)).GetFields do
   begin
     xType := xField.FieldType;
     if xField.Name = AFieldName then
     begin
       case PTypeInfo(xType.Handle).Kind of
         tkInteger :
           begin
             xValue := TValue.From<Integer>(AValue);
             xField.SetValue(@ARecord,xValue);
           end;
         tkUString :
           begin
             xValue := TValue.From<String>(AValue);
             xField.SetValue(@ARecord,xValue);
           end;
         tkFloat :
           begin
             xValue := TValue.From<Double>(AValue);
             xField.SetValue(@ARecord,xValue);
           end;
       end;
     end;
   end;
 finally
   xContext.Free;
 end;
end;

end.

Örnek

  type
   TTestRecord = record
   VAL_STR : String;
   VAL_INT : Integer;
   VAL_DTE : TDateTime;
   VAL_FLT : Double;
 end;

procedure TFrmTestRecord.BtnOKClick(Sender: TObject);
Var
 xTestRecord : TTestRecord;
 xFieldArray : TArray<TFieldInform>;
 Ind         : Integer;
begin
 memDefault.Clear;
 memNew.Clear;

 xTestRecord.VAL_STR := 'Test1';
 xTestRecord.VAL_INT := 1;
 xTestRecord.VAL_DTE := StrToDateTime('01.01.2019 01:10:15');
 xTestRecord.VAL_FLT := 0.1;

 xFieldArray := TRecordInfo<TTestRecord>.GetFieldList(xTestRecord);
 for Ind := Low(xFieldArray) to High(xFieldArray) do
     memDefault.Lines.Add
     (
       Format('FieldName[%s] -- FieldType[%s] -- Value=%s',
       [
         xFieldArray[Ind].FieldName
         ,xFieldArray[Ind].FieldType
         ,VarToStr(xFieldArray[Ind].FieldValue)
       ]
       )
     );

 TRecordInfo<TTestRecord>.SetFieldValue(xTestRecord,'VAL_STR','Test2');
 TRecordInfo<TTestRecord>.SetFieldValue(xTestRecord,'VAL_INT',2);
 TRecordInfo<TTestRecord>.SetFieldValue(xTestRecord,'VAL_DTE',Now);
 TRecordInfo<TTestRecord>.SetFieldValue(xTestRecord,'VAL_FLT',0.2);

 xFieldArray := TRecordInfo<TTestRecord>.GetFieldList(xTestRecord);
 for Ind := Low(xFieldArray) to High(xFieldArray) do
     memNew.Lines.Add
     (
       Format('FieldName[%s] -- FieldType[%s] -- Value=%s',
       [
         xFieldArray[Ind].FieldName
         ,xFieldArray[Ind].FieldType
         ,VarToStr(xFieldArray[Ind].FieldValue)
       ]
       )
     );
end;