程式執行 Post 寫入磁碟時若磁碟未就緒會發生異常。異常發生時應用程式暫停彈出錯誤對話框,使用者點擊後程式繼續執行至不可預期位置。此時表單所有控制項已與 TTable 失去連接(因前置 DisableControls),導致顯示資料與資料庫脫節。
Object Pascal Try...Finally 解決此問題:Try 區塊含可能產生異常程式碼,Finally 區塊含即使發生異常也必須執行陳述式。本例 Finally 僅含 EnableControls:
with Table do
begin
DisableControls; { 修改期間切斷控制項連接 }
try
First; { 指標移至第一筆 }
while not EOF do
begin
<讀取欄位值到變數>
<適當修改>
Edit; { 進入編輯狀態 }
<寫回修改值>
Post; { 寫入資料庫 }
Next; { 下一筆 }
end;
EnableControls;
finally { 異常發生時執行 }
EnableControls; { 恢復控制項功能 }
end;
end;
關鍵區別:Try...Finally 為異常保護(確保 Finally 執行讓程式繼續);Try...Except 為異常處理(採取對應處理)。切勿混淆。
unit Unit26;
interface
uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, Grids, DBGrids, ExtCtrls, DB, DBTables, Buttons;
type
TForm1 = class(TForm)
DataSource1: TDataSource;
CustomerTable: TTable;
Panel1: TPanel;
DBGrid1: TDBGrid;
Panel2: TPanel;
UpperCaseFirstAddBtn: TButton;
UpperCaseSecondAddBtn: TButton;
MixedCaseFirstAddBtn: TButton;
MixedCaseSecondAddBtn: TButton;
BitBtn1: TBitBtn;
procedure ForceCase(TargetField: string; ToUpper: Boolean);
procedure UpperCaseFirstAddBtnClick(Sender: TObject);
procedure MixedCaseFirstAddBtnClick(Sender: TObject);
procedure UpperCaseSecondAddBtnClick(Sender: TObject);
procedure MixedCaseSecondAddBtnClick(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var Form1: TForm1;
implementation
const
Upper = True;
Mixed = False;
{$R *.DFM}
function IsUpper(Ch: Char): Boolean;
begin
Result := (Ch >= 'A') and (Ch <= 'Z');
end;
procedure TForm1.ForceCase(TargetField: string; ToUpper: Boolean);
var
WorkBuffer: string;
I: Integer;
begin
with CustomerTable do
begin
DisableControls;
try
First;
while not EOF do
begin
WorkBuffer := FieldByName(TargetField).AsString;
if ToUpper then
for I := 1 to Length(WorkBuffer) do
WorkBuffer[I] := UpCase(WorkBuffer[I])
else
begin
for I := 1 to Length(WorkBuffer) do
if IsUpper(WorkBuffer[I]) then
WorkBuffer[I] := Chr(Ord(WorkBuffer[I]) + 32);
WorkBuffer[1] := UpCase(WorkBuffer[1]);
end;
Edit;
FieldByName(TargetField).AsString := WorkBuffer;
Post;
Next;
end;
finally
EnableControls;
end;
end;
end;
procedure TForm1.UpperCaseFirstAddBtnClick(Sender: TObject);
begin
ForceCase('Addr1', Upper);
end;
procedure TForm1.MixedCaseFirstAddBtnClick(Sender: TObject);
begin
ForceCase('Addr1', Mixed);
end;
procedure TForm1.UpperCaseSecondAddBtnClick(Sender: TObject);
begin
ForceCase('Addr2', Upper);
end;
procedure TForm1.MixedCaseSecondAddBtnClick(Sender: TObject);
begin
ForceCase('Addr2', Mixed);
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
CustomerTable.Open;
end;
end.
四按鈕分別處理 Addr1/Addr2 全大寫或首字大寫其餘小寫。ForceCase 統一邏輯:DisableControls → Try...Finally 保護 EnableControls → 遍歷記錄修改欄位值。