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

如何取得DBEdit元件屬性:DataSource...(自訂元件)

尚未結案
SKYSTAR
中階會員


發表:76
回覆:198
積分:64
註冊:2002-06-10

發送簡訊給我
#1 引用回覆 回覆 發表時間:2003-03-17 01:28:41 IP:210.66.xxx.xxx 未訂閱
請教各位大大....    我寫一個很簡單的元件,是繼承於TDBEdit... 現在想要在執行時期時,取得該元件所屬欄位的長度(即:資料表所定義的長度) 我是這樣子寫的...
if not (csDesigning in ComponentState) then
begin
  MaxLength := DataSource.DataSet.FieldByName(DataField).Size;
end;
在編譯元件時,並沒有錯誤..... 後來將元件加到專案中,並設定好相關屬性後,編譯專案也沒有問題... 可是執行時,卻連Form也不能開啟,並出現一個嚴重的錯誤....訊息如下: Project Project1.exe raised exception class EAccessViolation with message'Access Violation at address 004976A1 in module 'PROJECT1.EXE' .Read of address FFFFFFFF. Process stopped. Uses Step or Run to continue. 請問那裡不對呢? Thanks!!
Justmade
版主


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

發送簡訊給我
#2 引用回覆 回覆 發表時間:2003-03-17 10:47:39 IP:218.16.xxx.xxx 未訂閱
應該是該段程式執行時相關的 DataSources 或 DataSet 還未 create 罷。 最簡單的是加入 try except    
if not (csDesigning in ComponentState) then
begin  
  try
    MaxLength := DataSource.DataSet.FieldByName(DataField).Size;
  except
    on EAccessViolation do // Access Violation 不理
    else RAISE // 其他 exception 照當彈出
  end;
end;
你也可用程式碼先查查該兩元件 create 了沒有
Rain
資深會員


發表:31
回覆:236
積分:268
註冊:2003-02-17

發送簡訊給我
#3 引用回覆 回覆 發表時間:2003-03-17 13:14:00 IP:218.5.xxx.xxx 未訂閱
TDBEdit不是有個Field屬性嗎,所以沒必要那麼麻煩了 if not (csDesigning in ComponentState) then begin if Assigned(Field) then MaxLength := Field.Size; end;
SKYSTAR
中階會員


發表:76
回覆:198
積分:64
註冊:2002-06-10

發送簡訊給我
#4 引用回覆 回覆 發表時間:2003-03-18 17:26:29 IP:210.66.xxx.xxx 未訂閱
感謝兩位大大....    我都會去試試看....謝啦!! 另外,可否多請教一個問題.... 有沒有可能在
Justmade
版主


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

發送簡訊給我
#5 引用回覆 回覆 發表時間:2003-03-18 18:25:34 IP:218.16.xxx.xxx 未訂閱
var i : integer begin for i := 0 to Table1.FieldCount -1 do begin FieldName := Table1.Fields[i].FieldName; FieldKind := Table1.Fields[i].FieldKind; .... .... end end; 發表人 - Justmade 於 2003/03/18 18:26:27
cmj
高階會員


發表:15
回覆:242
積分:226
註冊:2002-06-12

發送簡訊給我
#6 引用回覆 回覆 發表時間:2003-03-18 22:56:05 IP:211.76.xxx.xxx 未訂閱
Table的所有欄位及相關屬性請查Table.FieldDefs Table的索引資料請查查Table.IndexDefs 上述二屬性乃記錄table之結構資訊
Justmade
版主


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

發送簡訊給我
#7 引用回覆 回覆 發表時間:2003-03-18 23:26:22 IP:218.16.xxx.xxx 未訂閱
TFieldDef 是 對實體數據庫欄位的描述, TFields 是 對存在於 DataSet 欄位的描述,包括 Calculated field, lookupfield 等等。對於沒有加入永久性欄位的 Table, 兩種都可取得所有欄位的資料。不過,TField 取可得的資料會比 TFieldDef 多一點因包括 dataset 的附加資料。
SKYSTAR
中階會員


發表:76
回覆:198
積分:64
註冊:2002-06-10

發送簡訊給我
#8 引用回覆 回覆 發表時間:2003-03-19 00:20:57 IP:210.66.xxx.xxx 未訂閱
首先感謝大大們的回答....    雖然說要解決的問題,已由自己先行解決了大部份,但是有一件事要先向大大們 說句抱歉....(不要生氣喲!!) 因為前面所說的要取出有關欄位的資訊...忘了說明一個前提.... 就是當Table未開啟狀態時......這樣子好像就不能使用Field了... 因為Assigned(Field)會傳回False.....所以就無法再進一步得知其它資訊了, 對吧!.....這樣子有解嗎?    另外,如果說不想自行撰寫DataField及DataSource的讀寫程序來覆蓋原DBEdit 的程序....或是將此兩個屬性的相關程序及變數等,原封不動的拷到新元件中來 實做時......請問有何種方式,可以在Table開啟或關閉時得知其屬性值已經變 更...比如說,將Cust_ID改成Cust_Name時,可以知道此DataField已變更...(變 更的動作是手動點選來變更的).... 這個問題,最主要是想要在變更其值時,可以執行我寫的一個程序... 原本我想用攔截Message的方式來做....但是苦於找不到相關的Message.... 不知道這種情形是否可用Message來做呢? 如果可以! 應該是那一個Message呢?    很多問題....還希望大家不會覺得煩...< > 先謝囉!!< >
Rain
資深會員


發表:31
回覆:236
積分:268
註冊:2003-02-17

發送簡訊給我
#9 引用回覆 回覆 發表時間:2003-03-19 13:10:03 IP:218.5.xxx.xxx 未訂閱
資料感知元件可以參照Delphi自己元件的構架,聲明一個TDataLink,事實上這樣很多事情就變得簡單多了,例如你這邊的DataField變更執行自己的程式可以這樣處理 Type yourComponent = class(TDBEdit) private FDataLink: TFieldDataLink; procedure DataChange(Sender: TObject); procedure CMGetDataLink(var Msg: TMessage); message CM_GETDATALINK; ……. constructor yourComponent.Create(AOwner: TComponent); begin inherited Create(AOwner); FDataLink := TFieldDataLink.Create; FDataLink.Control := Self; FDataLink.OnDataChange := DataChange; end; destructor yourComponent.Destroy; begin FDataLink.Free; FDataLink := nil; inherited Destroy; end; procedure yourComponent.CMGetDataLink(var Msg: TMessage); begin Msg.Result := Integer(FDataLink); end; procedure yourComponent.DataChange(Sender: TObject); begin //這裏執行你的程式 { if FDataLink.Field <> nil then begin end;} end; //當然具體你還可以參考資料感知元件比如TDBEidt的代碼
SKYSTAR
中階會員


發表:76
回覆:198
積分:64
註冊:2002-06-10

發送簡訊給我
#10 引用回覆 回覆 發表時間:2003-03-19 20:07:13 IP:210.66.xxx.xxx 未訂閱
To: Rain....    您好.... 我的範例如下:
unit DBEditX;    interface    uses
  Windows, Messages, SysUtils, Classes, Controls, StdCtrls, Mask, DBCtrls, DB;    type
  TDBEditX = class(TDBEdit)
  private
    { Private declarations }
    FDataLink: TFieldDataLink;
    procedure DataChange(Sender: TObject);
    procedure CMGetDataLink(var Msg: TMessage); message CM_GETDATALINK;
  protected
    { Protected declarations }
  public
    { Public declarations }
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
  published
    { Published declarations }
  end;    procedure Register;    implementation    uses dialogs;    procedure Register;
begin
  RegisterComponents('SKYSTAR', [TDBEditX]);
end;    { TDBEditX }    procedure TDBEditX.CMGetDataLink(var Msg: TMessage);
begin
  showmessage('apple');
  Msg.Result := Integer(FDataLink);
end;    constructor TDBEditX.Create(AOwner: TComponent);
begin
  inherited;
  FDataLink := TFieldDataLink.Create;
  FDataLink.Control := Self;
  FDataLink.OnDataChange := DataChange;
end;    procedure TDBEditX.DataChange(Sender: TObject);
begin
  if FDataLink.Field <> nil then
  begin
    showmessage('asd');
  end;
end;    destructor TDBEditX.Destroy;
begin
  FDataLink.Free;
  FDataLink := nil;
  inherited;
end;    end.
請問...在紅色部份,為何在設計時期,我去更換DataField時(用手動點選)...怎麼沒有反應呢? Thanks!!
系統時間:2024-05-16 13:05:25
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!