後一頁
前一頁
回目錄
回首頁
第十五章 數據存取部件的應用及程式設計(三)

15.6.1 欄位部件 

欄位部件在應用程式中始終是不可見的部件。在程式執行過程中是如此,在程式設計階段也是如此,但是它在應用中起著非常重要的作用,可以說它是所有數據瀏覽部件從資料庫表中顯示、編輯數據的基礎。這是因為欄位部件直接對應著資料庫表中的欄位,瀏覽和修改表中的數據必須要通過欄位部件,同時欄位部件所擁有的屬性可以用來敘述資料庫表中對應的欄位的數據型式、目前的欄位值、顯示格式、編輯格式等,欄位部件的事件如OnValidate可以用來設定輸入欄位值時進行有效性檢驗。

資料庫表的每一列在應用程式中都有其對應的一個欄位部件,在缺省情況下,當TTable或TQuery的Active屬性被置為False或呼叫close方法時,與表中各列對應的欄位部件也隨即消失,要想為應用程式建立永久性的欄位部件,我們必須要在程式設計階段使用欄位編輯器(Fields Editor)來建立。使用欄位編輯器建立永久性欄位的好處是:我們在程式代碼中利用永久性欄位部件可以更加有效、方便、可靠地存取資料庫表中記錄的各欄位值, 在任何時候我們都可以以同樣的欄位順序、固定的欄位顯示表中的記錄,即使資料庫表的結構已發生了變化。當然如果在資料庫表中與欄位部件對應的欄位已經不存在時,應用程式就不能正常地執行下去了,Delphi會彈出一個錯誤資訊框,告訴用戶表中的欄位已經不存在了。 

15.6.1.1 欄位部件的屬性及應用 

欄位部件具有很多的屬性,通過設定欄位部件有關的屬性,可以控制欄位物件在數據瀏覽部件中的顯示方式、欄位值能否被修改等。特別是對於用欄位編輯器建立的永久性的欄位部件,我們在程式設計階段便可以在Object Inspector中方便地選取欄位部件, 進行有關屬性的設定。

欄位部件的主要屬性如表15.6所示,該表中列出的屬性只是欄位部件的部分屬性,它主要用來控制欄位物件的顯示方式。 

表15.6 欄位部件的主要屬性

───────────────────────────────

屬性名 功 能

———————————————————————————————

Alignment 敘述欄位值在數據瀏覽部件中顯示時的對齊方式:

左對齊、右對齊、居中三種方式。

———————————————————————————————

Calculated 敘述欄位是否是計算欄位,屬性值為True時,該

欄位是計算欄位、欄位值可以根據表中其它欄位

的值計算得出。

———————————————————————————————

Currency 等於true時,以貨幣格式顯示數值,等於False時,

不以貨幣格式顯示數值型數據。

———————————————————————————————

DisplayFormat 用於敘述欄位值在數據瀏覽部件中的顯示格式

———————————————————————————————

DisplayLabel 欄位在網格(TDBGrid部件)中顯示時,為欄位指定

顯示標題。

———————————————————————————————

DisplayNidth 欄位在網格(TDBGrid部件)中顯示時,為欄位指定

顯示寬度,單位是字元數。

———————————————————————————————

EditFormat 敘述欄位在數據瀏覽部件中的編輯輸入格式

———————————————————————————————

EditMask 在進行欄位值的編輯輸入時,限定輸入欄位值的

過濾條件(即欄位值的範圍)。

———————————————————————————————

FieldName 該欄位部件對應實際資料庫表中的欄位的名字

———————————————————————————————

Index 該欄位部件在數據集所有欄位部件中的順序號

———————————————————————————————

MaxValue 敘述可以為該欄位輸入最大的數值

———————————————————————————————

MinValue 敘述可以為該欄位輸入最小的數值

———————————————————————————————

Name 欄位部件的名字

———————————————————————————————

ReadOnly 等於true時,只能讀取該欄位的欄位值,不能修改;

等於False時,可以對該欄位的欄位值進行讀寫。

———————————————————————————————

Size 敘述欄位的大小,單位是字元數

———————————————————————————————

Visible 為True時,該欄位可以在TBDBGrid部件中顯示;

為False時,該欄位不能在TDBGrid部件中顯示

───────────────────────────────

 

表15.6中的屬性並不是所有型式的欄位部件都擁有的,如一個TStringField型式的欄位部件是沒有Currency、MaxValue、MinValue和DisplayFormat屬性的,一個TFloatField型式的欄位部件是沒有Size屬性的。

對於布爾型屬性,在設計過程中的Object Inspector中連續按兩下該屬性,該屬性的值將會在True和False之間來回切換,其他屬性需要用戶輸入屬性值或從下拉式列示方塊中選取屬性值。所有的屬性都可以通過程式代碼進行設定。大多數屬性可以獨立地設定,只有DisplayFormat,EditFormat和EditMask是相互聯繫的。在設定它們的屬性值時一定要確保相互協調。

利用EditMask屬性為欄位設定編輯模式:

為欄位部件設定一定的EditMask屬性值,當編輯輸入該欄位的欄位值時,用戶只能根據EditMask設定的編輯模式進行編輯或輸入欄位值。在為EditMask屬性設定屬性值時可以用手動方式也可以用輸入模式編輯器來完成,當為某欄位部件設定EditMask屬性時,雙滑鼠連續按兩下EditMask屬性便可以打開輸入模式編輯器(Input Mask Editor) 。例如在為Customer.DB表的Phone欄位設定編輯模式時,首先在Object Inspector中選取與Phone欄位對應的Table1Phone欄位物件,然後連續按兩下EditMask屬性,打開輸入模式編輯器。 

欄位輸入模式編輯器 

在欄位輸入模式編輯中可以選擇一種輸入模式,而且在TestInput編輯框中輸入欄位值進行檢驗。

因為TStringField型式的欄位部件沒有DisplayFormat屬性,但是可以把EditMask屬性當DisplayFormat屬性使用。

設定欄位的顯示和編輯格式:

Delphi本身為某些型式的欄位物件提供了設定其顯示和編輯格式的例程,並且為欄位部件的DisplayFormat和EditFormat屬性指定了缺省值,例如對於與浮點型數值欄位對應的TFloatField型式的欄位部件,而且該欄位部件的Currency屬性設定為True 時,欄位值1234.56的顯示格式為$1234.56,編輯格式是1234.56。表15.7是Delphi提供了設定欄位顯示和編輯格式的例程。 

表15.7 欄位格式例程

─────────────────────────────

例 程 名 運用的欄位物件

—————————————————————————————

FormatFloat TFloatField,TCurrencyField

FormatDateTime TDateField,TTimeField,TDateTimeField

FormatInteger TIntegerField,TSmallIntField,TWordField

─────────────────────────────

 

上述這些用於設定日期時間型式、數值型以及貨幣型欄位的顯示和編輯格式的例程,都是按國際上通行格式來設定相應型式欄位的格式的,用戶可以自己設定欄位部件的DisplayFormat和EditFormat屬性,來設定適合自己使用的格式,還可以為有關欄位物件的OnGetText和OnSetText事件編寫代碼來設定欄位的顯示和編輯格式。

 

15.6.1.2 欄位部件的事件及應用

 

欄位部件常需處理的事件如表15.8所示

 

表15.8 欄位部件的事件

────────────────────────────

事件名 用 途

————————————————————————————

OnChange 當欄位部件的欄位值發生改變時,觸發該事件

OnGetText 當欄位部件獲得欄位值時,觸發該事件

OnSetText 當欄位部件被設定欄位值時,觸發該事件

OnValidata 當字值被修改或插入新的欄位值時,對欄位值

進行有效性檢驗時,觸發該事件

────────────────────────────

 

用戶想自己設定欄位的顯示和編輯格式時,可以編寫OnGetText事件和OnSetText事件的處理過程,以達到設定欄位的顯示和編輯格式。

 

15.6.1.3 欄位部件的型式轉換函數及使用

 

欄位部件具有一些內部函數用於轉換欄位值的型式,對於不同的欄位型式,這些轉換函數的作用是不一樣的,表15.9概括了不同型式的欄位及轉換函數的作用。

 

表15.9 欄位部件的轉換函數

────────────────────────────────────

欄位型式 AsString AsInteger AsFloat AsDatetime AsBoolean

————————————————————————————————————

TStringField 轉換成 轉換成整數 若能轉換 日期 轉換成布型

Stringg型 (若能轉換) 則轉換成 (若能轉換)

————————————————————————————————————

TIntegerField

TSmallField 字元型 整數型 浮點型 不允許 不允許轉換

TWordField

————————————————————————————————————

TFloatField

TCurrencyField 字元串型 舍入成整數 浮點型 不允許 不允許

TBCDField

————————————————————————————————————

TDateField

TDateTimeField 字元串 不允許 浮點數 日期型 不允許

TTimeField

————————————————————————————————————

TBooleanField 轉換成Time 不允許 不允許 不允許 布爾型

或False

————————————————————————————————————

TBytesField

TVarBytesField 字元串 不允許 不允許 不允許 不允許

TBlobField

————————————————————————————————————

TMemoField 二進制 不允許 不允許 不允許 不允許

TGraphilField 欄位

────────────────────────────────────

 

上述這些轉換函數可以在任何與欄位部件有關的表達式中使用,只要是表15.9中允許進行轉換的數據型式,這些轉換函數其實是當做欄位部件的屬性來使用的,它們可以出現在賦值語句的兩邊。例如下面的程式代碼是將欄位部件TableMyField的欄位值轉變成字元串型式的數據,並將它賦給編輯框Edit1的Text屬性:

 

Edit1.Text := TableMyField.AsString;

 

而下面的代碼是進行相反的操作,它將編輯框部件Edit1的Text屬性值以字元串的形式賦給欄位TableMyField,TableMyField通過AsString接受字元串並將其轉變成自身的數據型式。

 

TableMyField.AsString :=Edit1.Text;

 

15.6.1.4 欄位部件的存取

 

欄位部件對應著資料庫表中實際的欄位,用戶要讀寫資料庫表中的欄位值其實是通過存取相應的欄位部件進行的。在前面的章節中我們介紹過在Delphi的資料庫應用程式中有兩類欄位部件:一類是利用欄位編輯器建立的永久性欄位部件;另一類是隨著數據集部件被激活(被打開)而動態產生的欄位部件。對於永久性欄位部件的存取可以直接呼叫使用欄位部件的名字進行。假設我們在設計階段利用欄位編輯器建立了對應於Customer.DB表中Company欄位的欄位部件Table1Company,下面的代碼存取Company欄位的欄位值,並將該欄位值顯示在編輯框部件Edit1中。

 

Edit1.Text := Table1Company.Value;

 

因為company欄位是字元串型式的數據,它與Edit1中的數據型式相匹配的,因此可以直接使用欄位部件的Value屬性讀取欄位值。如果兩個變數的型式不匹配,則要使用表15.9中的轉換函數進行欄位值的讀取。例如:要讀取Customer.DB表中的CustNo欄位的值並將它顯示在編輯模框Edit1中,假設我們已用欄位編輯器(Fields Editor)建立了CustNo相應的欄位部件,Table1CustNo,則程式代碼如下:

 

Edit1.Text := Table1CustNo.AsString;

 

存取動態產生的欄位部件相對要困難一些,因為動態產生的欄位部件是沒有自己的名字的,我們必須利用特殊的手段獲得資料庫表中各欄位對應的欄位部件,然後對欄位進行存取。一般採用的方法有兩種:

● 使用數據集部件的Fields屬性

● 使用數據集部件的FieldByName方法

 

1. 使用數據集部件的Fields屬性存取資料庫表中各欄位

數據集部件的Fields屬性是與數據集部件相連的資料庫表中各個欄位對應的動態欄位部件的名字清單,因此我們可以通過Fields屬性的下標(即索引號)來存取各欄位部件,從而達到存取資料庫表中的各個欄位,索引號從0開始,也就是說資料庫表中第一個欄位對應著Fields清單的第一行即0索引,第二個欄位對應的Fields的索引號為1,以此類推。下面的例子是存取Customer.DB表中的第一個欄位並在編輯框Edit1中顯示其欄位值。假設Table1與資料庫表Customer.DB相連。

 

Edit1.Text := Table1.Fields[0].AsString;

 

下面的代碼是將編輯框Edit1中的字元值賦給Customer.DB表中目前記錄的第一個欄位,以實現修改Customer.DB表中的欄位值。

 

Table1.Fields[0].AsString := Edit1.Text;

 

2.使用數據集部件的FieldByName方法存取欄位部件

在數據集部件所擁有的方法中,有一個FieldByName方法,它是專門用於存取數據集部件中動態產生的欄位部件的,呼叫FieldByName方法時,必須要把資料庫表中的欄位名作為參數傳給FieldByName,呼叫該方法後便可以得到該欄位所對應的欄位部件,這樣通過欄位部件我們便可以讀寫表中相應的欄位值了,用這種方法存取欄位部件時,必須要知道資料庫表中各個欄位的名字,否則是沒有辦法呼叫該方法的。還是基於上面的假設。下面是存取Customer.DB表中的CustNo欄位的程式代碼:

 

Edit1.Text := Table1.FieldByName('CustNo').AsString;

Table1.FieldByName('CustNo').AsString := Edit1.Text;

 

在使用這兩種方法存取動態產生的欄位部件時,可以使用表15.9中的轉換函數,在變數和欄位值之間進行數據型式的轉換。

 

15.6.2 欄位編輯器的使用

 

欄位編輯器(Fields Editor)主要是用於建立永久性的欄位部件。在前面的內容中我們知道,當TTable或TQuery部件與資料庫表相連接時,且TTable或TQuery部件被激活時(Active屬性被設定成True或呼叫Open方法),Delphi便動態地為表中各欄位建立相應的欄位部件,欄位部件中包含著相應欄位的很多資訊如欄位值、欄位值的顯示、編輯格式等,有時我們在應用程式中為了更加方便、可靠地存取資料庫表中各個欄位,需要建立永久性的欄位部件,這時我們必須要借助於欄位編輯器來實現我們的設想。欄位編輯器的主要功能如下:

● 建立永久性的欄位部件

● 修改永久性欄位的顯示屬性,如顯示格式、顯示寬度等

● 解除永久性的欄位部件

● 增加新的永久性的欄位部件

● 定義計算欄位(不對應資料庫表中實際的欄位,欄位值根據表中其他欄位的值計算得出)

 

15.6.2.1 打開欄位編輯器

 

為TTable和TQuery部件打開欄位編輯有兩種方法:

● 用滑鼠左鍵連續按兩下TTable或TQuery部件

● 選擇TTable部件或TQuery部件,然後按一下滑鼠右鍵,然後從彈出式選擇表中選擇 Fields Editor

 

欄位編輯器Fields Editor被打開以後,窗體的名字和數據集部件的名字會顯示在視窗的標題上。 

欄位編輯器Fields itor中的Fields列示方塊是用於顯示已經建立的永久性欄位部件的名字的。欄位編輯器Fields Editor第一次被打開時, 該列示方塊是空的,因為在此之前的欄位部件都是動態產生的,只要Fields列示方塊中有欄位部件,那麼與數據集部件相連的數據瀏覽部件中只顯示Fields中列出的欄位的欄位值,在Fields列示方塊中,可以通過拖放欄位部件的名字來改變相應的欄位值在數據瀏覽部件中的顯示順序,如在TDBGrid部件中根據各欄位在Fields列示方塊中的順序顯示各欄位的值。

在欄位編輯器Fields Editor窗體上面的導航按鈕是用來移動TTable或TQuery部件中的記錄指標的,使用導航按鈕可以將記錄指標向前、向後移動,也可以移到第一條記錄處或最後一條記錄處。 

欄位編輯器中的彈出式選擇表 

15.6.2.2 增加欄位部件 

欄位編輯器Fields Editor中的Add Fields選擇表項用於向數據集部件中增加欄位部件的,按一下Add Fields選擇表項時便會打開增加欄位部件對話方塊,如圖15.9所示。Available Fields列示方塊中顯示出數據集部件TTable或TQuery中目前可以用於建立永久欄位部件的全部的欄位,也就是說Available Fields列示方塊中顯示欄位是資料庫表中實際存在的欄位,而且還沒有為這些欄位建立相應的永久性的欄位部件,在缺省狀態下所有的欄位都被選擇用於建立相應的永久性的欄位部件,用滑鼠按一下其中的欄位名可以有選擇地建立其相應的永久性的欄位部件,選擇好有關的欄位名之後,按一下OK按鈕便可以建立永久性的欄位部件。 

欄位編輯器的增加欄位部件對話方塊  

15.6.2.3 解除欄位部件 

用欄位編輯器Fields Editor為數據集部件建立好的欄位部件都會顯示在欄位編輯器的Fields列示方塊中,如果用戶認為其中的一些欄位部件不合適或不再需要時,可以按一下這些不需要的欄位部件,然後按一下滑鼠右鍵彈出一傭彈出式選擇表,從彈出式選擇表中選擇Delete選擇表項,便可解除相應的欄位部件,如果在彈出式選擇表中按一下Select All選擇表項,然後選擇Delete選擇表項,這樣會解除已建立好的所有的欄位部件。某一個欄位部件被解除以後,通過按一下Add Fields選擇表項可以重新建立,只是先前為該欄位部件設定的一些屬性將不復存在。

 15.6.2.4 定義新的欄位部件 

欄位編輯器Fields Editor中的彈出式選擇表中New Fields選擇表項是用來為數據集部件TTable或TQuery建立用於顯示目的的新的欄位部件,我們可以用它來為資料庫表中實際存在的欄位建立新的欄位部件(如改變欄位的數據型式,使它的欄位值被顯示時不再需有關的型式轉換),但是我們使用New Fields選擇表項建立新的欄位部件主要是建立計算欄位。計算欄位並不與資料庫表中實際存在的欄位對應,它的欄位值是根據表中其它的欄位值計算而來的,具體的計算表達式由用戶為TTable部件或TQuery部件的OnCalCFields事件編寫程式代碼時決定。

定義(建立)計算欄位的過程如下:

1.按一下欄位編輯器中的New Fields選擇表項,定義欄位對話方塊如圖15.11所示。

2.在FieldName編輯框中輸入新欄位部件的名字,或者從下拉式列示方塊中選擇一個已 存在的欄位部件的名字。

3.在FieldType列示方塊中為新欄位部件選擇一個欄位型式。

4.按一下Calculated檢查框,確認定義的新欄位部件是計算欄位。

5.按一下ok按鈕,建立上述定義的計算欄位部件,此時該欄位部件的名字會自動地加入 到欄位編輯中的Fields列示方塊中。 

建立新的計算欄位

新的計算欄位建立好了之後,它是沒有任何欄位值的,我們必須要編寫相應的程式代碼,根據資料庫表中實際存在的欄位的欄位值為計算欄位的寶定義欄位值,我們為計算欄位所在數據集部件的OnCalcFields事件編寫代碼來為計算欄位賦值,其步驟如下:

1.選擇數據集部件TTable或TQuery

2.按一下數據集部件的事件頁

3.連續按兩下OnCalcFields事件為TTable或TQuery部件編寫事件處理過程

 15.7 TReport部件及其應用 

在一般的資料庫應用程式中都包含著為最終用戶提供輸出報表的功能,使用Delphi開發資料庫應用程式時,可以使用一個叫TReport的部件來執行報表功能的,報表的具體格式和內容是由Delphi提供的一個專用報表產生工具ReprotSmith建立的,它報表的具體格式和內容產生一個報表文件,然後為TReport部件設定相應的屬性參數,由TReport部件執行報表功能。

我們可以在設計階段連續按兩下TReport部件,呼叫ReportSimith工具或者在Delphi程式群群組內連續按兩下ReportSmith圖示來呼叫ReportSmith工具來建立一個報表文件,具體的操作步驟和設計方法請參看ReportSimth工具的使用敘述。

我們在使用TReport部件執行報表功能時,要設定TReport部件的一些的一些屬性,這些屬性是:

ReportName屬性:敘述報表文件的名字,就是用ReportSmith建立的報表文件。

ReportDir屬性:敘述報表文件所在的途徑名。

PreView屬性:這是一個布爾型屬性。若它的值為True,那麼在執行報表功能時,只是在螢幕上顯示報表;若它的值為False,則報表內容將在缺省的列印機列印出來。

AutoUnload屬性:布爾型屬性,它的值為True時,在執行完一個報表功能後,自動地從記憶體中卸出ReportSmith工具;它的值為False時,在執行完一個報表功能後,不從記憶體中卸出ReportSmith工具。一般情況下,如果應用程式只有一個報表或者只有較少的報表要輸出時,應設定AutoUnload屬性為True,如果應用程式一次要輸出多個報表,那麼要應設定AutoUnload屬性為False。

InitialValues屬性:這是一個字元串型式的屬性,它是敘述報表文件中使用的變數,每一條敘述一個變數。如:

 

ReportVAR := Value;

 

要詳細了解建立和使用報表變數的過程請參看建立報表一節。

TReport部件要真正執行報表功能以輸出一個報表需要呼叫Run方法。如下所示:

 

Report1.Run;

 

TReport部件所具有的重要方法如表15.10所示。

 

表15.10 TReport部件的方法

────────────────────────────

方法 功 能

————————————————————————————

Run 執行報表功能,輸出報表

RunMacro 發送一個宏命令給Reportimith工具

Connect 預先連接報表文件和資料庫,在輸出報表時不

需要登入到資料庫

SetVariable 改變敘述的報表變數

ReCalcReport 當報表變數改變以後,重新輸出報表

────────────────────────────

 

還有一些其他的數據存取部件如TBatchMove部件, 它主要用在兩個資料庫表之間移動或拷貝帆數據記錄,具體的使用請參看本地SQL伺服器的使用。

 

15.8 應用舉例:多個窗體顯示同一個資料庫表

 

在應用當中,我們常常需要以不同的視圖顯示同一個資料庫表中的內容,例如要在兩窗體中同時顯示一個資料庫表中一個記錄的不同欄位時,我們必須要想辦法使兩個窗體中的數據瀏覽部件同步地顯示資料庫表中的同一條記錄的不同欄位的值。要想做到以不同的視圖顯示同一個資料庫表中的記錄,下面兩條規則是很重要的:

● 多個TDataSource部件能夠同時存取同一個數據集部件

● 在多個窗體中顯示同一個表時,必須為每個窗體設定一個TDataSource部件,只須 為其中的一個窗體設定一個TTable部件

 

例如,如果想在窗體Form1和Form2中同時顯示一個資料庫表的記錄,最簡單可行的辦法是:為Form1和Form2各設定一個TDataSource部件叫DataSource1、DataSource2,並在Form1中設定一個TTable部件Table1,連接Form1中的Datasource1和Table1,在程式執行過程中設定Form2中的DataSource2的DataSet屬性為Form1中的Table1,代碼如下:

 

Format2.DataSource1.Dataset := Form1.Table1;

 

這樣,當Table1被打開時,兩個窗體中便可以同步地顯示資料庫表中的同一條記錄了。

一個名叫TWOForms.DPR的例子在C:\Delphi\DEMos\DB\TwoForms中(如果Delphi裝設在其它的磁碟磁碟機中,從相應的磁碟磁碟機中可以找到該例子),它演示了在兩個窗體中顯示同一個資料庫表的記錄。應用程式在第一個窗體中打開Contry.DB表,並在窗體中顯示Name、Captial和Continent欄位,在第二個窗體中顯示Area和Population欄位,在第一個窗體中有一個按鈕用於打開第二個窗體,兩個窗體中都有TDBNavigator部件,用於記錄的導航。

 


後一頁
前一頁
回目錄
回首頁