求ClientDataSet存为二进制格式文件的文件格式。如何自己写代码生成相同的格式(不使用SaveToFile等)。

解决方案 »

  1.   

    很遗憾
    这个  
      SaveToStream
      SaveToFile
    都不是虚函数。
      

  2.   

    原来写的一个,不整理了,VariantIn是自己打的一个包,也可不打包,直接把这几个TTable按你自己定义的格式存在文本去,到时再解析出来就好了,(要做些修改)Function varPack(var VariantPack: Variant;MasterInfo:RJbDjMainTableInfo;PriMemData:TdxMemData;strTalbeName:String):Integer;overload;
    var
      pMasterFlds:array of string;
      pMasterTypes:array of string;
      pMasterValues:array of variant;
      i:Integer;
    begin
      VariantPack:=VarArrayCreate([0,3],varVariant);
      setlength(pMasterFlds,Length(MasterInfo));
      setlength(pMasterTypes,Length(MasterInfo));
      setlength(pMasterValues,Length(MasterInfo));
      for i:=low(MasterInfo) to high(MasterInfo) do
      begin
        pMasterFlds[i]:=MasterInfo[i].strFldName;
        pMasterTypes[i]:=MasterInfo[i].strFldType;
        pMasterValues[i]:=PriMemData.FieldByName(MasterInfo[i].strFldName).Value;
      end;
      VariantPack[0]:=strTalbeName;
      VariantPack[1]:=pMasterFlds;
      VariantPack[2]:=pMasterTypes;
      VariantPack[3]:=pMasterValues;
    end;Function varPack(var VariantPack: Variant;DetailInfo:RJbDjMxTableInfo;PriMemData:TdxMemData;MainMemData:TdxMemData;strTalbeName:String;strPkFld:String;strPkValue:String):Integer;overload;
    var
      pDetailFlds:array of string;
      pDetailTypes:array of string;
      pDetailValues:array of variant;
      pDetailValue:array of variant;
      i,j,k:integer;
    begin
      //明细数据
      k:=0;
      for j:=low(DetailInfo) to high(DetailInfo) do
      begin
        if DetailInfo[j].intFldKind<>0 then
          Continue;
        Inc(k);
      end;
      VariantPack:=VarArrayCreate([0,3],varVariant);
      setlength(pDetailFlds,k);
      setlength(pDetailTypes,k);
      k:=0;
      for j:=low(DetailInfo) to high(DetailInfo) do
      begin
        if DetailInfo[j].intFldKind<>0 then
          Continue;
        pDetailFlds[k]:=DetailInfo[j].strFldName;
        pDetailTypes[k]:=DetailInfo[j].strFldType;
        Inc(k);
      end;
      pDetailValues:=nil;
      PriMemData.First;
      setlength(pDetailValues,PriMemData.RecordCount);
      for i:=0 to PriMemData.RecordCount-1 do
      begin
        setlength(pDetailValue,Length(pDetailFlds));
        for j:=low(pDetailFlds) to high(pDetailFlds) do
        begin
          pDetailValue[j]:=PriMemData.FieldByName(pDetailFlds[j]).Value;
          if pDetailFlds[j]=strPkFld then
            pDetailValue[j]:=MainMemData.FieldByName(strPkFld).AsString;
        end;
        pDetailValues[i]:=pDetailValue;
        PriMemData.Next;
      end;
      VariantPack[0]:=strTalbeName;
      VariantPack[1]:=pDetailFlds;
      VariantPack[2]:=pDetailTypes;
      VariantPack[3]:=pDetailValues;
    end;Function SaveDataPack(const VariantIn:Variant;const Filter:String):Integer;
    var
      FileName:String;
      F:TextFile;
      i,j,k:Integer;
      MasterArr,FieldNameArr,FieldTypeArr,FieldValueArr,FieldValueDetailArr:Array of variant;
      FieldNameStr,FieldTypeStr,FieldValueStr:String;
      SaveDialogDataPack:TSaveDialog;
      DetailRecordCount:Integer;
      CurFilter:String;
      procedure SavePack(FileLabel:String;VariantRec:Variant);
      var
        j,k:Integer;
      begin
        FieldNameStr:='';
        FieldNameArr:=nil;
        FieldNameArr:=VariantRec[1];
        FieldTypeStr:='';
        FieldTypeArr:=nil;
        FieldTypeArr:=VariantRec[2];
        FieldValueArr:=nil;
        FieldValueArr:=VariantRec[3];
        if VarType(FieldValueArr[0])<>varEmpty then
          DetailRecordCount:=Length(FieldValueArr)
        else
          DetailRecordCount:=0;
        Writeln(F,FileLabel+SPLIT);
        Writeln(F,VarToStr(VariantRec[0])+SPLIT+IntToStr(Length(FieldNameArr))+SPLIT+IntToStr(DetailRecordCount)+SPLIT);
        for j:=low(FieldNameArr) to High(FieldNameArr) do
        begin
          FieldNameStr:=FieldNameStr+VarToStr(FieldNameArr[j])+SPLIT;
          FieldTypeStr:=FieldTypeStr+VarToStr(FieldTypeArr[j])+SPLIT;
        end;
        Writeln(F,FieldNameStr);
        Writeln(F,FieldTypeStr);
        if VarType(FieldValueArr[0])=varEmpty then
          Exit;
        for j:=low(FieldValueArr) to high(FieldValueArr) do
        begin
          FieldValueStr:='';
          FieldValueDetailArr:=nil;
          FieldValueDetailArr:=FieldValueArr[j];
          for k:=low(FieldValueDetailArr) to high(FieldValueDetailArr) do
          begin
            FieldValueStr:=FieldValueStr+VarToStr(FieldValueDetailArr[k])+SPLIT;
          end;
          Writeln(F,FieldValueStr);
        end;
      end;
    begin
      Result:=0;
      SaveDialogDataPack:=TSaveDialog.Create(nil);
      CurFilter:='*.'+Filter+'|*.'+Filter;
      SaveDialogDataPack.Filter:=CurFilter;
      SaveDialogDataPack.FileName:=VariantIn[0][1]+'.'+Filter;
      if (SaveDialogDataPack.Execute) and (Trim(SaveDialogDataPack.FileName)<>'') then
      begin
        FileName:=SaveDialogDataPack.FileName;
        if Pos(Filter,FileName)=0 then
          FileName:=FileName+'.'+Filter;
      end
      else begin
        SaveDialogDataPack.Free;
        Result:=0;
        Exit;
      end;
      try
        AssignFile(F,FileName);
        Rewrite(F);
        Writeln(F,'单据编号'+SPLIT);
        Writeln(F,VarToStr(VariantIn[0][0])+SPLIT+VarToStr(VariantIn[0][1])+SPLIT);
        Writeln(F,'主表数据'+SPLIT);
        MasterArr:=VariantIn[1];
        FieldNameStr:='';
        FieldNameArr:=nil;
        FieldNameArr:=MasterArr[1];
        FieldTypeStr:='';
        FieldTypeArr:=nil;
        FieldTypeArr:=MasterArr[2];
        FieldValueStr:='';
        FieldValueArr:=nil;
        FieldValueArr:=MasterArr[3];
        Writeln(F,VarToStr(MasterArr[0])+SPLIT+IntToStr(Length(FieldNameArr))+SPLIT);
        for i:=low(FieldNameArr) to high(FieldNameArr) do
        begin
          FieldNameStr:=FieldNameStr+VarToStr(FieldNameArr[i])+SPLIT;
          FieldTypeStr:=FieldTypeStr+VarToStr(FieldTypeArr[i])+SPLIT;
          FieldValueStr:=FieldValueStr+VarToStr(FieldValueArr[i])+SPLIT;
        end;
        Writeln(F,FieldNameStr);
        Writeln(F,FieldTypeStr);
        Writeln(F,FieldValueStr);    Writeln(F,'明细数据'+SPLIT);
        Writeln(F,VarToStr(VariantIn[2])+SPLIT);
        MasterArr:=nil;
        MasterArr:=VariantIn;
        for i:=0 to VariantIn[2]-1 do
          SavePack('明细数据'+IntToStr(i),VariantIn[3+i]);
        {if VariantIn[2]>1 then
          SavePack('配码数据',VariantIn[2+VariantIn[2]-1]);
        if VariantIn[2]>2 then
          SavePack('装箱数据',VariantIn[2+VariantIn[2]]); }
      except
        Result:=-1;
        ShowMessage('另存异常!');
      end;
      CloseFile(F);
      SaveDialogDataPack.Free;
    end;
      

  3.   

    是要写成和ClientDataSet生成的文件一样的格式,不是自已定义格式。
    经过一晚上地研究,终于搞清楚了它的格式。
    感谢 leejiey(李杰) 贴了这么多代码,需要自定义格式时值得学习。