两个问题,请各位大侠指教!本周就得交差 :-( 1.如何用ADOBlobStream的stream方式读写blob字段?(50分) 2.如何象Acc

  • 主题发起人 主题发起人 yangkee
  • 开始时间 开始时间
Y

yangkee

Unregistered / Unconfirmed
GUEST, unregistred user!
两个问题,请各位大侠指教!本周就得交差 :-( 1.如何用ADOBlobStream的stream方式读写blob字段?(50分) 2.如何象Access中一样操作表中的blob段(150分)(200分)<br />请教各位,如何用ADOBlobStream的stream方式读写blob字段?李维的书上是用的临时文件
的方法,但我觉得用stream的方式效率应当更好。
我的程序如下
var
bs :TADOBlobStream;
begin
bs:=TADOBlobStream.Create(TBlobField(adotable1.fieldbyname('visio'));
try
OleContainer1.LoadFromStream(bs);//&lt;---显示‘invalid stream format'
finally
bs.free;
end;
end;

另外再请教各位大侠,如何象Access中一样操作表中的blob字段:

Access中的表中含有blob字段时,可将该blob对象打开(即打开关联的程序)。如果字段包含
的是office文档(word,excel,powerpoint,visio)的话,打开的文档名称就是"文档在 XXX: 表"
,XXX是表的名称,否则文档名就是“PkgXXX”,XXX是个随机数。且office程序的“文件”菜单也相应变化:
原来的“关闭”变成了“关闭并返回 XXX: 表”,“保存”变成了“更新”。你对对象做
的修改在关闭对象关联的程序后会保存到access表中(但不是都会保存,我用visio5就不能
保存,visio2000才行)。
在delphi中如何实现?
 
Create方法中是否还有读写属性呢?!
 
打漏了,应该是
bs:=TADOBlobStream.Create(TBlobField(adotable1.fieldbyname('visio'),bmRead);
执行完这一句后我查看bs.size好像是正确的,但到了OleContainer1.LoadFromStream(bs)
就出现异常,显示‘invalid stream format'
另外请各位大侠拉一下问题 2 :如何象Access中一样操作表中的blob字段?
分不成问题,我还有4000分
 
我想可能是OleContainer1.LoadFromStream(bs)不知道bs中内容的格式?
各位大侠拉一拉!
 
听课,我也有几个问题待答中。我一见blob就头痛。
 
ole 的格式不是纯blob格式,当你用access为mdb数据库的blob字段插入一个ole对象时,
已经不仅仅是原来那个文件消息了,前后已经加上了格式控制信息。
另外不知道你的mdb数据库中的blob字段的内容是通过程序加入的,还是用access加入的
如果是用程序加入的,一般没问题,如果是用access加入的,加入的信息已经被改变为
ole类型的了。
还有一点很重要:每当使用流之前,一定要把流的position置为零,bs.position:=0;
 
to wangxd:
谢谢,终于有人回答我的问题了。
正如你所说,mdb中的ole字段并不是原来的文件了,我还用delphi的stream试了一下,
要这样才行:先OleContainer1.createobjectfromfile('foo.vsd'),然后用
var ms:tmemorystream;
begin
ms:= tmemorystream.create;
olecontainer1.SaveToStream(ms);
if adotable1.state&lt;&gt;dsedit then
adotable1.edit;
tblobfield(adotable1.fieldbyname('visio')).loadfromstream(ms);
adotable1.post;
ms.free;
end;
把它以stream的格式存到表中,以后就可以用
var
bs :TADOBlobStream;
begin
bs:=TADOBlobStream.Create(TBlobField(adotable1.fieldbyname('visio'));
try
OleContainer1.LoadFromStream(bs);
finally
bs.free;
end;
end;
用stream方式直接把它读出来了。这样的好处是速度极快,比李维的书上是用的临时文件的
方法快了几十倍,但必须先进行格式转换。这可以从字段的大小上看出来:原文件大小是
470K,用olecontainer1.SaveToStream(ms)转换后大小是1286K,而在access中存为ole字段
大小是2094K。
我想问的是:用转换后的格式保存有问题吗?如何在delphi中读取access中ole字段的内容?
还有,我的问题2可以用olecontainer来解决,但我如何知道office程序已关闭返回,编辑已完成?
用olecontainer打开的文档名称就是"文档在 olecontainer1",如何象access一样直接编辑
ole字段而不通过olecontainer,当office程序关闭返回后就自动将结果保存到ole字段中?
请大家再讨论一下,分是一定会给的。

 
看看以前的答案啊
 
你看一下我的第八条问题,看是否有帮助!
 
现在的问题是,我的olecontainer的AllowInPlace设为false;也就是编辑ole对象时会打开
单独的窗口,如编辑olecontainer中的word文档对象会运行word,但我如何知道程序已经从
word返回,或是在word中按了“保存”或是“关闭并返回”菜单项?
《delphi5开发人员指南》第23章 com和ActiveX讲了自动化事件(p746),但它讲的是如何
如何编写自动化服务器程序和客户端程序配合实现对事件响应,对于自动化服务器程序已固定
(如word,excel)的情况该如何实现对其事件的响应?
 
to delphifaq:
'0' 是什么意思?我看到你在别的地方也 0
 
如果你只是想从你自己的程序中保存和读取blob字段的数据,你的做法我认为
是完全可以的,我想补充的一点是你可以省掉ms(TMemoryStream)这个中间步骤,
速度还可以更快
var bs:TADOBlobStream;
begin
if adotable1.state&lt;&gt;dsedit then begin
adotable1.edit;
OleContainer1.createobjectfromfile('foo.vsd');
bs:=TADOBlobStream.Create(TBlobField(adotable1.fieldbyname('visio'),bmWrite);
try
olecontainer1.SaveToStream(bs);
finally
bs.Free;
adotable1.post;
end;
end;
 
to dxqsoft:
谢谢,我试了一下,速度是要快一些。只是想不通为什么先bs.Free然后才adotable1.post;
另外打开olecontainer中的word文档对象后,如何知道程序已经从word返回,或是在word中按了“保存”或是“关闭并返回”菜单项?
有无类似OnOleWordDocumentUpdate或是OnOleWordDocumentReturn的事件?
 
根据我的观察,bs.Free操作执行的时候,就会自动调用Post方法进行更新记录操作,
因此,所以你在bs.Free操作结束后应该可以省掉Post的,不过我总是觉得不放心,所以
才加上的,但是如果把Post放在bs.Free前面,肯定会出错的,提示DataSet not in
Edit Mode.
关于如何知道程序已经从word返回,我估计你是想在自己的程序中打开一个Blob字段中
的OLE对象并调用关联的程序进行编辑,然后在编辑完成后保存编辑后的结果,并且在
这整个过程中不使用临时文件,我想可以这样试试:
使用一个专门的编辑窗口来放置OleContainer,每次编辑的时候都使用这个窗口,在窗口的
OnKeyDown事件中监视是否用户对OLE对象进行过修改,如果检测到修改,则在关闭这个窗体的
时候将OLE对象流重新写回到Blob字段中进行刷新,这样或许就可以不用知道用户是否在word中
按了“保存”或是“关闭并返回”菜单项,因为我们的目的已经达到了
 
多人接受答案了。
 
后退
顶部