请问为什么使用delphi7的servers控件操作word时消耗时间不是与操作量 |
尚未結案
|
logv
一般會員 發表:5 回覆:22 積分:10 註冊:2004-03-16 發送簡訊給我 |
|
malanlk
尊榮會員 發表:20 回覆:694 積分:577 註冊:2004-04-19 發送簡訊給我 |
|
logv
一般會員 發表:5 回覆:22 積分:10 註冊:2004-03-16 發送簡訊給我 |
任何操作,比如连续获取1000个字的大小。
先记录初始时间d0,
然后在获取到第250个的时候记录一下当前时间d1,
在获取到第500个的时候记录一下当前时间d2,
在获取到第750个的时候记录一下当前时间d3,
在获取到第1000个的时候记录一下当前时间d4,
设消耗时间d1-d0=n,
那么就会发现d2-d0=4n而不是2n
d3-d0=8n而不是3n
d4-d0=16n而不是4n。
不仅用delphi的控件如此,我用CreateOleObject('word.Application')调用word也是如此,只是速度稍微快一点点。
|
malanlk
尊榮會員 發表:20 回覆:694 積分:577 註冊:2004-04-19 發送簡訊給我 |
照你的說法 同樣獲取 1000 個字
先紀錄初始時間 d0
然後在獲取第 200 個的時候 紀錄一下當前時間 d1,
在獲取第 400 個的時候 紀錄一下當前時間 d2,
在獲取第 600 個的時候 紀錄一下當前時間 d3,
在獲取第 800 個的時候 紀錄一下當前時間 d4,
在獲取第 1000 個的時候 紀錄一下當前時間 d5, 設消耗時間d1-d0=n
d2-d0=4n
d3-d0=8n
d4-d0=16n
d5-d0=32n 我這樣推論對嗎?
若分為 10 次測量, 設 d1-d0=m 那 d10-d0=2^10m=1024m 哦.... 這是不是表示你獲取每個字時, 程式都要從第1個開始算. 我的意思是
取第k個字時, 是要花移動 k 個字的時間, 所以 取 n 個字要花 n*(n 1)/2次移動, 就算是這樣 上面的 d5-d0 也只有不到 25n 還不至於到 32n. 所以你的推論是對的嗎, 有範例程式可以佐證嗎? 也許我沒說清楚, "給個簡單的範例" 就是給ㄧ段簡單的程式碼會造成你所說的狀況出現, 像我看到你的問題時, 我就要花時間去弄ㄧ個範例出來檢查是不是有你所說的情況, 不然就等我有空才能慢慢試試看; 如果你能給ㄧ個.pas檔案 的內容, 大家ㄧ定很樂意馬上抓下來測, 給別人方便就是方便自己. 您覺得我說的有理嗎?
|
logv
一般會員 發表:5 回覆:22 積分:10 註冊:2004-03-16 發送簡訊給我 |
下面是我写的一个测试程序的pas文件,测试一个4000字的文档结果为(秒):
d1-d0=27.21 (前1000个操作的时间)
d2-d0=87.92 (前2000个操作的时间)
d3-d0=182.27 (前3000个操作的时间)
d4-d0=308.49 (前4000个操作的时间)
使用的delphi7+word2003,虽然不是严格象我前面提的那样成倍数增长,也基本显示了这种趋势了。
unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, Word2000, OleServer, ComCtrls; type TForm1 = class(TForm) wa1: TWordApplication; wd1: TWordDocument; Button1: TButton; Button2: TButton; Memo1: TMemo; Button3: TButton; pb1: TProgressBar; procedure Button1Click(Sender: TObject); procedure Button3Click(Sender: TObject); procedure Button2Click(Sender: TObject); function connecttoword:boolean; private { Private declarations } public { Public declarations } end; var Form1: TForm1; implementation {$R *.dfm} function Tform1.connecttoword:boolean; var fn:OleVariant; begin result:=false; try wa1.connect; except memo1.Lines.Add('Word连接失败,请确定Word2000或Word2003是否已经正确安装!'); exit; end; if wa1.Documents.Count=0 then begin memo1.Lines.Add('没有打开文件!'); exit; end; wd1.ConnectTo(wa1.ActiveDocument); memo1.Lines.Add('已连接到文档:' wd1.Name); result:=true; end; procedure TForm1.Button1Click(Sender: TObject); begin connecttoword; if wd1.Characters.Count<4000 then memo1.Lines.Add('文章长度不够,请选择更长的文件测试'); end; procedure TForm1.Button3Click(Sender: TObject); begin wd1.Disconnect; wa1.Disconnect; end; procedure TForm1.Button2Click(Sender: TObject); var i,i1,i2,i3,i4:integer; size:single; d0,d1,d2,d3,d4:Tdatetime; begin d0:=now; pb1.Min:=0; pb1.Position:=0; pb1.Max:=4000; for i:=1 to 4000 do begin case i of 1000:d1:=now; 2000:d2:=now; 3000:d3:=now; 4000:d4:=now; else end; size:=wd1.Characters.item(i).Font.Size; pb1.Position:=i; end; memo1.Lines.Add(format('d1-d0=%f',[(d1-d0)*24*3600])); memo1.Lines.Add(format('d2-d0=%f',[(d2-d0)*24*3600])); memo1.Lines.Add(format('d3-d0=%f',[(d3-d0)*24*3600])); memo1.Lines.Add(format('d4-d0=%f',[(d4-d0)*24*3600])); end; end.發表人 - logv 於 2005/08/01 21:39:08 |
malanlk
尊榮會員 發表:20 回覆:694 積分:577 註冊:2004-04-19 發送簡訊給我 |
|
logv
一般會員 發表:5 回覆:22 積分:10 註冊:2004-03-16 發送簡訊給我 |
|
malanlk
尊榮會員 發表:20 回覆:694 積分:577 註冊:2004-04-19 發送簡訊給我 |
參考這ㄧ篇
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dv_wrcore/html/wrtskhowtoretrievestartendcharactersinranges.asp
procedure TForm1.Button1Click(Sender: TObject); var rgn: Range; i,iStart,iEnd,iCount: Integer; begin iCount := WordDocument1.Characters.Count; iStart:=1; iEnd := Min(iStart 100,iCount); rgn := WordDocument1.Range(iStart,iEnd); while (iStart |
malanlk
尊榮會員 發表:20 回覆:694 積分:577 註冊:2004-04-19 發送簡訊給我 |
引言: 參考這ㄧ篇 http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dv_wrcore/html/wrtskhowtoretrievestartendcharactersinranges.aspprocedure TForm1.Button1Click(Sender: TObject); var rgn: Range; i,iStart,iEnd,iCount: Integer; begin iCount := WordDocument1.Characters.Count; iStart:=1; iEnd := Min(iStart 100,iCount); rgn := WordDocument1.Range(iStart,iEnd); while (iStart |
logv
一般會員 發表:5 回覆:22 積分:10 註冊:2004-03-16 發送簡訊給我 |
|
logv
一般會員 發表:5 回覆:22 積分:10 註冊:2004-03-16 發送簡訊給我 |
引言:我将你的代码修改如下后通过,而且速度均衡。引言: 參考這ㄧ篇 http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dv_wrcore/html/wrtskhowtoretrievestartendcharactersinranges.aspprocedure TForm1.Button1Click(Sender: TObject); var rgn: Range; i,iStart,iEnd,iCount: Integer; begin iCount := WordDocument1.Characters.Count; iStart:=1; iEnd := Min(iStart 100,iCount); rgn := WordDocument1.Range(iStart,iEnd); while (iStart var rgn: Range; iStart,iEnd,iCount: olevariant; size:single; i:integer; d0,d1:Tdatetime; s:string; begin iCount := Wd1.Characters.Count; iStart:=0; iEnd := Min(iStart 100,iCount); rgn := Wd1.Range(iStart,iEnd); while (iStart |
malanlk
尊榮會員 發表:20 回覆:694 積分:577 註冊:2004-04-19 發送簡訊給我 |
Sorry, 只有看你的程式, 並未實際去 Compile, 因為在趕 Project 抽空回答問題, 所以才會出現這段錯誤碼, 基本上 傳給 OleServer 多數是要求傳址(也就是 func(var a:OleVariant; var b:OleVariant; var ....); 的格式,
所以
Wd1.Range(iStart,iEnd) 過關了, 因為 Delphi 會自動轉為 OleVariant 再傳.
而
rgn.Next(wdCharacter,iEnd-iStart 1); ㄧ個是常數, ㄧ個是計算式都不會過關....而且就如錯誤訊息所言
Types of actual and formal var parameters must be identical 讓程式表達更清晰的小撇步....
加 [red]..........[/red]在字句的前後, 字句就會變紅色
加 [green]..[/green]在字句的前後, 字句就會變綠色... rgn.Next(wdCharacter,iEnd-iStart 1); //這裡編譯錯誤 這樣表達更醒目
|
logv
一般會員 發表:5 回覆:22 積分:10 註冊:2004-03-16 發送簡訊給我 |
经过调试,以下代码通过测试,谢谢!
现将修改后的代码帖在下面,修改的地方用红色标明
var rgn: Range; iStart,iEnd,iCount,iv,iw: olevariant; size:single; i:integer; d0,d1:Tdatetime; begin iCount := Wd1.Characters.Count; iStart:=0; iEnd := Min(iStart 100,iCount); rgn := Wd1.Range(iStart,iEnd); while (iStart |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |