全國最多中醫師線上諮詢網站-台灣中醫網
發文 回覆 瀏覽次數:2898
推到 Plurk!
推到 Facebook!

QuickRep的預覽問題

尚未結案
amemiya
一般會員


發表:1
回覆:11
積分:2
註冊:2003-05-10

發送簡訊給我
#1 引用回覆 回覆 發表時間:2003-05-12 06:51:32 IP:218.172.xxx.xxx 未訂閱
請問各位有遇過嗎?就是將QuickRep.Preview放在thread內執行,執行期間一切正常,但只要系統一關閉的時候,它就會出現:    Project Project1.exe raised exception class EOSError with message'System Error Code 1400.相互驗證失敗。在網域控制站的伺服器密碼已過期。'.Process stopped.Use Step to continue.    而只要不執行QuickRep.Preview就可以正常關閉喔,求救一下..
wnhoo
高階會員


發表:75
回覆:443
積分:198
註冊:2003-04-22

發送簡訊給我
#2 引用回覆 回覆 發表時間:2003-05-12 07:45:05 IP:61.155.xxx.xxx 未訂閱
在QuickRep.Preview執行完毕---关闭得时候,同时释放线程中得相关对象,及线程自身。    供参考!!!    风花雪月 e梦情缘
------
风花雪月 e梦情缘
amemiya
一般會員


發表:1
回覆:11
積分:2
註冊:2003-05-10

發送簡訊給我
#3 引用回覆 回覆 發表時間:2003-05-12 07:59:22 IP:218.172.xxx.xxx 未訂閱
我在Form1.FormClose程序中已有把thread.free加入,可是一樣會有相同的錯誤出現喔..
wnhoo
高階會員


發表:75
回覆:443
積分:198
註冊:2003-04-22

發送簡訊給我
#4 引用回覆 回覆 發表時間:2003-05-12 09:06:45 IP:61.155.xxx.xxx 未訂閱
begin ..... QuickRep.Preview; thread.free; end; 發表人 - wnhoo 於 2003/05/12 09:07:37
------
风花雪月 e梦情缘
amemiya
一般會員


發表:1
回覆:11
積分:2
註冊:2003-05-10

發送簡訊給我
#5 引用回覆 回覆 發表時間:2003-05-12 09:23:46 IP:218.172.xxx.xxx 未訂閱
因為Preview之後還有其他程式碼要執行,而且最後關閉時我也有free..所以free不加在thread的最後,就真的不行嗎?
amemiya
一般會員


發表:1
回覆:11
積分:2
註冊:2003-05-10

發送簡訊給我
#6 引用回覆 回覆 發表時間:2003-05-12 09:45:57 IP:218.172.xxx.xxx 未訂閱
剛剛修改成樓上大大的的建議,問題還是存在。我相信應是QuickRep.Preview這行指令的問題,因為只要拿掉甚至改為執行QuickRep.print系統都可正常關閉,還是說QuickRep.Preview是不能放在thread中執行的?
chih
版主


發表:48
回覆:1186
積分:639
註冊:2002-04-02

發送簡訊給我
#7 引用回覆 回覆 發表時間:2003-05-12 09:53:27 IP:211.74.xxx.xxx 未訂閱
hi...amemiya..加上紅色部分試看看... begin ..... QuickRep.Preview; QuickRep.QRPrinter.Free; QuickRep.QRPrinter := nil; QRTQuery.Close;//QuickRep.DataSet thread.free; end;
amemiya
一般會員


發表:1
回覆:11
積分:2
註冊:2003-05-10

發送簡訊給我
#8 引用回覆 回覆 發表時間:2003-05-12 16:58:44 IP:218.172.xxx.xxx 未訂閱
chih大大你好,我可能要把問題再說詳細一點,我的QuickRep.Preview是放在Thread.Execute程序內的,所以一但我把Thread.Free加在該程序的最後會導致預覽無法關閉,情況變得更糟;至於您所建議的三行程式碼我已試過,在系統關閉也就是Form1.close(Form1是Main Form)依舊會出現上述錯誤...
liorex
初階會員


發表:19
回覆:60
積分:32
註冊:2002-08-20

發送簡訊給我
#9 引用回覆 回覆 發表時間:2003-05-12 20:57:32 IP:211.76.xxx.xxx 未訂閱
amemiya 大大你要不要試試,在thread 的OnTerminate 上Free preview 的物件呢? ---------------------- 一切有為法 如夢幻泡影 如露亦如電 應做如是觀 ----------------------
amemiya
一般會員


發表:1
回覆:11
積分:2
註冊:2003-05-10

發送簡訊給我
#10 引用回覆 回覆 發表時間:2003-05-13 00:12:21 IP:218.172.xxx.xxx 未訂閱
可以請liorex詳細一點說明嗎,謝謝。    這個錯誤真的很‧‧‧,我一步步執行才發現根本攔截不到...    begin   Application.Initialize;   Application.CreateForm(TForm1, Form1);   Application.Run; end.←在這裡執行過後就會出現EOSError
wnhoo
高階會員


發表:75
回覆:443
積分:198
註冊:2003-04-22

發送簡訊給我
#11 引用回覆 回覆 發表時間:2003-05-13 07:47:41 IP:61.155.xxx.xxx 未訂閱
amemiya 兄: 请将你相关部分的源码贴出来,让大家帮你分析。 不然,这样就全凭揣测了!!    风花雪月 e梦情缘
------
风花雪月 e梦情缘
amemiya
一般會員


發表:1
回覆:11
積分:2
註冊:2003-05-10

發送簡訊給我
#12 引用回覆 回覆 發表時間:2003-05-13 13:51:47 IP:218.172.xxx.xxx 未訂閱
程式很簡單 Form1(Unit1)是Main Form 透過Button1呼叫Form2(Unit2),同時執行DBOpen2及ProcessThread(Unit3)兩隻thread。當Form1關閉時就會出現錯誤... {********************************************************************} unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls,unit3; type TForm1 = class(TForm) Button1: TButton; procedure Button1Click(Sender: TObject); private { Private declarations } public { Public declarations } end; var Form1: TForm1; ProcessThread:ProcessTime; implementation uses Unit2; {$R *.dfm} procedure TForm1.Button1Click(Sender: TObject); begin ProcessThread:=ProcessTime.Create(false); Form2:=TForm2.Create(Application); end; end. {********************************************************************} unit Unit2; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs,unit3, ExtCtrls, QuickRpt; type TForm2 = class(TForm) QuickRep1: TQuickRep; procedure FormCreate(Sender: TObject); private { Private declarations } public { Public declarations } end; type DBQuery2 = class(TThread) private { Private declarations } procedure PrintData; protected procedure Execute; override; end; var Form2: TForm2; DBOpen2:DBQuery2; implementation uses unit1,printers; {$R *.dfm} procedure DBQuery2.Execute; begin PrintData; end; procedure DBQuery2.PrintData; begin ProcessThread.Free; Form2.QuickRep1.Preview; end; procedure TForm2.FormCreate(Sender: TObject); begin DBOpen2:=DBQuery2.Create(false); end; end. {********************************************************************} unit Unit3; interface uses Windows,Classes,SysUtils; type ProcessTime = class(TThread) private { Private declarations } procedure Process; protected procedure Execute; override; end; implementation uses unit1; procedure ProcessTime.Execute; begin While not Terminated do begin Synchronize(Process); end; end; procedure ProcessTime.Process; var sleep_interval:integer; begin sleep_interval:=200; Form1.Caption:='處理中'; sleep(sleep_interval); Form1.Caption:='處理中.'; sleep(sleep_interval); Form1.Caption:='處理中..'; sleep(sleep_interval); Form1.Caption:='處理中...'; sleep(sleep_interval); end; end.
wnhoo
高階會員


發表:75
回覆:443
積分:198
註冊:2003-04-22

發送簡訊給我
#13 引用回覆 回覆 發表時間:2003-05-13 15:28:49 IP:61.155.xxx.xxx 未訂閱
//修改如下: {********************************************************************} unit Unit1;    interface    uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls,unit3;    type TForm1 = class(TForm)     Button1: TButton;    procedure Button1Click(Sender: TObject); private { Private declarations } public { Public declarations } end;    var Form1: TForm1; ProcessThread:ProcessTime;    implementation    uses Unit2;    {$R *.dfm} procedure TForm1.Button1Click(Sender: TObject); begin ProcessThread:=ProcessTime.Create(true); ProcessThread.Resume; Form2:=TForm2.Create(Application); Form2.QuickRep1.Preview; ProcessThread.Free; end; end. {********************************************************************} unit Unit2; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs,unit3, ExtCtrls, QuickRpt; type TForm2 = class(TForm) QuickRep1: TQuickRep; private { Private declarations } public { Public declarations } end; var Form2: TForm2; implementation uses unit1,printers; {$R *.dfm} end. {********************************************************************} unit Unit3; interface uses Windows,Classes,SysUtils; type ProcessTime = class(TThread) private { Private declarations } procedure Process; protected procedure Execute; override; end; implementation uses unit1; procedure ProcessTime.Execute; begin While not Terminated do begin Synchronize(Process); end; end; procedure ProcessTime.Process; var sleep_interval:integer; begin sleep_interval:=200; Form1.Caption:='處理中'; sleep(sleep_interval); Form1.Caption:='處理中.'; sleep(sleep_interval); Form1.Caption:='處理中..'; sleep(sleep_interval); Form1.Caption:='處理中...'; sleep(sleep_interval); end; end. 风花雪月 e梦情缘
------
风花雪月 e梦情缘
amemiya
一般會員


發表:1
回覆:11
積分:2
註冊:2003-05-10

發送簡訊給我
#14 引用回覆 回覆 發表時間:2003-05-13 16:05:54 IP:218.172.xxx.xxx 未訂閱
wnhoo兄感謝您的修改建議,不過如此就違反了我的原意了。我原本的意思是希望能將QuickRep1.Preview放在thread中執行(因為有此需要),這支程式是簡化過的,否則全貼出來會很複雜,但錯誤是一樣存在的。    您這樣改就沒有把QuickRep1.Preview拿到thread內執行了,這樣是不會有問題的。    p.s不過我覺得ProcessThread.Free要拿到QuickRep1.Preview之前,不然連關閉    Preview都有點怪怪的...    麻煩各位大大在幫我想想吧....感激不盡
amemiya
一般會員


發表:1
回覆:11
積分:2
註冊:2003-05-10

發送簡訊給我
#15 引用回覆 回覆 發表時間:2003-05-13 16:42:56 IP:218.172.xxx.xxx 未訂閱
我發現問題出在Form2,只要執行過Button1,它就只可以Close,一但要Free就會出現上述錯誤..
amemiya
一般會員


發表:1
回覆:11
積分:2
註冊:2003-05-10

發送簡訊給我
#16 引用回覆 回覆 發表時間:2003-05-13 16:43:14 IP:218.172.xxx.xxx 未訂閱
我發現問題出在Form2,只要執行過Button1,它就只可以Close,一但要Free就會出現上述錯誤..
wnhoo
高階會員


發表:75
回覆:443
積分:198
註冊:2003-04-22

發送簡訊給我
#17 引用回覆 回覆 發表時間:2003-05-14 09:03:51 IP:61.155.xxx.xxx 未訂閱
我也实验了好多次,如果象你这样使用是会出现异常。    风花雪月 e梦情缘
------
风花雪月 e梦情缘
Justmade
版主


發表:94
回覆:1934
積分:2030
註冊:2003-03-12

發送簡訊給我
#18 引用回覆 回覆 發表時間:2003-05-14 13:05:30 IP:218.16.xxx.xxx 未訂閱
第一次認真試玩 Thread 我發覺問題是出自在 class="code"> var i : integer; begin for i := 0 to Application.ComponentCount - 1 do if Application.Components[i].ClassName = 'TQRStandardPreview' then Application.Components[i].Free; end; 另外,我覺得將DBQuery2搬到 Unit1, 從 Form2.Create 便交給 DBQuery2 去做比較好,Preview 後可順手 Free 掉 Form2, Free掉 Preview Form, 最後再 Free 掉自己 (DBQuery2),完全沒殘留任何沒用的東西。而且亦不需使用 DBOpen2 變數(你若在別處要用當然一樣可建立變數); 程序碼如下 :
unit Unit1;
 
interface
 
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls,unit3;
 
type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  end;
 
  DBQuery2 = class(TThread)
  private
    procedure PrintData;
  protected
    procedure Execute; override;
  end;
 
var
  Form1: TForm1;
  ProcessThread:ProcessTime;
 
implementation
 
uses Unit2;
 
{$R *.dfm}
 
procedure DBQuery2.Execute;
begin
  PrintData;
  Free;
end;
 
procedure DBQuery2.PrintData;
var i : integer;
begin
  with TForm2.Create(Application) do
  try
    ProcessThread.Free;
    QuickRep1.Preview;
  finally
    Free;
    for i := 0 to Application.ComponentCount - 1 do
      if Application.Components[i].ClassName = 'TQRStandardPreview' then
        Application.Components[i].Free;
  end;
end;
 
procedure TForm1.Button1Click(Sender: TObject);
begin
  ProcessThread:=ProcessTime.Create(false);
  DBQuery2.Create(false);
end;
 
end.
Unit2 完全沒程式碼, Unit3沒變。 若你的 Report.Preview 會執行很久,而你想預備好整個 report 才 show preview form 亦可在 ProcessThread.Free; 前加入 QuickRep1.Prepare;
wnhoo
高階會員


發表:75
回覆:443
積分:198
註冊:2003-04-22

發送簡訊給我
#19 引用回覆 回覆 發表時間:2003-05-14 14:09:39 IP:61.155.xxx.xxx 未訂閱
终于找到问题所在了 1.正如Justmade兄所说的Preview没有Free掉 2.UNIT2的FORM2没有FREE掉    所以修改如下: {********************************************************************} unit Unit1;    interface    uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls,unit3;    type TForm1 = class(TForm)     Button1: TButton;    procedure Button1Click(Sender: TObject);    private { Private declarations } public { Public declarations } end;    var Form1: TForm1; ProcessThread:ProcessTime;    implementation    uses Unit2;    {$R *.dfm}    procedure TForm1.Button1Click(Sender: TObject); begin ProcessThread:=ProcessTime.Create(false); Form2:=TForm2.Create(Application); end; end.    {********************************************************************} unit Unit2; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs,unit3, ExtCtrls, QuickRpt;    type TForm2 = class(TForm) QuickRep1: TQuickRep; procedure FormCreate(Sender: TObject); private { Private declarations } public { Public declarations } end;    type DBQuery2 = class(TThread) private { Private declarations } procedure PrintData; protected procedure Execute; override; end;    var Form2: TForm2; DBOpen2:DBQuery2;    implementation uses unit1,printers;    {$R *.dfm}    procedure DBQuery2.Execute; begin PrintData; end;    procedure DBQuery2.PrintData; var i:integer;    begin try ProcessThread.Free; Form2.QuickRep1.Preview; finally for i:=Application.ComponentCount-1 downto 0 do if Application.Components[i].ClassName = 'TQRStandardPreview' then Application.Components[i].Free; form2.Free; end; end; procedure TForm2.FormCreate(Sender: TObject); begin DBOpen2:=DBQuery2.Create(false); end; end. {********************************************************************} unit Unit3; interface uses Windows,Classes,SysUtils; type ProcessTime = class(TThread) private { Private declarations } procedure Process; protected procedure Execute; override; end; implementation uses unit1; procedure ProcessTime.Execute; begin While not Terminated do begin Synchronize(Process); end; end; procedure ProcessTime.Process; var sleep_interval:integer; begin sleep_interval:=200; Form1.Caption:='處理中'; sleep(sleep_interval); Form1.Caption:='處理中.'; sleep(sleep_interval); Form1.Caption:='處理中..'; sleep(sleep_interval); Form1.Caption:='處理中...'; sleep(sleep_interval); end; end. //UNIT1,UNIT3没动,UNIT2改变主要再RED部分。 风花雪月 e梦情缘
------
风花雪月 e梦情缘
amemiya
一般會員


發表:1
回覆:11
積分:2
註冊:2003-05-10

發送簡訊給我
#20 引用回覆 回覆 發表時間:2003-05-14 15:17:46 IP:218.172.xxx.xxx 未訂閱
非常感謝版主及wnhoo兄的鼎力相助,尤其是wnhoo大大契而不捨的的幫忙,真是感激不盡... 事實上經我昨晚測試的結果,我發現只要將QuickRep1.Preview包在Synchronize內執行就不會再出現異常,不知這與兩位大大的修改方式是否有異曲同工之妙,萬乞予以指點一二...
Justmade
版主


發表:94
回覆:1934
積分:2030
註冊:2003-03-12

發送簡訊給我
#21 引用回覆 回覆 發表時間:2003-05-14 15:41:54 IP:218.16.xxx.xxx 未訂閱
我說過我是首次認真玩 Thread 所以不熟,是花了數小時 debug VCL 執行時的動來作找出 PreviewForm 沒被正常地 Free 產生問題而提議用手動 Free 的方法。 用 Synchronize 可解決該問題,應是因為 Synchronize 是使程式在 MainThread 裡執行所致 。 Help 裡的 Synchronize 如此說 : Synchronize method (TThread) Executes a method call within the main thread. Delphi syntax: procedure Synchronize(Method: TThreadMethod); Description Synchronize causes the call specified by Method to be executed using the main thread, thereby avoiding multi-thread conflicts. If you are unsure whether a method call is thread-safe, call it from within the Synchronize method to ensure that it executes in the main thread. Execution of the thread current is suspended while Method executes in the main thread. 看程式碼來說,應是使用Synchronize 較正路因不用手動 Free 東西。但我想,若將這 Method 用回主程式來執行,那為甚麼一定要放在 Thread 裡呢? 不過由於我對 Thread 沒甚麼經驗,所以亦不敢說那種方法會較好。看看有沒有前輩高手給一些意見罷。
amemiya
一般會員


發表:1
回覆:11
積分:2
註冊:2003-05-10

發送簡訊給我
#22 引用回覆 回覆 發表時間:2003-05-14 16:20:28 IP:218.172.xxx.xxx 未訂閱
可能是因為我對QuickRep不熟的關係吧,因此把它的preview指令給放在迴圈中,讓它以開啟--關閉的方式呈現多頁的效果,而在指令執行前又需要open資料庫、create許多物件,浪費許多時間,因而才想要用thread來使Form1不至於像當掉一樣... 其實只要能事先給予QuickRep知道共要展示幾頁,我大可在最後執行一次preview即可,今天就不會弄得這麼麻煩了... 請問版主大大有這樣的指令可以規定QuickRep共要展示/列印幾頁嗎?
Justmade
版主


發表:94
回覆:1934
積分:2030
註冊:2003-03-12

發送簡訊給我
#23 引用回覆 回覆 發表時間:2003-05-14 16:49:12 IP:218.16.xxx.xxx 未訂閱
不是很明白你的思。 QuickReport 的 Preview 本身不是也支援多頁的嗎 ? 還是因為你要在 Loop 裡面去 Load 不連貫的 資料? 建議你到報表區去開個問題問比較會多人看得到並作答。
系統時間:2024-05-05 0:00:57
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!