2007-09-12 14:11:44 +00:00
|
|
|
|
unit uDataTableUtils;
|
|
|
|
|
|
|
|
|
|
|
|
interface
|
|
|
|
|
|
|
|
|
|
|
|
uses
|
2007-09-19 16:38:24 +00:00
|
|
|
|
uDACDSDataTable, uDADataTable, uDAInterfaces, uDADelta, uDAMemDataTable;
|
2007-09-12 14:11:44 +00:00
|
|
|
|
|
|
|
|
|
|
const
|
|
|
|
|
|
ID_NULO = -9000;
|
|
|
|
|
|
ID_TODOS = -9001;
|
|
|
|
|
|
ID_PRIMERO = -9002;
|
|
|
|
|
|
|
|
|
|
|
|
type
|
|
|
|
|
|
|
|
|
|
|
|
TModoDuplicarRegistros = (mdrTodos, mdrActual, mdrSeleccionados);
|
|
|
|
|
|
|
|
|
|
|
|
function SetFieldNull(ATarget: TDADataTable; const FieldName: String): Boolean;
|
|
|
|
|
|
|
|
|
|
|
|
procedure ConectarTabla (ATarget: TDADataTable);
|
|
|
|
|
|
procedure DesconectarTabla (ATarget: TDADataTable);
|
|
|
|
|
|
|
2007-11-15 12:55:13 +00:00
|
|
|
|
procedure CopyDataTableDA5(ASource : TDADataTable; ATarget: TDADataTable;
|
2007-10-03 10:27:58 +00:00
|
|
|
|
const OnlySelectedRows : Boolean = False);
|
|
|
|
|
|
|
2007-09-12 14:11:44 +00:00
|
|
|
|
procedure CloneDataTable(const ASource : TDACDSDataTable;
|
|
|
|
|
|
var ATarget : TDACDSDataTable;
|
2007-09-19 16:38:24 +00:00
|
|
|
|
RemoteUpdate: Boolean = True); overload;
|
|
|
|
|
|
|
|
|
|
|
|
function CloneDataTable(const ASource : TDAMemDataTable;
|
|
|
|
|
|
RemoteUpdate: Boolean = True): TDAMemDataTable; overload;
|
|
|
|
|
|
|
2007-09-12 14:11:44 +00:00
|
|
|
|
|
|
|
|
|
|
procedure DuplicarRegistro(ASource : TDADataTable; ATarget : TDADataTable;
|
2008-05-26 16:59:17 +00:00
|
|
|
|
Const WithPKKey: Boolean = False; Const WithFKKey: Boolean = False);
|
2007-09-12 14:11:44 +00:00
|
|
|
|
procedure DuplicarRegistros(ASource : TDADataTable; ATarget : TDADataTable;
|
|
|
|
|
|
AModo : TModoDuplicarRegistros; APermitirRepetidos: Boolean = True;
|
2008-05-26 16:59:17 +00:00
|
|
|
|
Const WithDeltas: Boolean = True; Const WithPKKey: Boolean = False; Const WithFKKey: Boolean = False);
|
2007-09-12 14:11:44 +00:00
|
|
|
|
|
|
|
|
|
|
procedure DeleteAllTable(const ADataTable : TDADataTable);
|
|
|
|
|
|
|
|
|
|
|
|
function DeltaValuesAreDifferent(const aDelta : IDADelta): boolean;
|
|
|
|
|
|
|
|
|
|
|
|
procedure EnlazarMaestroDetalle(AMasterDataSource : TDADataSource;
|
|
|
|
|
|
ADetail : IDAStronglyTypedDataTable);
|
|
|
|
|
|
|
|
|
|
|
|
function DataTableModified (const ADataTable : TDADataTable): Boolean;
|
|
|
|
|
|
|
|
|
|
|
|
procedure SetDataTableReadOnly(ADataTable: TDADataTable; const value: Boolean);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
implementation
|
|
|
|
|
|
|
|
|
|
|
|
uses
|
|
|
|
|
|
Classes, DB, uDAClasses, SysUtils, uDABINAdapter, uROTypes, cxControls,
|
2007-10-26 18:07:10 +00:00
|
|
|
|
Dialogs, Variants, uDBSelectionListUtils, uROClasses, uDADataStreamer, uDABin2DataStreamer;
|
2007-09-12 14:11:44 +00:00
|
|
|
|
|
2007-10-03 10:27:58 +00:00
|
|
|
|
|
2008-05-21 14:54:00 +00:00
|
|
|
|
procedure CopyDataTableDA5(ASource : TDADataTable; ATarget: TDADataTable;
|
|
|
|
|
|
const OnlySelectedRows : Boolean = False);
|
2007-10-03 10:27:58 +00:00
|
|
|
|
var
|
2008-05-21 14:54:00 +00:00
|
|
|
|
DABin: Binary;
|
|
|
|
|
|
DADataStreamer : TDABin2DataStreamer;
|
2007-10-03 10:27:58 +00:00
|
|
|
|
AFiltered : Boolean;
|
2008-07-31 18:11:26 +00:00
|
|
|
|
AFilter : String;
|
2007-10-03 10:27:58 +00:00
|
|
|
|
AObj : ISeleccionable;
|
|
|
|
|
|
i : Integer;
|
|
|
|
|
|
begin
|
|
|
|
|
|
AFilter := '';
|
|
|
|
|
|
AFiltered := False;
|
|
|
|
|
|
|
|
|
|
|
|
if OnlySelectedRows then
|
|
|
|
|
|
begin
|
|
|
|
|
|
if not Supports(ASource, ISeleccionable, aObj) then
|
|
|
|
|
|
raise Exception.Create('El origen de datos no soporta la interfaz ISeleccionable (CopyDataTable)');
|
|
|
|
|
|
|
2008-07-31 18:11:26 +00:00
|
|
|
|
{ Si la tabla est<EFBFBD> abierta, la cerramos antes de aplicar los filtros
|
|
|
|
|
|
porque por cada cambio en el filtro se hacen llamadas internas de TDADataTable. }
|
|
|
|
|
|
if ASource.Active then
|
|
|
|
|
|
ASource.Close;
|
|
|
|
|
|
|
|
|
|
|
|
// Si la tabla origen viene con un filtro, lo guardamos para luego restablecerlo.
|
2007-10-03 10:27:58 +00:00
|
|
|
|
if ASource.Filtered then
|
|
|
|
|
|
begin
|
|
|
|
|
|
AFiltered := True;
|
|
|
|
|
|
AFilter := ASource.Filter;
|
|
|
|
|
|
ASource.Filtered := False;
|
|
|
|
|
|
end;
|
|
|
|
|
|
|
|
|
|
|
|
ASource.Filter := '';
|
|
|
|
|
|
|
2008-05-28 17:53:12 +00:00
|
|
|
|
//Si no hay elemento seleccionados filtramos para que ATarget se quede vacia
|
|
|
|
|
|
if (AObj.SelectedRecords.Count = 0) then
|
2008-07-31 18:11:26 +00:00
|
|
|
|
ASource.Filter := ASource.Filter + '(' + ASource.RecIDField.FieldName + ' = ' + IntToStr(ID_NULO) + ')'
|
|
|
|
|
|
|
2008-05-28 17:53:12 +00:00
|
|
|
|
//En caso contrario filtramos por los elementos seleccionados
|
|
|
|
|
|
else
|
|
|
|
|
|
for i := 0 to AObj.SelectedRecords.Count - 1 do
|
|
|
|
|
|
begin
|
|
|
|
|
|
if (i > 0) then
|
|
|
|
|
|
ASource.Filter := ASource.Filter + ' or ';
|
2008-07-31 18:11:26 +00:00
|
|
|
|
ASource.Filter := ASource.Filter + '(' + ASource.RecIDField.FieldName + ' = ' + IntToStr(AObj.SelectedRecords.Items[i]) + ')';
|
2008-05-28 17:53:12 +00:00
|
|
|
|
end;
|
2007-10-03 10:27:58 +00:00
|
|
|
|
ASource.Filtered := True;
|
|
|
|
|
|
end;
|
|
|
|
|
|
|
2008-05-21 14:54:00 +00:00
|
|
|
|
DABin := Binary.Create;
|
|
|
|
|
|
DADataStreamer := TDABin2DataStreamer.Create(nil);
|
2007-10-03 10:27:58 +00:00
|
|
|
|
|
2008-05-21 14:54:00 +00:00
|
|
|
|
ShowHourglassCursor;
|
|
|
|
|
|
ASource.DisableControls;
|
|
|
|
|
|
ATarget.DisableControls;
|
2007-10-03 10:27:58 +00:00
|
|
|
|
try
|
2008-05-21 14:54:00 +00:00
|
|
|
|
ATarget.LogicalName := ASource.LogicalName; // We need to specify new dataset LogicalName
|
|
|
|
|
|
ATarget.RemoteFetchEnabled := False; // "Desconectamos" la tabla destino del servidor
|
|
|
|
|
|
|
2008-07-31 18:11:26 +00:00
|
|
|
|
if not ASource.Active then
|
|
|
|
|
|
ASource.Open;
|
|
|
|
|
|
|
2008-05-21 14:54:00 +00:00
|
|
|
|
ASource.First;
|
|
|
|
|
|
|
|
|
|
|
|
DADataStreamer.WriteDataset(DABin, ASource, [woRows, woSchema], -1);
|
|
|
|
|
|
DADataStreamer.ReadDataset(DABin, ATarget, True);
|
|
|
|
|
|
DADataStreamer.Finalize;
|
|
|
|
|
|
|
|
|
|
|
|
ATarget.RemoteFetchEnabled := True; // "Conectamos" la tabla del servidor otra vez
|
2007-11-15 12:55:13 +00:00
|
|
|
|
|
2007-10-03 10:27:58 +00:00
|
|
|
|
// 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;
|
2008-05-21 14:54:00 +00:00
|
|
|
|
|
|
|
|
|
|
finally
|
|
|
|
|
|
FreeAndNil(DABin);
|
|
|
|
|
|
FreeAndNil(DADataStreamer);
|
|
|
|
|
|
ASource.EnableControls;
|
|
|
|
|
|
ATarget.EnableControls;
|
|
|
|
|
|
HideHourglassCursor;
|
2007-10-03 10:27:58 +00:00
|
|
|
|
end;
|
|
|
|
|
|
end;
|
|
|
|
|
|
|
|
|
|
|
|
|
2007-09-12 14:11:44 +00:00
|
|
|
|
function SetFieldNull(ATarget: TDADataTable; const FieldName: String): Boolean;
|
|
|
|
|
|
begin
|
|
|
|
|
|
Result := False;
|
|
|
|
|
|
if Assigned(ATarget) then
|
|
|
|
|
|
begin
|
|
|
|
|
|
try
|
|
|
|
|
|
ATarget.FieldByName(FieldName).AsVariant := Null;
|
|
|
|
|
|
Result := True;
|
|
|
|
|
|
except
|
|
|
|
|
|
on E: Exception do
|
|
|
|
|
|
Result := False;
|
|
|
|
|
|
end;
|
|
|
|
|
|
end;
|
|
|
|
|
|
end;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function DataTableModified (const ADataTable : TDADataTable): Boolean;
|
|
|
|
|
|
var
|
|
|
|
|
|
bCambiado : Boolean;
|
|
|
|
|
|
dtDetails : TList;
|
|
|
|
|
|
i : integer;
|
|
|
|
|
|
begin
|
|
|
|
|
|
bCambiado := False;
|
2007-12-12 20:02:04 +00:00
|
|
|
|
|
2007-09-12 14:11:44 +00:00
|
|
|
|
if Assigned(ADataTable) and (ADataTable.Active) then
|
|
|
|
|
|
begin
|
2007-12-12 20:02:04 +00:00
|
|
|
|
bCambiado :=(ADataTable.State = dsEdit) or
|
|
|
|
|
|
(ADataTable.HasDelta and DeltaValuesAreDifferent(ADataTable.Delta));
|
2007-09-12 14:11:44 +00:00
|
|
|
|
|
|
|
|
|
|
if (not bCambiado) then
|
|
|
|
|
|
begin
|
|
|
|
|
|
dtDetails := ADataTable.GetDetailDataTables;
|
|
|
|
|
|
for i := 0 to dtDetails.Count - 1 do
|
|
|
|
|
|
begin
|
|
|
|
|
|
bCambiado := bCambiado or
|
|
|
|
|
|
((TDADataTable(dtDetails.Items[i])).State in dsEditModes) or
|
2007-12-12 20:02:04 +00:00
|
|
|
|
((TDADataTable(dtDetails.Items[i])).HasDelta and
|
|
|
|
|
|
DeltaValuesAreDifferent((TDADataTable(dtDetails.Items[i])).Delta));
|
2007-09-12 14:11:44 +00:00
|
|
|
|
if bCambiado then
|
|
|
|
|
|
Break;
|
|
|
|
|
|
end;
|
|
|
|
|
|
end;
|
|
|
|
|
|
end;
|
|
|
|
|
|
Result := bCambiado;
|
|
|
|
|
|
end;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
procedure DeleteAllTable(const ADataTable : TDADataTable);
|
|
|
|
|
|
begin
|
|
|
|
|
|
ADataTable.ClearRows;
|
|
|
|
|
|
end;
|
|
|
|
|
|
|
2007-09-19 16:38:24 +00:00
|
|
|
|
|
|
|
|
|
|
function CloneDataTable(const ASource : TDAMemDataTable;
|
2007-11-08 20:58:47 +00:00
|
|
|
|
RemoteUpdate: Boolean = True): TDAMemDataTable;
|
2007-09-19 16:38:24 +00:00
|
|
|
|
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
|
|
|
|
|
|
|
2007-11-08 20:58:47 +00:00
|
|
|
|
{ ATENCI<EFBFBD>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<EFBFBD>n de los eventos.
|
|
|
|
|
|
}
|
|
|
|
|
|
ATarget.DisableEventHandlers; // <--- INDISPENSABLE!!!!!!!!!!!!!!!!!!!!
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
try
|
|
|
|
|
|
if not Assigned(ASource.RemoteDataAdapter) then
|
|
|
|
|
|
raise Exception.Create('No est<73> asignado RemoteDataAdapter (' + ASource.Name + ')');
|
|
|
|
|
|
|
|
|
|
|
|
LogicalName := ASource.LogicalName;
|
|
|
|
|
|
CustomAttributes.Assign(ASource.CustomAttributes);
|
|
|
|
|
|
Fields.AssignFieldCollection(ASource.Fields); // o tambi<62>n ATarget.LoadSchema;
|
|
|
|
|
|
Params.AssignParamCollection(ASource.Params);
|
2007-09-19 16:38:24 +00:00
|
|
|
|
|
2007-11-08 20:58:47 +00:00
|
|
|
|
RemoteDataAdapter := ASource.RemoteDataAdapter;
|
2007-09-19 16:38:24 +00:00
|
|
|
|
|
2007-11-08 20:58:47 +00:00
|
|
|
|
Randomize;
|
|
|
|
|
|
Name := ASource.Name + '_' + IntToStr(Random(MAXINT));
|
2007-09-19 16:38:24 +00:00
|
|
|
|
|
2007-11-08 20:58:47 +00:00
|
|
|
|
BusinessRulesID := ASource.BusinessRulesID;
|
2007-09-19 16:38:24 +00:00
|
|
|
|
|
2007-11-08 20:58:47 +00:00
|
|
|
|
with MasterParamsMappings do
|
|
|
|
|
|
for i := 0 to ASource.MasterParamsMappings.Count - 1 do
|
|
|
|
|
|
Add(ASource.MasterParamsMappings.Strings[i]);
|
2007-09-19 16:38:24 +00:00
|
|
|
|
|
2007-11-08 20:58:47 +00:00
|
|
|
|
with MasterRequestMappings do
|
|
|
|
|
|
for i := 0 to ASource.MasterRequestMappings.Count - 1 do
|
|
|
|
|
|
Add(ASource.MasterRequestMappings.Strings[i]);
|
2007-09-19 16:38:24 +00:00
|
|
|
|
|
2007-11-08 20:58:47 +00:00
|
|
|
|
MasterMappingMode := ASource.MasterMappingMode;
|
2007-09-19 16:38:24 +00:00
|
|
|
|
|
2007-11-08 20:58:47 +00:00
|
|
|
|
MasterFields := ASource.MasterFields;
|
|
|
|
|
|
MasterOptions := ASource.MasterOptions;
|
2007-09-19 16:38:24 +00:00
|
|
|
|
|
2007-11-08 20:58:47 +00:00
|
|
|
|
DetailFields := ASource.DetailFields;
|
|
|
|
|
|
DetailOptions := ASource.DetailOptions;
|
2007-09-19 16:38:24 +00:00
|
|
|
|
|
2007-11-08 20:58:47 +00:00
|
|
|
|
RemoteUpdatesOptions := ASource.RemoteUpdatesOptions;
|
|
|
|
|
|
StreamingOptions := ASource.StreamingOptions;
|
|
|
|
|
|
RemoteFetchEnabled := ASource.RemoteFetchEnabled;
|
|
|
|
|
|
finally
|
|
|
|
|
|
ATarget.EnableEventHandlers; // <--- INDISPENSABLE!!!!!!!!!!!!!!!!!!!!!!!!!
|
|
|
|
|
|
end;
|
2007-09-19 16:38:24 +00:00
|
|
|
|
end;
|
|
|
|
|
|
|
|
|
|
|
|
if not RemoteUpdate then
|
|
|
|
|
|
begin
|
|
|
|
|
|
ATarget.LogChanges := False;
|
|
|
|
|
|
ATarget.RemoteFetchEnabled := False;
|
|
|
|
|
|
end;
|
|
|
|
|
|
|
|
|
|
|
|
Result := ATarget;
|
|
|
|
|
|
end;
|
|
|
|
|
|
|
|
|
|
|
|
|
2007-09-12 14:11:44 +00:00
|
|
|
|
procedure CloneDataTable(const ASource : TDACDSDataTable;
|
|
|
|
|
|
var ATarget : TDACDSDataTable; RemoteUpdate: Boolean);
|
|
|
|
|
|
var
|
|
|
|
|
|
i : Integer;
|
|
|
|
|
|
begin
|
|
|
|
|
|
with ATarget do
|
|
|
|
|
|
begin
|
2007-09-19 16:38:24 +00:00
|
|
|
|
|
|
|
|
|
|
if not Assigned(ASource.RemoteDataAdapter) then
|
|
|
|
|
|
raise Exception.Create('No est<73> asignado RemoteDataAdapter (' + ASource.Name + ')');
|
|
|
|
|
|
|
2007-09-12 14:11:44 +00:00
|
|
|
|
RemoteDataAdapter.Assign(ASource.RemoteDataAdapter);
|
|
|
|
|
|
|
|
|
|
|
|
BusinessRulesID := ASource.BusinessRulesID;
|
|
|
|
|
|
Randomize;
|
|
|
|
|
|
Name := ASource.Name + '_' + IntToStr(Random(MAXINT));
|
|
|
|
|
|
LogicalName := ASource.LogicalName;
|
|
|
|
|
|
|
|
|
|
|
|
Params.AssignParamCollection(ASource.Params);
|
|
|
|
|
|
|
|
|
|
|
|
if Assigned(ASource.LocalSchema) then
|
|
|
|
|
|
LocalSchema := ASource.LocalSchema
|
|
|
|
|
|
else begin
|
|
|
|
|
|
ATarget.Fields.AssignFieldCollection(ASource.Fields); // o tambi<62>n ATarget.LoadSchema;
|
|
|
|
|
|
end;
|
|
|
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
|
end;
|
|
|
|
|
|
|
|
|
|
|
|
if not RemoteUpdate then
|
|
|
|
|
|
begin
|
|
|
|
|
|
ATarget.LogChanges := False;
|
|
|
|
|
|
ATarget.RemoteFetchEnabled := False;
|
|
|
|
|
|
end;
|
|
|
|
|
|
end;
|
2007-09-19 16:38:24 +00:00
|
|
|
|
|
2007-09-12 14:11:44 +00:00
|
|
|
|
function DeltaValuesAreDifferent(const aDelta : IDADelta): boolean;
|
|
|
|
|
|
var
|
|
|
|
|
|
i, x : integer;
|
|
|
|
|
|
OldNewAreDifferent: boolean;
|
|
|
|
|
|
begin
|
|
|
|
|
|
OldNewAreDifferent := FALSE;
|
|
|
|
|
|
for i := 0 to (aDelta.Count-1) do
|
|
|
|
|
|
begin
|
|
|
|
|
|
for x := 0 to (aDelta.LoggedFieldCount-1) do
|
|
|
|
|
|
begin
|
|
|
|
|
|
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.
|
|
|
|
|
|
end;
|
|
|
|
|
|
|
|
|
|
|
|
if OldNewAreDifferent then
|
|
|
|
|
|
Break; // Abandon iteration at the first difference between old and new.
|
|
|
|
|
|
end;
|
|
|
|
|
|
result := OldNewAreDifferent;
|
|
|
|
|
|
end;
|
|
|
|
|
|
|
|
|
|
|
|
|
2008-05-26 16:59:17 +00:00
|
|
|
|
procedure DuplicarRegistro(ASource : TDADataTable; ATarget : TDADataTable; Const WithPKKey: Boolean = False; Const WithFKKey: Boolean = False);
|
2007-09-12 14:11:44 +00:00
|
|
|
|
var
|
|
|
|
|
|
i, j: Integer;
|
|
|
|
|
|
ATargetField: TDAField;
|
|
|
|
|
|
ASourceField: TDAField;
|
|
|
|
|
|
ADetailFields : TStringList;
|
|
|
|
|
|
begin
|
|
|
|
|
|
if not ASource.Active then
|
|
|
|
|
|
ASource.Open;
|
|
|
|
|
|
|
|
|
|
|
|
if not ATarget.Active then
|
|
|
|
|
|
ATarget.Open;
|
|
|
|
|
|
|
2008-05-14 14:38:09 +00:00
|
|
|
|
ADetailFields := Nil;
|
|
|
|
|
|
|
2007-09-12 14:11:44 +00:00
|
|
|
|
// <20>ATarget es una tabla detalle?
|
|
|
|
|
|
if Assigned(ATarget.MasterSource) then
|
|
|
|
|
|
begin
|
|
|
|
|
|
case ATarget.MasterMappingMode of
|
|
|
|
|
|
//mmDataRequest: //Sin hacer;
|
2008-01-04 17:14:30 +00:00
|
|
|
|
mmParams, mmWhere: begin
|
2007-09-12 14:11:44 +00:00
|
|
|
|
//Creamos la lista de campos foreing key
|
|
|
|
|
|
ADetailFields := TStringList.Create;
|
|
|
|
|
|
ADetailFields.Sorted := True;
|
|
|
|
|
|
ADetailFields.Delimiter := ',';
|
|
|
|
|
|
ADetailFields.Duplicates := dupIgnore;
|
|
|
|
|
|
ADetailFields.Add(ATarget.DetailFields);
|
|
|
|
|
|
end;
|
|
|
|
|
|
end;
|
|
|
|
|
|
end
|
|
|
|
|
|
else
|
|
|
|
|
|
ADetailFields := Nil;
|
|
|
|
|
|
|
|
|
|
|
|
ATarget.Insert;
|
|
|
|
|
|
{ Hay que desactivar los eventos para que dejan de funcionar
|
|
|
|
|
|
las reglas de negocio y no nos interfieran en la copia
|
|
|
|
|
|
de valores de los campos. }
|
|
|
|
|
|
ATarget.DisableEventHandlers;
|
|
|
|
|
|
try
|
|
|
|
|
|
for i := 0 to ASource.Fields.Count - 1 do
|
|
|
|
|
|
begin
|
|
|
|
|
|
ASourceField := ASource.Fields[i];
|
|
|
|
|
|
ATargetField := ATarget.FindField(ASourceField.Name);
|
|
|
|
|
|
|
|
|
|
|
|
if Assigned(ATargetField) then
|
|
|
|
|
|
begin
|
|
|
|
|
|
// Los campos AutoInc no se rellenan y tampoco los campos que
|
|
|
|
|
|
// formen parte de la relaci<63>n maestro-detalle en el
|
|
|
|
|
|
// caso de que la tabla destino sea una tabla detalle.
|
2008-05-26 16:59:17 +00:00
|
|
|
|
if not WithPKKey then
|
2007-09-12 14:11:44 +00:00
|
|
|
|
begin
|
|
|
|
|
|
//Si no es campo clave
|
|
|
|
|
|
//Si no es autoinc (podria desaparecer pero no lo quitamos por si acaso
|
2008-05-26 16:59:17 +00:00
|
|
|
|
if not (ATargetField.InPrimaryKey) and
|
|
|
|
|
|
(ATargetField.DataType <> datAutoInc) then
|
|
|
|
|
|
begin
|
|
|
|
|
|
//En el caso de no copiar las claves foraneas
|
|
|
|
|
|
//Si no hay campos foreing key o los hay pero el campo a copiar no es uno de ellos
|
|
|
|
|
|
if not WithFKKey then
|
|
|
|
|
|
begin
|
|
|
|
|
|
if (not Assigned(ADetailFields) or not ADetailFields.Find(ATargetField.Name, j)) then
|
|
|
|
|
|
//Copiamos el campo
|
|
|
|
|
|
ATargetField.Value := ASourceField.Value;
|
|
|
|
|
|
end
|
|
|
|
|
|
else
|
|
|
|
|
|
//Copiamos el campo
|
|
|
|
|
|
ATargetField.Value := ASourceField.Value;
|
|
|
|
|
|
|
|
|
|
|
|
end;
|
2007-09-12 14:11:44 +00:00
|
|
|
|
end
|
|
|
|
|
|
else
|
2008-05-26 16:59:17 +00:00
|
|
|
|
//En el caso de no copiar las claves foraneas
|
|
|
|
|
|
//Si no hay campos foreing key o los hay pero el campo a copiar no es uno de ellos
|
|
|
|
|
|
if not WithFKKey then
|
|
|
|
|
|
begin
|
|
|
|
|
|
//Si no hay campos foreing key o los hay pero el campo a copiar no es uno de ellos
|
|
|
|
|
|
if (not Assigned(ADetailFields) or not ADetailFields.Find(ATargetField.Name, j)) then
|
|
|
|
|
|
//Copiamos el campo
|
|
|
|
|
|
ATargetField.Value := ASourceField.Value;
|
|
|
|
|
|
end
|
|
|
|
|
|
else
|
|
|
|
|
|
//Copiamos el campo
|
|
|
|
|
|
ATargetField.Value := ASourceField.Value;
|
2007-09-12 14:11:44 +00:00
|
|
|
|
end;
|
|
|
|
|
|
end;
|
|
|
|
|
|
finally
|
|
|
|
|
|
ATarget.EnableEventHandlers;
|
|
|
|
|
|
ATarget.Post;
|
|
|
|
|
|
end;
|
|
|
|
|
|
end;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
procedure DuplicarRegistros(ASource : TDADataTable; ATarget : TDADataTable;
|
|
|
|
|
|
AModo : TModoDuplicarRegistros; APermitirRepetidos: Boolean = True;
|
2008-05-26 16:59:17 +00:00
|
|
|
|
Const WithDeltas: Boolean = True; Const WithPKKey: Boolean = False; Const WithFKKey: Boolean = False);
|
2007-09-12 14:11:44 +00:00
|
|
|
|
begin
|
|
|
|
|
|
if not ASource.Active then
|
|
|
|
|
|
ASource.Open;
|
|
|
|
|
|
|
|
|
|
|
|
if not ATarget.Active then
|
|
|
|
|
|
ATarget.Open;
|
|
|
|
|
|
|
|
|
|
|
|
try
|
|
|
|
|
|
//Para que no se generen deltas de inserci<63>n, y luego actue como un update
|
|
|
|
|
|
if not WithDeltas then
|
|
|
|
|
|
DesconectarTabla(ATarget);
|
|
|
|
|
|
|
|
|
|
|
|
if AModo = mdrActual then
|
2008-05-26 16:59:17 +00:00
|
|
|
|
DuplicarRegistro(ASource, ATarget, WithPKKey, WithFKKey) //ATarget.CloneSelectedRecord(ASource, True)
|
2007-09-12 14:11:44 +00:00
|
|
|
|
else begin
|
|
|
|
|
|
ASource.First;
|
|
|
|
|
|
while not ASource.EOF do
|
|
|
|
|
|
begin
|
|
|
|
|
|
if APermitirRepetidos then
|
2008-05-26 16:59:17 +00:00
|
|
|
|
DuplicarRegistro(ASource, ATarget, WithPKKey, WithFKKey)
|
2007-09-12 14:11:44 +00:00
|
|
|
|
else
|
|
|
|
|
|
begin
|
|
|
|
|
|
ATarget.First;
|
2008-07-31 18:11:26 +00:00
|
|
|
|
if not ATarget.Locate(ATarget.RecIDField.FieldName, ASource.GetRowRecIDValue, []) then
|
2008-05-26 16:59:17 +00:00
|
|
|
|
DuplicarRegistro(ASource, ATarget, WithPKKey, WithFKKey);
|
2007-09-12 14:11:44 +00:00
|
|
|
|
end;
|
|
|
|
|
|
|
|
|
|
|
|
ASource.Next;
|
|
|
|
|
|
end;
|
|
|
|
|
|
end;
|
|
|
|
|
|
finally
|
|
|
|
|
|
//Para que no se generen deltas de inserci<63>n, y luego actue como un update
|
|
|
|
|
|
if not WithDeltas then
|
|
|
|
|
|
ConectarTabla(ATarget);
|
|
|
|
|
|
end;
|
|
|
|
|
|
end;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
procedure EnlazarMaestroDetalle(AMasterDataSource : TDADataSource;
|
|
|
|
|
|
ADetail : IDAStronglyTypedDataTable);
|
|
|
|
|
|
begin
|
|
|
|
|
|
if Assigned(ADetail) then
|
|
|
|
|
|
begin
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD> MUY IMPORTANTE !!!!!!!!!!!!!!!!!!
|
2007-09-24 11:09:48 +00:00
|
|
|
|
//ADetail.DataTable.DisableEventHandlers;
|
2007-09-12 14:11:44 +00:00
|
|
|
|
try
|
|
|
|
|
|
ADetail.DataTable.MasterSource := AMasterDataSource;
|
|
|
|
|
|
finally
|
|
|
|
|
|
{ Hay que activar los eventos porque dejan de funcionar
|
|
|
|
|
|
las reglas de negocio al establecer la relaci<EFBFBD>n
|
|
|
|
|
|
maestro-detalle. (Fallo de Data Abstract 3) }
|
2007-09-24 11:09:48 +00:00
|
|
|
|
//ADetail.DataTable.EnableEventHandlers;
|
2007-09-12 14:11:44 +00:00
|
|
|
|
end;
|
|
|
|
|
|
end;
|
|
|
|
|
|
end;
|
|
|
|
|
|
|
|
|
|
|
|
procedure DesconectarTabla (ATarget: TDADataTable);
|
|
|
|
|
|
begin
|
|
|
|
|
|
ATarget.RemoteFetchEnabled := False;
|
|
|
|
|
|
ATarget.LogChanges := False;
|
|
|
|
|
|
end;
|
|
|
|
|
|
|
|
|
|
|
|
procedure ConectarTabla (ATarget: TDADataTable);
|
|
|
|
|
|
begin
|
|
|
|
|
|
ATarget.RemoteFetchEnabled := True;
|
|
|
|
|
|
ATarget.LogChanges := True;
|
|
|
|
|
|
end;
|
|
|
|
|
|
|
|
|
|
|
|
procedure SetDataTableReadOnly(ADataTable: TDADataTable; const value: Boolean);
|
|
|
|
|
|
var
|
|
|
|
|
|
dtDetails : TList;
|
|
|
|
|
|
i : integer;
|
|
|
|
|
|
|
|
|
|
|
|
begin
|
|
|
|
|
|
if Assigned(ADataTable)
|
|
|
|
|
|
and (ADataTable.ReadOnly <> Value) then
|
|
|
|
|
|
begin
|
|
|
|
|
|
ADataTable.ReadOnly := Value;
|
|
|
|
|
|
dtDetails := ADataTable.GetDetailDataTables;
|
|
|
|
|
|
for i := 0 to dtDetails.Count - 1 do
|
|
|
|
|
|
TDADataTable(dtDetails.Items[i]).ReadOnly := ADataTable.ReadOnly;
|
|
|
|
|
|
end;
|
|
|
|
|
|
end;
|
|
|
|
|
|
|
|
|
|
|
|
end.
|