FindComponent如何回傳找到的TQuery&TDataSource元件 |
尚未結案
|
rich777
一般會員 發表:25 回覆:25 積分:10 註冊:2002-04-22 發送簡訊給我 |
不才的小弟又來請教各位高手了~~~
想於TDataModule找出已存在的TQuery&TDataSource元件並傳回其設定~~~ 程式嗎
procedure TF_Main.FoundComponent(Str:String;TQ:TQuery;DS:TDataSource);
Var I:integer;
begin
for i := 0 to DmMlv.ComponentCount -1 do
begin
if (DmMlv.Components[i] is TQuery) then
begin
if (UpperCase(DmMlv.Components[i].Name)=UpperCase('TAB_' Str)) then
begin
showmessage('TQb:' tq.DatabaseName);//為了驗證下列行是否有做作
TQ:=DmMlv.Components[i].Owner.FindComponent('Tab_' UpperCase(Str)) as TQuery;
showmessage('TQe:' tq.DatabaseName);//的確的找到我要的資料...有顯示出我想要
end;
end;
//showmessage(IntTostr(i) ':' DmMlv.Components[i].Name ':' 'Ds_' UpperCase(Str)); if (DmMlv.Components[i] is TDataSource) then
begin if DmMlv.Components[i].Name='Ds_' UpperCase(Str) then
begin
DS:=DmMlv.Components[i].Owner.FindComponent('Ds_' UpperCase(Str)) as TDataSource;
showmessage('DS:' DS.Name);
end;
end;
end; end; 呼叫的副程式
procedure TStatEdit.FormShow(Sender: TObject);
//Tab_Stat,Ds_Stat<==實際在form上的元件
a.F_Main.FoundComponent(StaTableName,Tab_Stat,Ds_Stat); //error
b.Tab_Stat:=DmMlv.Tab_PRINTS; //ok
c.Ds_Stat:=DmMlv.DS_PRINTS; //ok SHOWMESSAGE('SQL:' Tab_StaT.DatabaseName);
當以bc二行程式碼執行是沒問題
但若以a呼叫副程式卻Tab_StaT.DatabaseName為空白耶???
但在副程式的Tab_StaT.DatabaseName回應是正確的耶???
那是否表示Tab_Stat,Ds_Stat二個元件沒接受到副程式的結果吶???
該如何才能接受到實際找到的元件吶???
|
hagar
版主 發表:143 回覆:4056 積分:4445 註冊:2002-04-14 發送簡訊給我 |
|
rich777
一般會員 發表:25 回覆:25 積分:10 註冊:2002-04-22 發送簡訊給我 |
感謝版大的回覆~~~
我現在的問題是無法將找到的元件回傳給呼叫的參數...
而不是找不到我要的元件
你所回覆的TDataModule.FindComponent
跟我所寫的TQ:=DmMlv.Components[i].Owner.FindComponent('Tab_' UpperCase(Str)) as TQuery;
意義上是相同的吧??? a.F_Main.FoundComponent(StaTableName,Tab_Stat,Ds_Stat); //error
Tab_Stat<===無法回傳實際我要繼承的元件???
|
ccchen
版主 發表:61 回覆:940 積分:1394 註冊:2002-04-15 發送簡訊給我 |
沒看到整個程式, 無法正確判斷, 然而可能錯誤如下:
1.
procedure TF_Main.FoundComponent(Str:String;TQ:TQuery;DS:TDataSource); Var I:integer; begin for i := 0 to DmMlv.ComponentCount -1 do begin if (DmMlv.Components[i] is TQuery) then begin if (UpperCase(DmMlv.Components[i].Name)=UpperCase('TAB_' Str)) then begin showmessage('TQb:' tq.DatabaseName);//為了驗證下列行是否有做作 TQ指向了DmMlv上之Query元件 TQ:=DmMlv.Components[i].Owner.FindComponentend; ...呼叫的副程式 procedure TStatEdit.FormShow(Sender: TObject); //Tab_Stat,Ds_Stat<==實際在form上的元件Tab_Stat本身已 create a.F_Main.FoundComponent(StaTableName,Tab_Stat,Ds_Stat); //error //當然錯誤, Tab_Stat與DmMlv上之該query, 均已create, 分別占有不同之memory space [blue]如果沒有其他錯誤, Tab_Stat只宣告為TQuery, 不要在Form有此元件應該就可以了 2. 其實由你的程式真的很不清楚, dmMlv是否有create?, f_main是否有create? a, b分別是什麼均無交代, 只能用猜的 |
rich777
一般會員 發表:25 回覆:25 積分:10 註冊:2002-04-22 發送簡訊給我 |
版大的這句提醒了我一個傳址呼叫的觀念~~~
Tab_Stat與DmMlv上之該query, 均已create, 分別占有不同之memory space
我將Tab_Stat改以宣告而不放在from上...
且將函數改以傳址呼叫...(var)
function TF_Main.FoundComponent(Var Str:String;TQ:TQuery;DS:TDataSource):Boolean;
結果還是一樣...Tab_Stat還是無法傳回 Sorry 我詞意不明....
f_main為主form...於project執行是就會自動creat... 而DmMlv...TDataModule..亦是DataModule視窗...
應該也是主from Creata時也會自動creat(此from 我是放在 auto-crear forms) 今以視窗(Available forms)放了一個TDBGrid元件..
希望以StaTableName變數的不同而自動開啟不同的於已存在DmMlv上的query?? b.Tab_Stat:=DmMlv.Tab_PRINTS; //ok
c.Ds_Stat:=DmMlv.DS_PRINTS; //ok
是代表不使用a.F_Main.FoundComponent函數時替代的做法???
但若如此就無法以變數方式開啟不同的Query了~~~ 或者我應改個方式問....
TStatEdit..form 主要是想做到以StaTableName的不同開啟不同的table...
並自動代入TDBGrid元件
當然可以以下列程式碼來代替:
Tab_Stat.RequestLive:=False;
Tab_Stat.Close;
Tab_Stat.SQL.Clear;
Tab_Stat.SQL.Add('Select * from ' StaTableName ');
Tab_Stat.Open;
但若如此TDBGrid.Title便會是英文的抬頭....
所以我才會才以DataModule元件來設定好所有要使用的Query並設好其中文抬頭...
|
ccchen
版主 發表:61 回覆:940 積分:1394 註冊:2002-04-15 發送簡訊給我 |
這幾行就有些觀念不太對, 因此可能有些你自己沒想到的錯誤,
將程式上傳來看看
且將函數改以傳址呼叫...(var)
function TF_Main.FoundComponent(Var Str:String;TQ:TQuery;DS:TDataSource):Boolean;
1. 所有的object在Delphi中均是Object Reference故不須在用var
2. (Var Str:String;TQ:TQuery;DS:TDataSource)
這個var只對 str有效, 對TQ,DS沒用
不過正好負負得正 另我將Tab_Stat改以宣告而不放在from上...
是否有Create, 不應create
|
rich777
一般會員 發表:25 回覆:25 積分:10 註冊:2002-04-22 發送簡訊給我 |
另我將Tab_Stat改以宣告而不放在from上...
我沒Creat只是宣告而已
sorry 不知如何將程式碼格式排版耶???? unit Stat_Edit; interface uses
Main, Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
ExtCtrls, StdCtrls, Buttons, Aedit, DBCtrls, Mask, EMdate, DrLabel, Db, OX3DBEdit,
DBTables, Grids, DBGrids, UserSet, LblEffct, Edsprint, Printers, siBtns,
Bit, Gauges,
ComObj,USERSET2, DBBBtn, NavBtn ; type
TStatEdit = class(TForm)
PL1: TPanel;
LB_StaName: TDRLabel;
Bit_Exit: TBitBtn;
DRLabel2: TDRLabel;
ME_Serch: TEdit;
DRLabel9: TDRLabel;
ME_DateB: TEMDATE;
LabelEffect1: TLabelEffect;
ME_DateE: TEMDATE;
Bit_Date: TBit;
DBG_Ext: TDBGrid;
Bit_Excel: TBitBtn;
Lab_Run: TLabelEffect;
Gauge1: TGauge;
Bit_Edit: TDBNavigationButton;
Bit_Save: TDBNavigationButton;
procedure FormKeyPress(Sender: TObject; var Key: Char);
procedure FormShow(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure Bit_ExitClick(Sender: TObject);
procedure Tab_StatCalcFields(DataSet: TDataSet);
procedure Bit_DateClick(Sender: TObject);
procedure ME_SerchExit(Sender: TObject);
procedure FormActivate(Sender: TObject);
procedure Bit_EditClick(Sender: TObject);
procedure DBG_ExtDrawDataCell(Sender: TObject; const Rect: TRect;
Field: TField; State: TGridDrawState);
private
{}
public
{ Public declarations }
end; var
StatEdit : TStatEdit;
Total : Longint;
Item : Integer; Tab_Stat: TQuery;
Ds_Stat: TDataSource; implementation uses Dm_Mlv; {$R *.DFM} procedure TStatEdit.FormKeyPress(Sender: TObject; var Key: Char);
begin
IF Key = #13 THEN
Begin
Key := #0;
SelectNext(ActiveControl,True,True);
End;
end; procedure TStatEdit.FormShow(Sender: TObject);
Var I:integer;
begin
// F_Main.FoundComponent(StaTableName,Tab_Stat,Ds_Stat);
// Tab_Stat:=DmMlv.Tab_PRINTS;
// Ds_Stat:=DmMlv.DS_PRINTS;
//本想將下列程式碼獨立在主form...以便讓別的form也可以call
for i := 0 to DmMlv.ComponentCount -1 do
begin
if (DmMlv.Components[i] is TQuery) then
begin
if (UpperCase(DmMlv.Components[i].Name)=UpperCase('TAB_' StaTableName)) then
begin
Tab_Stat:=DmMlv.Components[i].Owner.FindComponent('TAB_' UpperCase(StaTableName)) as TQuery;
end;
end; if (DmMlv.Components[i] is TDataSource) then
begin if DmMlv.Components[i].Name='DS_' UpperCase(StaTableName) then
begin
DS_Stat:=DmMlv.Components[i].Owner.FindComponent('DS_' UpperCase(StaTableName)) as TDataSource;
end;
end;
end;
//但現在因回傳參數的問題...所以放在使用的form上!而且也已達到我想要的功能了 SHOWMESSAGE('SQLa:' Tab_StaT.DatabaseName);//驗證是否有接受到 Bit_Edit.DataSource:=DmMLV.DS_PRINTS;
Bit_Save.DataSource:=DmMLV.DS_PRINTS;
DBG_Ext.DataSource:=Ds_Stat;
Tab_Stat.Open;
{
Tab_Users.Open;
ME_Users.Clear;
While not Tab_Users.EOF do
begin
if Tab_Users.FieldByName('Sta_Name').AsString = STA_Name then
begin
ME_Users.Items.Add(Tab_Users.FieldByName('CName').AsString);
end;
Tab_Users.Next;
end;
Tab_Users.Close;
}
ME_DateB.Text:=DateToStr(Date);
ME_DateE.Text:=DateToStr(Date); if (UserPower[4]='1') or (UserPower[9]='1') then
Bit_Edit.Enabled:=True
else
Bit_Edit.Enabled:=False; end; procedure TStatEdit.FormClose(Sender: TObject; var Action: TCloseAction);
begin
Tab_Stat.Close;
Tab_Stat.SQL.Clear;
Tab_Stat.SQL.Add('Select * from ' StaTableName);
Action := CaFree;
end; procedure TStatEdit.Bit_ExitClick(Sender: TObject);
begin
Close;
end; procedure TStatEdit.Tab_StatCalcFields(DataSet: TDataSet);
begin
// if (Tab_STA.FieldByName('QTYOK').Asinteger<>0) and (Tab_STA.FieldByName('QTYIN').Asinteger<>0) then
// Tab_STAOK.Value := (Tab_STA.FieldByName('QTYOK').Asinteger/Tab_STA.FieldByName('QTYIN').Asinteger)*100;
end; procedure TStatEdit.Bit_DateClick(Sender: TObject);
begin
Tab_Stat.RequestLive:=False;
Tab_Stat.Close;
Tab_Stat.SQL.Clear;
Tab_Stat.SQL.Add('Select * from ' StaTableName ' Where CDate >= "' ME_DateB.Text '" and CDate <= "' ME_DateE.Text '" order by CDATE');
Tab_Stat.Open;
Tab_Stat.RequestLive:=True; DbgTitleCenter(DBG_Ext);
Bit_Edit.Enabled:=False;
end; procedure TStatEdit.ME_SerchExit(Sender: TObject);
begin
IF NOT Tab_Stat.Locate('LotNO',ME_Serch.Text,[loCaseInsensitive]) AND (ME_Serch.Text<>'') THEN
SHOWMESSAGE('查無此批號!!!');
end; procedure TStatEdit.FormActivate(Sender: TObject);
begin
DbgTitleCenter(DBG_Ext);
end; procedure TStatEdit.Bit_EditClick(Sender: TObject);
begin
DBG_Ext.ReadOnly:=False;
end; procedure TStatEdit.DBG_ExtDrawDataCell(Sender: TObject; const Rect: TRect;
Field: TField; State: TGridDrawState);
begin
// DBG_Ext.ReadOnly := not Bit_Save.Enabled;
end; end.
|
ccchen
版主 發表:61 回覆:940 積分:1394 註冊:2002-04-15 發送簡訊給我 |
|
rich777
一般會員 發表:25 回覆:25 積分:10 註冊:2002-04-22 發送簡訊給我 |
感謝ccchen大大您範例程式,已經達到我想要的效果了...
只是還有不清楚的是....即然tb:TQuery可以做到傳址呼叫...
為什麼ds:TDataSource不行呢???
而我在form中有做一個查詢的按鈕功能...
程式碼如下:
Tab_Stat.RequestLive:=False;
Tab_Stat.Close;
Tab_Stat.SQL.Clear;
Tab_Stat.SQL.Add('Select * from ' StaTableName ' Where CDate >= "' ME_DateB.Text '" and CDate <= "' ME_DateE.Text '" order by CDATE');
Tab_Stat.Open;
它可以達到我要的效果....
但若我離開form...再進入便會出現上次查詢的結果...而不是全部的資料呢???
除非我離開整個ap才會出現跟第一次進入form的資料???
除非在form的close事件加上....
Tab_Stat.Close;
Tab_Stat.SQL.Clear;
Tab_Stat.SQL.Add('Select * from ' StaTableName);
才會出現與第一次進入form時所出現的資料一樣....
若是傳址呼叫的話.Tab_Stat的查詢結果應該不會影響到dm實際tquery元件的結果啊 會如此好像Tab_Stat並沒在form結束被毀滅???
不是在form Creat 時Tab_Stat也會creat一次嗎??? 想要可以同時回傳tb:TQuery; ds:TDataSource的程式碼:
tb可正確回覆...但ds卻無法???
function FoundSqlTab(tabname:string; Var tb:TQuery; ds:TDataSource):Boolean;
var c:TComponent;
begin
c :=DmMlv.FindComponent('TAB_' tabname);
Result:=False;
if c <> nil then begin
tb:=TQuery(c);
Result:=True;
end; c :=DmMlv.FindComponent('DS_' tabname);
if c <> nil then begin
ds:=TDataSource(c);
Result:=True;
end;
end;
|
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |