我们有一个遗留数据集,其中一个字段(最后一个)用于保存打包记录。
我们现在需要访问这些数据,我认为将其读回到打包记录中会非常简单 - 但不是那么简单。看来我要出局了
设计/编写代码的人早已离去,所以我留下了我能发现的东西。
这是我到目前为止所拥有的 -
写入的打包记录格式为:
TRecordStru = packed record
RecData1 : integer ;
RecData2 : array [0..9] of char ;
RecData3 : array [0..9] of char ;
RecData4 : integer ;
RecData5 : array [0..9] of char ;
RecData6 : integer ;
end;
创建打包记录的代码是:
with myRecord do // TRecordStru
begin
RecData1 := Num1 ; // integer
StrPLCopy(RecData2,StrData2,sizeof(RecData2)) ; // mm/dd/yyyy
StrPLCopy(RecData3,StrData3,sizeof(RecData3)) ;
RecData4 := Num2 ; // integer
StrPLCopy(RecData5,StrData5,sizeof(RecData5)) ;
RecData6 := Num6 ; // integer
end;
为字段创建数据的代码:
...
var
tmpData : string
...
tmpData := spaces(sizeof(myRecord)); // TRecordStru
move(myRecord,tmpData[1],sizeof(myRecord));
...
以及将数据保存到字段的代码:
...FieldByName('myField').AsString := VarToStr(Value)+#0 ; // variant
为了读回它,我尝试了以下方法:
DataType
报告的FieldByName('myField').DataType
是ftBytes
。
我可以使用以下方法将数据放入缓冲区:
FieldByName('myField').GetData(myBuffer)
myBuffer
定义为:
myBuffer : array of byte;
并像这样初始化:
getmem(myBuffer,260) ;
我可以看到数据在那里,并且可以手动解析,但是有“正确”的方法吗?
我会用这样的东西。也许需要额外的检查。
type
PRecordStru = ^TRecordStru;
// ...
function RecToVar(const pSource: PRecordStru): Variant;
var
pValue: PByte absolute pSource;
i: Integer;
begin
Result := Null;
if ( nil = pSource ) then exit;
try
Result := VarArrayCreate([0, SizeOf(TRecordStru) - 1], varByte);
except
exit;
end;
for i := 0 to SizeOf(TRecordStru) - 1 do
begin
Result[i] := pValue[i];
end;
end;
function VarToRec(const vSource: Variant; const pTarget: PRecordStru): Boolean;
var
pValue: PByte absolute pTarget;
i: Integer;
begin
Result := ( pTarget <> nil )
and VarIsArray(vSource)
and ( 1 = VarArrayDimCount(vSource) )
and ( SizeOf(TRecordStru) - 1 = VarArrayHighBound(vSource, 1) );
if ( not Result ) then exit;
for i := 0 to SizeOf(TRecordStru) - 1 do
begin
pValue[i] := vSource[i];
end;
end;
procedure TForm1.Button2Click(Sender: TObject);
var
r: TRecordStru;
begin
r.RecData1 := 1;
r.RecData2 := '2222222222';
r.RecData3 := '3333333333';
r.RecData4 := 4;
r.RecData5 := '5555555555';
r.RecData6 := 6;
MyDataSet.Append();
// ...
MyDataSet.FieldValues['myField'] := RecToVar(@r);
MyDataSet.Post();
end;
procedure TForm1.Button3Click(Sender: TObject);
var
r: TRecordStru;
begin
if ( VarToRec(MyDataSet.FieldValues['myField'], @r) ) then
begin
// ...
end;
end;