ACCESS to XML 使用了ADoquery.SavetoXML() 自身自带函数这个速度很快,几秒钟。
XML to ACCESS 这个不ADO没有提供有函数,各位大夹帮助一下,如何解决?目前我是用 while 一条一条的从XML取出来,再一条一条的再保存到access 表里面,速度慢得受不了。想再寻找更高明的算法。BDE 有一个BatchMove ,速度也顶快的,不知道它里面怎么处理?只可惜它不支持ADO。有力出力,没力也帮UP一下或者GZ一下也可以,多谢。帮帮我

解决方案 »

  1.   

    我看不少朋友都是连接了excel以后一行一行往excel里面倒入,这样非常没有效率,我一般使用ExcelTableQuery控件,批量倒入,只要设定好了倒入的格式,倒入速度可以提高几十倍.我在使用delphi倒出excel方面使用的是TQueryTable控件,这个控件的作用相当于excel里面的"数据"---->"获取外部数据"---->"倒入文本文件",这种倒入方式主要思路是先把要保存的数据写到一个文本文件里面,然后使用TQueryTable将文本文件倒入到excel里面,这种方式倒入的速度是一条一条倒入的几十倍,效率非常快.
    具体的实现是:
    (一)把DataSet中的数据写入一个文本
    function TComm.ReadyFile(Fn: string; Ds: TDataSet): Boolean;
    var i,rowcount:integer;
        line:string;
    begin
      Result:=False;
      if not Ds.Active then exit;
      rowcount:=Ds.FieldCount;
      AssignFile(F,Fn);
      try
        try
          ReWrite(F);
          line:=Ds.Fields[0].DisplayName;
          for i:=1 to rowcount-1 do line:=line+''+Ds.Fields[i].DisplayName;//先准备好标题
          Writeln(F,line);
          Ds.First;//下面是一条一条的写入数据到文本文件,每行一条记录,每字段之间使用Tab间隔
          while not Ds.Eof do
          begin
            line:=Ds.Fields[0].AsString;
            for i:=1 to rowcount-1 do line:=line+''+Ds.Fields[i].AsString;//注意,这里的''是Tab键
            Writeln(F,line);
            Ds.Next;
          end;
          Result:=True;
        except
          Result:=False;
          exit;
        end;
      finally
        CloseFile(F);
      end;
    end;
    (二)还要准备一个OleVariant参数,这个参数是一个整数变量,这个参数的目的是为了在倒入excel的时候正确区分列是文本还是数字,如果不准备这个参数,例如0000111这样的文本导入后就会成为111这样的数字.
    function TComm.InitFormatA(DataSet: TDataSet): OleVariant;
    var i:integer;
        A:Variant;
    begin
      A:=VarArrayCreate([0,DataSet.Fields.Count-1],varVariant);
      for i:=0 to DataSet.FieldCount-1 do
        if DataSet.Fields[i].DataType=ftStringthen A[i]:=2 else A[i]:=1;//如果是文本,元素就是2,否则就是1
      InitFormatA:=A;
    end;
    (三)文本准备好了,格式参数也准备好了,就可以连接excel使用ExcelQueryTable控件导入数据了.ReadyFile('c:\tmp',Query1);//把Query1里面的数据导入到c:\tmp2这个文本文件里面
    Text2Excel_Format:=InitFormatA(Query1);//通过分析Query1获得导入excel的格式参数
    try
      ExcelApplication1.Connect;
      ExcelApplication1.Visible[0]:=True;
      ExcelApplication1.Workbooks.Add(NULL,0);
      ExcelWorkbook1.ConnectTo(ExcelApplication1.Workbooks[ExcelApplication1.Workbooks.Count]);
      ExcelWorksheet1.ConnectTo(ExcelWorkbook1.Sheets[1] as _WorkSheet);
      //开始连接EXCELQueryTables
      ExcelWorkSheet1.QueryTables.Add('TEXT;'+'C:\tmp',ExcelWorkSheet1.Range['A1','A1'],EmptyParam);//设置Excel需要导入的数据是c:\tmp的文本
      ExcelQueryTable1.ConnectTo(ExcelWorkSheet1.QueryTables[1] as _QueryTable);
      ExcelQueryTable1.TextFileColumnDataTypes:=Text2Excel_Format;//设置导入格式
      ExcelQueryTable1.Refresh;//刷新以后就获得数据了.
    finally
        ExcelQueryTable1.Disconnect;
      ExcelWorkSheet1.Disconnect;
      ExcelWorkBook1.Disconnect;
      ExcelApplication1.Disconnect;
    end;
    这种导入数据的方式绝对很快,可是是一般导入方式的几十甚至上百倍.
      

  2.   

    同志...这...这...与我的没多少相关呀.ACCESS数据库可是要POST一次的。while 一次就post一次相当消耗时间。
    要的是Access 的例子.我顶
      

  3.   

    procedure TForm1.Button2Click(Sender: TObject);
    begin
        ClientDataSet1.Close;
        ClientDataSet1.ProviderName:='XMLTransformProvider1';
        XMLTransformProvider1.CacheData := False;
        XMLTransformProvider1.TransformRead.TransformationFile:=ExtractFilePath(Application.ExeName)+'toDp.xtr';
        XMLTransformProvider1.TransformWrite.TransformationFile:=ExtractFilePath(Application.ExeName)+'toXML.xtr';
        XMLTransformProvider1.XMLDataFile:=ExtractFilePath(Application.ExeName)+'ogrenci.xml';
        ClientDataSet1.FileName:=ExtractFilePath(Application.ExeName)+'ogrenci.xml';
        ClientDataSet1.Open;
    end;
      

  4.   

    hongqi162(失踪的月亮)
    我没用CliengDataset ,我用Adoquery.
    TransformRead.TransformationFile (是不是相当于adoquery.loadfile())
    TransformWrite.TransformationFile (是不是相当于adoquery.savetofiel())
    这个只是把数据装载到数据集里而已,并不能把它弄到access 表里面!
    对吧?
      

  5.   

    data access组件页里的XMLTransformProvider,看到控件的命名就知道他是干什么的了,有时间可以研究一下,呵呵呵
      

  6.   

    我想问下各位:BDE 中那个 TBatchMove 什么原理?它怎么能一次性把数据保存到表里面? 它是不是在内存中一次性搞好。我用 while adotest.fieldbyname() := xxx ado .next end 这种好慢。