本人正主持一项目,遇到难题,特向各位专家请教,如果提供正确的解决方法,将略表心意,500元内我都可签字解决。具体如下:delphi6+Access完成一个有关公文流转的项目。在数据表中包括许多已经做好word文档模板,不同用户进去后选择不同模板名,即可显示该word模板,在word文档上填写相关内容后,保存之后,发送给领导签字,最好还要有“痕迹”的功能,及不同用户对文档的修改应有不同的标记。我用Olecontainer来装载access数据表,但是一直出现“invalid stream format”的错误。代码如下:  Table.Open;
  stream:=Tmemorystream.Create;
  try
    TBlobField(Table.FieldByName('Template')).SaveToStream(stream);
    if stream.Size>0 then
      begin
        stream.Position:=0;
        Ole.LoadFromStream(stream);
        Ole.DoVerb(1);
      end;
  Finally
    stream.Free;
  End;
  Ole.Refresh;
如果那位专家做过相关项目,请赐招,如有代码,请发送邮箱 [email protected]。汇款方式由专家指定。

解决方案 »

  1.   

    我试了一下,在Delphi7下原来的存/取流方式不知道为什么不能用了,是不是Delphi7的BuG呀!
      

  2.   

    我做过的项目代码,操作access用ado比较方便。//对表中ole对象字段附值
      adotable1.Edit ;
      tblobfield(adotable1.FieldByName('s6')).loadfromfile('c:\test.txt');//或者是loadfromstream() ;
      adotable1.Post ; 
      
     //取出表中ole对象字段的值 
        adoquery1.SQL.Clear ;
        adoquery1.SQL.Add('select * from  bb');
        adoquery1.Open ;
        tblobfield(adoquery1.FieldByName('s6')).savetofile('c:\test1.txt') ;
        richedit1.Lines.Clear ;
        richedit1.Lines.LoadFromFile('c:\test1.txt') ;
        richedit1.Text :=  tblobfield(adoquery1.FieldByName('s6')).value ;  
     
     //用动态sql语句插入有ole对象字段的记录
        sqlstring := 'insert into bb(s1,s2,s6) values("12","45",:bb)' ;
        adoquery1.SQL.Add(sqlstring) ;
        adoquery1.Parameters.ParamByName('bb').loadfromfile('c:\test1.txt',ftblob) ;
        adoquery1.execsql;
      

  3.   

    我发现一个问题,不同的数据库,使用的方法不同,在paradox下可以通过的,但是在ACCESS下却不行。delphi中帮助里建议使用dataset的CreateBlobStream方法,帮助代码如下:
    The following example copies the data in the Notes field of Table1 to the Res field of ClientDataSet1.procedure TForm1.Button1Click(Sender: TObject);var
      Stream1: TBlobStream;
      Stream2: TStream;
    begin
      Stream1 := TBlobStream.Create(Table1Notes, bmRead);
      try
        ClientDataSet1.Edit;
        { here抯 a different way to create a blob stream } 
        Stream2 := ClientDataSet1.CreateBlobStream(ClientDataSet1.FieldByName('Res'), bmReadWrite);
        try
          Stream2.CopyFrom(Stream1, Stream1.Size);
          ClientDataSet1.Post;
        finally
          Stream2.Free;
        end;  finally
        Stream1.Free;
      end;
    end;
      

  4.   

    用lotus notes就很容易完成这个功能。
      

  5.   

    invalid stream format的错误可能是由于你的OleContainer的OldStreamFormat设置为False的原因,如果改为True后就不会出现这个错误了,但我试了试,结果,:-(  结果又出现另外一个错误:%1己经存在!
      

  6.   

    在Access里边存取文件:

    procedure TForm1.Button3Click(Sender: TObject);
    var
      sFileName:string;
      function BlobContentToString(const filename:string):string;
      begin
        with TFileStream.Create(FileName,fmOpenRead) do
        try
          SetLength(Result,Size);
          Read(Pointer(Result)^,Size);
        finally
          Free;
        end;
      end;
    begin
       if(OpenDialog1.Execute)then
       begin
          sFileName:=OPenDialog1.FileName;
          ADODataSet1.Edit;
          ADODataSet1.FieldByName('Blobs').AsString:=BlobContentToString(sFilename);
          ADODataSet1.Post;
          ADODataSet1.Close;
          ADODataSet1.Open;
       end;
    end;读:
    procedure TForm1.Button4Click(Sender: TObject);
    var
      sFileName:string;
      Bs:TADOBlobStream;
    begin
      Bs:=TADOBlobStream.Create(TBlobField(adodataset1.FieldByName('Blobs')),bmread);
      try
        sFileName:=ExtractFilePath(Application.ExeName)+'tmpBlob';
        sFileName:=sFileName+'.'+ADODataSEt1.fieldbyname('extension').AsString;
        Bs.SaveToFile(sFileName);
        OleContainer1.CreateObjectFromFile(sFileName,False);
      finally
        Bs.Free;
      end;
    end;楼主说话算话啊,公布源码,估计俺这边也要做个相类似的工程吧
      

  7.   

    楼上这位兄弟谢谢你的支持。但是我很遗憾的告诉你,经过专家的指点,我刚刚才知道我的实现方向是错误,在delphi中操作word文档有三种方式,我采用第一种即通过oletainer这种方式来读取word根本是错误的,属于原则错误,这种方法无法控制word的属性。需要使用CreateOleObject等方法来实现并控制。
     我正在研究,有结果一定告诉你。
      

  8.   

    公文流转一般是用B/S的电子文档,最后生成相应的DOC文档。
      

  9.   

    oletainer这种方式来读取word根本是错误的,这是不正确的,是DELPHI对Oletainer支持的不好,自己要改这个控件,才能对word的属性进行控制,不只你的控制那一层次,深层次,可能工作量也比较大,真的还不如用CreateOldObject来的方便,但是你的控制签名,因为没有做过
      

  10.   

    回答楼上:如果使用Oletainer,可以在一个界面里面编辑word内容,如果使用CreateOldObject,关键问题是要重新打开word窗口,而这是最致命的。