home *** CD-ROM | disk | FTP | other *** search
- unit ErrForm;
-
- interface
-
- uses
- SysUtils, Windows, Messages, Classes, Graphics, Controls, Forms, Dialogs,
- StdCtrls, Grids, DB, DBTables;
-
- type
- TUpdateErrorForm = class(TForm)
- ErrorText: TLabel;
- UpdateType: TLabel;
- UpdateData: TStringGrid;
- SkipButton: TButton;
- RetryButton: TButton;
- AbortButton: TButton;
- procedure FormCreate(Sender: TObject);
- procedure FormDestroy(Sender: TObject);
- procedure UpdateDataSetEditText(Sender: TObject; ACol, ARow: Integer;
- const Value: string);
- private
- FDataFields: TStringList;
- procedure GetFieldValues(DataSet: TDataSet);
- procedure SetFieldValues(DataSet: TDataSet);
- public
- function HandleError(DataSet: TDataSet; E: EDatabaseError;
- UpdateKind: TUpdateKind): TUpdateAction;
- end;
-
- var
- UpdateErrorForm: TUpdateErrorForm;
-
- implementation
-
- {$R *.DFM}
-
- { Public and Private Methods }
-
- { This method handles the error by displaying a dialog with information about
- the error and then allowing the user to decide what course of action to take }
-
- function TUpdateErrorForm.HandleError(DataSet: TDataSet; E: EDatabaseError;
- UpdateKind: TUpdateKind): TUpdateAction;
- const
- UpdateKindStr: array[TUpdateKind] of string = ('Modified', 'Inserted',
- 'Deleted');
- begin
- { Put the error context information into the labels on the form }
- UpdateType.Caption := UpdateKindStr[UpdateKind];
- ErrorText.Caption := E.Message;
- { Fill the string grid with the update field values }
- GetFieldValues(DataSet);
- ShowModal;
- case ModalResult of
- mrRetry:
- begin
- { If user wants to retry, then put any changed values from the
- string grid back into the associated field's NewValue property }
- SetFieldValues(DataSet);
- Result := uaRetry;
- end;
- mrIgnore:
- Result := uaSkip;
- else
- Result := uaAbort;
- end;
- end;
-
- { This fills in the string grid with data from the record being updated }
-
- procedure TUpdateErrorForm.GetFieldValues(DataSet: TDataSet);
- var
- I: Integer;
- F: TField;
- begin
- { Create a list of the data fields in the dataset, and store them in
- a stringlist which we can use to determine which values the user
- has edited }
-
- FDataFields.Clear;
- for I := 0 to DataSet.FieldCount - 1 do
- with Dataset.Fields[I] do
- if (FieldKind = fkData) then
- FDataFields.AddObject('', DataSet.Fields[I]);
-
- { Now fill up the string grid with the Old and New values of each field.
- OldValue and NewValue are public properties of TDataSet which are used
- from within the OnUpdateError event handler to determine what data a
- user has updated. We use the VarToStr RTL function to ensure that null
- fields are displayed as blank strings }
-
- UpdateData.RowCount := FDataFields.Count + 1;
- for I := 0 to FDataFields.Count - 1 do
- begin
- F := TField(FDataFields.Objects[I]);
- UpdateData.Cells[0, I + 1] := VarToStr(F.NewValue);
- UpdateData.Cells[1, I + 1] := VarToStr(F.OldValue);
- end;
- end;
-
- procedure TUpdateErrorForm.SetFieldValues(DataSet: TDataSet);
- var
- I: Integer;
- F: TField;
- begin
- for I := 0 to FDataFields.Count - 1 do
- { We set the string in the data field list to '*' for any fields the
- user edited in the string grid. Those are the only fields we need
- to write back into the associated TField's NewValue property }
- if FDataFields[I] = '*' then
- begin
- F := TField(FDataFields.Objects[I]);
- F.NewValue := UpdateData.Cells[0, I + 1];
- end;
- end;
-
- { Event handlers }
-
- procedure TUpdateErrorForm.FormCreate(Sender: TObject);
- begin
- FDataFields := TStringList.Create;
- { Fill in the titles of the string grid }
- UpdateData.Cells[0,0] := 'New Value';
- UpdateData.Cells[1,0] := 'Old Value';
- end;
-
- procedure TUpdateErrorForm.FormDestroy(Sender: TObject);
- begin
- FDataFields.Free;
- end;
-
- procedure TUpdateErrorForm.UpdateDataSetEditText(Sender: TObject; ACol,
- ARow: Integer; const Value: string);
- begin
- { Set a flag in the list of datafields indicating that this value
- was changed. }
- FDataFields[ARow - 1] := '*';
- end;
-
- end.
-