Arreglado un error que se producía al comprobar si un DataTable sin deltas preparados ha sido modificado.
git-svn-id: https://192.168.0.254/svn/Proyectos.LuisLeon_FactuGES/trunk@199 c93665c3-c93d-084d-9b98-7d5f4a9c3376
This commit is contained in:
parent
72510f75e7
commit
e6e810c371
@ -3,7 +3,7 @@ unit uDataTableUtils;
|
||||
interface
|
||||
|
||||
uses
|
||||
uDACDSDataTable, uDADataTable, uDAInterfaces;
|
||||
uDACDSDataTable, uDADataTable, uDAInterfaces, uDADelta, uDAMemDataTable;
|
||||
|
||||
const
|
||||
ID_NULO = -9000;
|
||||
@ -19,9 +19,19 @@ function SetFieldNull(ATarget: TDADataTable; const FieldName: String): Boolean;
|
||||
procedure ConectarTabla (ATarget: TDADataTable);
|
||||
procedure DesconectarTabla (ATarget: TDADataTable);
|
||||
|
||||
procedure CopyDataTableDA5(ASource : TDADataTable; ATarget: TDADataTable;
|
||||
const OnlySelectedRows : Boolean = False);
|
||||
|
||||
procedure CopyDataTableDA3(ASource : TDADataTable; ATarget : TDADataTable;
|
||||
const OnlySelectedRows : Boolean = False);
|
||||
|
||||
procedure CloneDataTable(const ASource : TDACDSDataTable;
|
||||
var ATarget : TDACDSDataTable;
|
||||
RemoteUpdate: Boolean = True);
|
||||
RemoteUpdate: Boolean = True); overload;
|
||||
|
||||
function CloneDataTable(const ASource : TDAMemDataTable;
|
||||
RemoteUpdate: Boolean = True): TDAMemDataTable; overload;
|
||||
|
||||
|
||||
procedure DuplicarRegistro(ASource : TDADataTable; ATarget : TDADataTable;
|
||||
Const WithKey: Boolean = False);
|
||||
@ -29,9 +39,6 @@ procedure DuplicarRegistros(ASource : TDADataTable; ATarget : TDADataTable;
|
||||
AModo : TModoDuplicarRegistros; APermitirRepetidos: Boolean = True;
|
||||
Const WithDeltas: Boolean = True; Const WithKey: Boolean = False);
|
||||
|
||||
procedure CopyDataTable(ASource : TDADataTable; ATarget : TDADataTable;
|
||||
const OnlySelectedRows : Boolean = False);
|
||||
|
||||
procedure DeleteAllTable(const ADataTable : TDADataTable);
|
||||
|
||||
function DeltaValuesAreDifferent(const aDelta : IDADelta): boolean;
|
||||
@ -48,7 +55,84 @@ implementation
|
||||
|
||||
uses
|
||||
Classes, DB, uDAClasses, SysUtils, uDABINAdapter, uROTypes, cxControls,
|
||||
Dialogs, Variants, uDBSelectionListUtils, uROClasses;
|
||||
Dialogs, Variants, uDBSelectionListUtils, uROClasses, uDADataStreamer, uDABin2DataStreamer;
|
||||
|
||||
|
||||
procedure CopyDataTableDA5(ASource : TDADataTable;
|
||||
ATarget: TDADataTable;
|
||||
const OnlySelectedRows : Boolean);
|
||||
var
|
||||
AStream : Binary;
|
||||
AStream2 : Binary;
|
||||
AFilter : String;
|
||||
AFiltered : Boolean;
|
||||
AObj : ISeleccionable;
|
||||
i : Integer;
|
||||
begin
|
||||
AFilter := '';
|
||||
AFiltered := False;
|
||||
|
||||
if not Assigned(ASource) then
|
||||
raise Exception.Create ('No se ha asignado la tabla de origen (CopyDataTable)');
|
||||
|
||||
if not Assigned(ATarget) then
|
||||
raise Exception.Create ('No se ha asignado la tabla de destino (CopyDataTable)');
|
||||
|
||||
if not ATarget.Active then
|
||||
ATarget.Active := True;
|
||||
|
||||
if OnlySelectedRows then
|
||||
begin
|
||||
if not Supports(ASource, ISeleccionable, aObj) then
|
||||
raise Exception.Create('El origen de datos no soporta la interfaz ISeleccionable (CopyDataTable)');
|
||||
|
||||
if ASource.Filtered then
|
||||
begin
|
||||
AFiltered := True;
|
||||
AFilter := ASource.Filter;
|
||||
ASource.Filtered := False;
|
||||
end;
|
||||
|
||||
ASource.Filter := '';
|
||||
if ASource.Active then
|
||||
ASource.Close;
|
||||
|
||||
for i := 0 to AObj.SelectedRecords.Count - 1 do
|
||||
begin
|
||||
if (i > 0) then
|
||||
ASource.Filter := ASource.Filter + ' or ';
|
||||
ASource.Filter := ASource.Filter + '(ID = ' + IntToStr(AObj.SelectedRecords.Items[i]) + ')';
|
||||
end;
|
||||
|
||||
ASource.Filtered := True;
|
||||
end;
|
||||
|
||||
if not ASource.Active then
|
||||
ASource.Open;
|
||||
|
||||
AStream := Binary.Create;
|
||||
DesconectarTabla(ATarget);
|
||||
try
|
||||
ASource.SaveToStream(AStream);
|
||||
AStream2 := AStream.Clone;
|
||||
|
||||
// ShowMessage(AStream.ToReadableString);
|
||||
ATarget.LoadFromStream(AStream2); ///->>>>>>>>>>>>>>>>>>>>>>>>>>ERRORRRR
|
||||
finally
|
||||
FreeAndNil(AStream);
|
||||
ConectarTabla(ATarget);
|
||||
// Dejar el filtro de la tabla origen como estaba
|
||||
if OnlySelectedRows then
|
||||
begin
|
||||
ASource.Filtered := False;
|
||||
ASource.Filter := AFilter;
|
||||
if AFiltered then
|
||||
ASource.Filtered := True;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
|
||||
function SetFieldNull(ATarget: TDADataTable; const FieldName: String): Boolean;
|
||||
begin
|
||||
@ -101,10 +185,11 @@ var
|
||||
i : integer;
|
||||
begin
|
||||
bCambiado := False;
|
||||
|
||||
if Assigned(ADataTable) and (ADataTable.Active) then
|
||||
begin
|
||||
bCambiado := (ADataTable.State = dsEdit) or
|
||||
DeltaValuesAreDifferent(ADataTable.Delta);
|
||||
bCambiado :=(ADataTable.State = dsEdit) or
|
||||
(ADataTable.HasDelta and DeltaValuesAreDifferent(ADataTable.Delta));
|
||||
|
||||
if (not bCambiado) then
|
||||
begin
|
||||
@ -113,7 +198,8 @@ begin
|
||||
begin
|
||||
bCambiado := bCambiado or
|
||||
((TDADataTable(dtDetails.Items[i])).State in dsEditModes) or
|
||||
DeltaValuesAreDifferent((TDADataTable(dtDetails.Items[i])).Delta);
|
||||
((TDADataTable(dtDetails.Items[i])).HasDelta and
|
||||
DeltaValuesAreDifferent((TDADataTable(dtDetails.Items[i])).Delta));
|
||||
if bCambiado then
|
||||
Break;
|
||||
end;
|
||||
@ -128,6 +214,81 @@ begin
|
||||
ADataTable.ClearRows;
|
||||
end;
|
||||
|
||||
|
||||
function CloneDataTable(const ASource : TDAMemDataTable;
|
||||
RemoteUpdate: Boolean = True): TDAMemDataTable;
|
||||
var
|
||||
i : Integer;
|
||||
ATarget : TDAMemDataTable;
|
||||
begin
|
||||
if not Assigned(ASource) then
|
||||
raise Exception.Create ('No se ha asignado la tabla de origen (CloneDataTable)');
|
||||
|
||||
ATarget := TDAMemDataTable.Create(NIL);
|
||||
with ATarget do
|
||||
begin
|
||||
|
||||
{ ATENCIÓN !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
--------------------------------------------------------------------
|
||||
DA5 tiene un fallo en el cual las tablas definidas como detalle no
|
||||
tienen asociados los eventos internos before... y after... por lo
|
||||
que los campos AutoInc no funcionan (no pone el -1, -2...).
|
||||
La forma de arreglarlo es llamar a DisableEventHandlers/EnableEventHandlers
|
||||
que realiza la asociación de los eventos.
|
||||
}
|
||||
ATarget.DisableEventHandlers; // <--- INDISPENSABLE!!!!!!!!!!!!!!!!!!!!
|
||||
|
||||
|
||||
try
|
||||
if not Assigned(ASource.RemoteDataAdapter) then
|
||||
raise Exception.Create('No está asignado RemoteDataAdapter (' + ASource.Name + ')');
|
||||
|
||||
LogicalName := ASource.LogicalName;
|
||||
CustomAttributes.Assign(ASource.CustomAttributes);
|
||||
Fields.AssignFieldCollection(ASource.Fields); // o también ATarget.LoadSchema;
|
||||
Params.AssignParamCollection(ASource.Params);
|
||||
|
||||
RemoteDataAdapter := ASource.RemoteDataAdapter;
|
||||
|
||||
Randomize;
|
||||
Name := ASource.Name + '_' + IntToStr(Random(MAXINT));
|
||||
|
||||
BusinessRulesID := ASource.BusinessRulesID;
|
||||
|
||||
with MasterParamsMappings do
|
||||
for i := 0 to ASource.MasterParamsMappings.Count - 1 do
|
||||
Add(ASource.MasterParamsMappings.Strings[i]);
|
||||
|
||||
with MasterRequestMappings do
|
||||
for i := 0 to ASource.MasterRequestMappings.Count - 1 do
|
||||
Add(ASource.MasterRequestMappings.Strings[i]);
|
||||
|
||||
MasterMappingMode := ASource.MasterMappingMode;
|
||||
|
||||
MasterFields := ASource.MasterFields;
|
||||
MasterOptions := ASource.MasterOptions;
|
||||
|
||||
DetailFields := ASource.DetailFields;
|
||||
DetailOptions := ASource.DetailOptions;
|
||||
|
||||
RemoteUpdatesOptions := ASource.RemoteUpdatesOptions;
|
||||
StreamingOptions := ASource.StreamingOptions;
|
||||
RemoteFetchEnabled := ASource.RemoteFetchEnabled;
|
||||
finally
|
||||
ATarget.EnableEventHandlers; // <--- INDISPENSABLE!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
end;
|
||||
end;
|
||||
|
||||
if not RemoteUpdate then
|
||||
begin
|
||||
ATarget.LogChanges := False;
|
||||
ATarget.RemoteFetchEnabled := False;
|
||||
end;
|
||||
|
||||
Result := ATarget;
|
||||
end;
|
||||
|
||||
|
||||
procedure CloneDataTable(const ASource : TDACDSDataTable;
|
||||
var ATarget : TDACDSDataTable; RemoteUpdate: Boolean);
|
||||
var
|
||||
@ -135,10 +296,17 @@ var
|
||||
begin
|
||||
with ATarget do
|
||||
begin
|
||||
RemoteService := ASource.GetRemoteService;
|
||||
Adapter := ASource.GetAdapter;
|
||||
// ****** Inicio migración DA 5
|
||||
{RemoteService := ASource.GetRemoteService;
|
||||
Adapter := ASource.GetAdapter;}
|
||||
|
||||
//BusinessRulesID := ASource.BusinessRulesID;
|
||||
if not Assigned(ASource.RemoteDataAdapter) then
|
||||
raise Exception.Create('No está asignado RemoteDataAdapter (' + ASource.Name + ')');
|
||||
|
||||
RemoteDataAdapter.Assign(ASource.RemoteDataAdapter);
|
||||
// ****** Fin migración DA 5
|
||||
|
||||
BusinessRulesID := ASource.BusinessRulesID;
|
||||
Randomize;
|
||||
Name := ASource.Name + '_' + IntToStr(Random(MAXINT));
|
||||
LogicalName := ASource.LogicalName;
|
||||
@ -148,6 +316,8 @@ begin
|
||||
if Assigned(ASource.LocalSchema) then
|
||||
LocalSchema := ASource.LocalSchema
|
||||
else begin
|
||||
// ****** Inicio migración DA 5
|
||||
{
|
||||
with SchemaCall do
|
||||
begin
|
||||
MethodName := ASource.SchemaCall.MethodName;
|
||||
@ -162,9 +332,13 @@ begin
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
}
|
||||
// ****** Fin migración DA 5
|
||||
ATarget.Fields.AssignFieldCollection(ASource.Fields); // o también ATarget.LoadSchema;
|
||||
end;
|
||||
|
||||
// ****** Inicio migración DA 5
|
||||
{
|
||||
with DataUpdateCall do
|
||||
begin
|
||||
MethodName := ASource.DataUpdateCall.MethodName;
|
||||
@ -211,6 +385,8 @@ begin
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
}
|
||||
// ****** Fin migración DA 5
|
||||
|
||||
with MasterParamsMappings do
|
||||
for i := 0 to ASource.MasterParamsMappings.Count - 1 do
|
||||
@ -239,7 +415,6 @@ begin
|
||||
ATarget.RemoteFetchEnabled := False;
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
function DeltaValuesAreDifferent(const aDelta : IDADelta): boolean;
|
||||
var
|
||||
@ -251,16 +426,7 @@ begin
|
||||
begin
|
||||
for x := 0 to (aDelta.LoggedFieldCount-1) do
|
||||
begin
|
||||
if aDelta.LoggedFieldTypes[x] <> datBlob then
|
||||
begin
|
||||
try
|
||||
OldNewAreDifferent := (aDelta.Changes[i].OldValues[x] <> aDelta.Changes[i].NewValues[x]);
|
||||
except
|
||||
// Capturar cualquier tipo de excepción de conversión de tipos
|
||||
on E: EVariantTypeCastError do
|
||||
OldNewAreDifferent := True;
|
||||
end;
|
||||
end;
|
||||
OldNewAreDifferent := (aDelta.Changes[i].OldValues[x] <> aDelta.Changes[i].NewValues[x]);
|
||||
|
||||
if OldNewAreDifferent then
|
||||
Break; // Abandon iteration at the first difference between old and new.
|
||||
@ -273,7 +439,7 @@ begin
|
||||
end;
|
||||
|
||||
|
||||
procedure CopyDataTable(ASource : TDADataTable; ATarget : TDADataTable;
|
||||
procedure CopyDataTableDA3(ASource : TDADataTable; ATarget : TDADataTable;
|
||||
const OnlySelectedRows : Boolean = False);
|
||||
var
|
||||
DABin: Binary;
|
||||
@ -314,6 +480,7 @@ begin
|
||||
|
||||
DABin := Binary.Create;
|
||||
DAAdapter := TDABINAdapter.Create(nil);
|
||||
|
||||
try
|
||||
ATarget.LogicalName := ASource.LogicalName; // We need to specify new dataset LogicalName
|
||||
ATarget.RemoteFetchEnabled := False; // "Desconectamos" la tabla destino del servidor
|
||||
@ -322,12 +489,11 @@ begin
|
||||
ASource.Open;
|
||||
ASource.First;
|
||||
|
||||
DAAdapter.Initialize(DABin, aiWrite);
|
||||
DAAdapter.WriteDataset(DABin, ASource, [woRows]);
|
||||
DAAdapter.Initialize(DABin, aiReadFromBeginning);
|
||||
DAAdapter.ReadDataset(DABin, ATarget);
|
||||
DAAdapter.Finalize;
|
||||
|
||||
|
||||
ATarget.RemoteFetchEnabled := True; // "Conectamos" la tabla del servidor otra vez
|
||||
|
||||
// Dejar el filtro de la tabla origen como estaba
|
||||
@ -461,14 +627,14 @@ begin
|
||||
if Assigned(ADetail) then
|
||||
begin
|
||||
// ¡¡¡¡¡ MUY IMPORTANTE !!!!!!!!!!!!!!!!!!
|
||||
ADetail.DataTable.DisableEventHandlers;
|
||||
//ADetail.DataTable.DisableEventHandlers;
|
||||
try
|
||||
ADetail.DataTable.MasterSource := AMasterDataSource;
|
||||
finally
|
||||
{ Hay que activar los eventos porque dejan de funcionar
|
||||
las reglas de negocio al establecer la relación
|
||||
maestro-detalle. (Fallo de Data Abstract 3) }
|
||||
ADetail.DataTable.EnableEventHandlers;
|
||||
//ADetail.DataTable.EnableEventHandlers;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
@ -501,5 +667,4 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
end.
|
||||
|
||||
Reference in New Issue
Block a user