unit uEditorDBBase; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, uEditorItem, ImgList, PngImageList, StdActns, ActnList, TBX, TB2Item, TB2Dock, TB2Toolbar, ComCtrls, JvExControls, JvComponent, JvNavigationPane, DB, uDADataTable, uEditorBase, JvFormAutoSize, uDAScriptingProvider, uDACDSDataTable, AppEvnts, uCustomView, uViewBase, uViewMensaje, JvAppStorage, JvAppRegistryStorage, JvFormPlacement, pngimage, ExtCtrls, JvComponentBase, dxLayoutLookAndFeels; type IEditorDBBase = interface(IEditorBase) ['{497AE4CE-D061-4F75-A29A-320F8565FF54}'] end; TfEditorDBBase = class(TfEditorBase, IEditorDBBase) dsDataTable: TDADataSource; procedure actRefrescarExecute(Sender: TObject); procedure actAnteriorExecute(Sender: TObject); procedure actSiguienteExecute(Sender: TObject); procedure actAnteriorUpdate(Sender: TObject); procedure actSiguienteUpdate(Sender: TObject); procedure actRefrescarUpdate(Sender: TObject); procedure actCancelarCambiosExecute(Sender: TObject); procedure actGuardarExecute(Sender: TObject); procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean); virtual; procedure actEliminarExecute(Sender: TObject); procedure actEliminarUpdate(Sender: TObject); procedure actModificarUpdate(Sender: TObject); procedure actPrevisualizarUpdate(Sender: TObject); procedure actImprimirUpdate(Sender: TObject); private { Private declarations } protected function GetModified: Boolean; override; published end; var fEditorDBBase: TfEditorDBBase; implementation uses uExceptions, uDataTableUtils, uBizInformesBase, uDAInterfaces, uBizImportesDetalleBase; {$R *.dfm} procedure TfEditorDBBase.actRefrescarExecute(Sender: TObject); var ACursor: TCursor; ABookmark : TBookmark; begin inherited; if Assigned(dsDataTable.DataTable) then begin if (not ModifiedQuery) then Exit; // No continuar con el refresco ACursor := Screen.Cursor; Screen.Cursor := crHourGlass; try if dsDataTable.DataTable.IsEmpty then begin dsDataTable.DataTable.Refresh; end else begin ABookmark := dsDataTable.DataTable.GetBookMark; // dsDataTable.DataTable.DisableControls; <- No descomentar dsDataTable.DataTable.Refresh; if dsDataTable.DataTable.Dataset.BookmarkValid(ABookmark) then dsDataTable.DataTable.GotoBookmark(ABookmark); dsDataTable.DataTable.FreeBookmark(ABookmark); // dsDataTable.DataTable.EnableControls; <- No descomentar end; finally Screen.Cursor := ACursor; end; end; end; procedure TfEditorDBBase.actAnteriorExecute(Sender: TObject); begin inherited; if Assigned(dsDataTable.DataTable) then begin if (not ModifiedQuery) then Exit; dsDataTable.DataTable.Prior; end; end; procedure TfEditorDBBase.actSiguienteExecute(Sender: TObject); begin inherited; if Assigned(dsDataTable.DataTable) then begin if (not ModifiedQuery) then Exit; dsDataTable.DataTable.Next; end; end; procedure TfEditorDBBase.actAnteriorUpdate(Sender: TObject); begin inherited; if Assigned(dsDataTable.DataTable) then (Sender as TAction).Enabled := not dsDataTable.DataTable.BOF else (Sender as TAction).Enabled := False; end; procedure TfEditorDBBase.actSiguienteUpdate(Sender: TObject); begin inherited; if Assigned(dsDataTable.DataTable) then (Sender as TAction).Enabled := not dsDataTable.DataTable.EOF else (Sender as TAction).Enabled := False; end; procedure TfEditorDBBase.actRefrescarUpdate(Sender: TObject); begin inherited; if Assigned(dsDataTable.DataTable) and (not (dsDataTable.DataTable.State = dsInsert)) then (Sender as TAction).Enabled := not (dsDataTable.DataTable.Fetching or dsDataTable.DataTable.Opening or dsDataTable.DataTable.Closing) else (Sender as TAction).Enabled := False; end; procedure TfEditorDBBase.actCancelarCambiosExecute(Sender: TObject); var dtDetails : TList; i : integer; ABookmark : TBookmark; ACursor : TCursor; AParche : IParche; begin inherited; AParche := NIL; if Assigned(dsDataTable.DataTable) then begin ABookmark := dsDataTable.DataTable.GetBookMark; dsDataTable.DataTable.DisableControls; // dsDataTable.DataTable.DisableEventHandlers; <- No descomentar ACursor := Screen.Cursor; Screen.Cursor := crHourGlass; { No lo pongo en try..finally para ver posibles errores } //try dsDataTable.DataTable.Cancel; dtDetails := dsDataTable.DataTable.GetDetailDataTables; for i := 0 to dtDetails.Count - 1 do begin (TDADataTable(dtDetails.Items[i])).Cancel; { PARCHE ********************************** OJO: Está pensado para que sólo una de las tablas detalle soporte el interfaz de IParche } if not Assigned(AParche) and Supports((TDADataTable(dtDetails.Items[i])), IParche, AParche) then AParche.DesactivarEventos; end; dsDataTable.DataTable.CancelUpdates; { Comprobar si el bookmark no es válido cuando estamos cancelando la inserción de una fila nueva. CUIDADO!! Si no es válido salta una excepción. NO devuelve false!!!} try if (Assigned(ABookmark)) and (dsDataTable.DataTable.Dataset.BookmarkValid(ABookmark)) then dsDataTable.DataTable.GotoBookmark(ABookmark); except end; { PARCHE ********************************** } if Assigned(AParche) then begin AParche.ActivarEventos; AParche.Refrescar; AParche := NIL; end; //finally dsDataTable.DataTable.EnableControls; dsDataTable.DataTable.FreeBookmark(ABookmark); // dsDataTable.DataTable.EnableEventHandlers; <- No descomentar Screen.Cursor := ACursor; //end; end; end; procedure TfEditorDBBase.actGuardarExecute(Sender: TObject); var dtDetails : TList; i : integer; begin inherited; if Assigned(dsDataTable.DataTable) then begin if dsDataTable.DataTable.Editing then dsDataTable.DataTable.Post; dtDetails := dsDataTable.DataTable.GetDetailDataTables; for i := 0 to dtDetails.Count - 1 do if (TDADataTable(dtDetails.Items[i])).Editing then (TDADataTable(dtDetails.Items[i])).Post; dsDataTable.DataTable.ApplyUpdates; Modified := False; end; end; function TfEditorDBBase.GetModified: Boolean; var dtDetails : TList; i : integer; bCambiado : Boolean; begin bCambiado := False; if Assigned(dsDataTable.DataTable) then begin bCambiado := (dsDataTable.DataTable.State = dsEdit) or DeltaValuesAreDifferent(dsDataTable.DataTable.Delta); if (not bCambiado) then begin dtDetails := dsDataTable.DataTable.GetDetailDataTables; for i := 0 to dtDetails.Count - 1 do begin bCambiado := bCambiado or ((TDADataTable(dtDetails.Items[i])).State = dsEdit) or DeltaValuesAreDifferent((TDADataTable(dtDetails.Items[i])).Delta); if bCambiado then Break; end; end; end; if (not bCambiado) then bCambiado := inherited GetModified; Result := bCambiado; end; procedure TfEditorDBBase.FormCloseQuery(Sender: TObject; var CanClose: Boolean); begin { Para resetear el estado de la tabla en el caso de hacer un insert sin meter ningún dato. } if Assigned(dsDataTable.DataTable) and (not Modified) then dsDataTable.DataTable.Cancel; inherited; end; procedure TfEditorDBBase.actEliminarExecute(Sender: TObject); var aObj : IApplyUpdateFailedException; ACursor: TCursor; begin inherited; ACursor := Screen.Cursor; Screen.Cursor := crHourGlass; try if dsDataTable.DataTable.State in dsEditModes then dsDataTable.DataTable.Cancel; dsDataTable.DataTable.Delete; try dsDataTable.DataTable.ApplyUpdates; Modified := False; except on E: EDAApplyUpdateFailed do begin dsDataTable.DataTable.CancelUpdates; actRefrescar.Execute; if Supports(dsDataTable.DataTable, IApplyUpdateFailedException, aObj) then aObj.ShowApplyUpdateFailed(E); end else raise; // Generic exception end; finally Screen.Cursor := ACursor; end; end; procedure TfEditorDBBase.actEliminarUpdate(Sender: TObject); begin inherited; if Assigned(dsDataTable.DataTable) then (Sender as TAction).Enabled := (not dsDataTable.DataTable.IsEmpty) and not (dsDataTable.DataTable.State = dsInsert) else (Sender as TAction).Enabled := False; end; procedure TfEditorDBBase.actModificarUpdate(Sender: TObject); begin inherited; if Assigned(dsDataTable.DataTable) then (Sender as TAction).Enabled := (not dsDataTable.DataTable.IsEmpty) else (Sender as TAction).Enabled := False; end; procedure TfEditorDBBase.actPrevisualizarUpdate(Sender: TObject); begin inherited; if Assigned(dsDataTable.DataTable) then (Sender as TAction).Enabled := (not dsDataTable.DataTable.IsEmpty) and not (dsDataTable.DataTable.State = dsInsert) else (Sender as TAction).Enabled := False; end; procedure TfEditorDBBase.actImprimirUpdate(Sender: TObject); begin inherited; if Assigned(dsDataTable.DataTable) then (Sender as TAction).Enabled := (not dsDataTable.DataTable.IsEmpty) and not (dsDataTable.DataTable.State = dsInsert) else (Sender as TAction).Enabled := False; end; end.