Extraer seleccionados: Mejorado el sistema de localización de las filas seleccionadas. Se usa la columna internar 'RecID' para identificar de manera única una tupla en vez de usar el campo 'ID', que no siempre existe en una tabla.

git-svn-id: https://192.168.0.254/svn/Proyectos.Acana_FactuGES2/trunk@304 f4e31baf-9722-1c47-927c-6f952f962d4b
This commit is contained in:
David Arranz 2008-07-31 18:24:52 +00:00
parent 5d3bb5aeb7
commit 70f9a6c532
2 changed files with 56 additions and 226 deletions

View File

@ -106,7 +106,7 @@ function TSelectedRecords.CurrentRow: integer;
begin begin
if not FDataTable.Active then if not FDataTable.Active then
raise EDatabaseError.Create(sDataSetClosed); raise EDatabaseError.Create(sDataSetClosed);
Result := FDataTable.FieldByName('ID').AsInteger; Result := FDataTable.GetRowRecIDValue;
end; end;
function TSelectedRecords.GetCurrentRowSelected: Boolean; function TSelectedRecords.GetCurrentRowSelected: Boolean;
@ -158,7 +158,8 @@ function TSelectedRecords.LocateItem(const Index: Integer) : Boolean;
begin begin
if not FDataTable.Active then if not FDataTable.Active then
raise EDatabaseError.Create(sDataSetClosed); raise EDatabaseError.Create(sDataSetClosed);
Result := FDataTable.Locate('ID', Items[Index], []); Result := FDataTable.Locate(FDataTable.RecIDField.FieldName, Items[Index], []);
end; end;

View File

@ -22,9 +22,6 @@ procedure DesconectarTabla (ATarget: TDADataTable);
procedure CopyDataTableDA5(ASource : TDADataTable; ATarget: TDADataTable; procedure CopyDataTableDA5(ASource : TDADataTable; ATarget: TDADataTable;
const OnlySelectedRows : Boolean = False); const OnlySelectedRows : Boolean = False);
procedure CopyDataTableDA3(ASource : TDADataTable; ATarget : TDADataTable;
const OnlySelectedRows : Boolean = False);
procedure CloneDataTable(const ASource : TDACDSDataTable; procedure CloneDataTable(const ASource : TDACDSDataTable;
var ATarget : TDACDSDataTable; var ATarget : TDACDSDataTable;
RemoteUpdate: Boolean = True); overload; RemoteUpdate: Boolean = True); overload;
@ -58,34 +55,30 @@ uses
Dialogs, Variants, uDBSelectionListUtils, uROClasses, uDADataStreamer, uDABin2DataStreamer; Dialogs, Variants, uDBSelectionListUtils, uROClasses, uDADataStreamer, uDABin2DataStreamer;
procedure CopyDataTableDA5(ASource : TDADataTable; procedure CopyDataTableDA5(ASource : TDADataTable; ATarget: TDADataTable;
ATarget: TDADataTable; const OnlySelectedRows : Boolean = False);
const OnlySelectedRows : Boolean);
var var
AStream : Binary; DABin: Binary;
AStream2 : Binary; DADataStreamer : TDABin2DataStreamer;
AFilter : String;
AFiltered : Boolean; AFiltered : Boolean;
AFilter : String;
AObj : ISeleccionable; AObj : ISeleccionable;
i : Integer; i : Integer;
begin begin
AFilter := ''; AFilter := '';
AFiltered := False; 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 if OnlySelectedRows then
begin begin
if not Supports(ASource, ISeleccionable, aObj) then if not Supports(ASource, ISeleccionable, aObj) then
raise Exception.Create('El origen de datos no soporta la interfaz ISeleccionable (CopyDataTable)'); raise Exception.Create('El origen de datos no soporta la interfaz ISeleccionable (CopyDataTable)');
{ Si la tabla está 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.
if ASource.Filtered then if ASource.Filtered then
begin begin
AFiltered := True; AFiltered := True;
@ -94,38 +87,43 @@ begin
end; end;
ASource.Filter := ''; ASource.Filter := '';
if ASource.Active then
ASource.Close;
//Si no hay elemento seleccionados filtramos para que ATarget se quede vacia //Si no hay elemento seleccionados filtramos para que ATarget se quede vacia
if (AObj.SelectedRecords.Count = 0) then if (AObj.SelectedRecords.Count = 0) then
ASource.Filter := ASource.Filter + '(ID = ' + IntToStr(ID_NULO) + ')' ASource.Filter := ASource.Filter + '(' + ASource.RecIDField.FieldName + ' = ' + IntToStr(ID_NULO) + ')'
//En caso contrario filtramos por los elementos seleccionados //En caso contrario filtramos por los elementos seleccionados
else else
for i := 0 to AObj.SelectedRecords.Count - 1 do for i := 0 to AObj.SelectedRecords.Count - 1 do
begin begin
if (i > 0) then if (i > 0) then
ASource.Filter := ASource.Filter + ' or '; ASource.Filter := ASource.Filter + ' or ';
ASource.Filter := ASource.Filter + '(ID = ' + IntToStr(AObj.SelectedRecords.Items[i]) + ')'; ASource.Filter := ASource.Filter + '(' + ASource.RecIDField.FieldName + ' = ' + IntToStr(AObj.SelectedRecords.Items[i]) + ')';
end; end;
ASource.Filtered := True; ASource.Filtered := True;
end; end;
if not ASource.Active then DABin := Binary.Create;
ASource.Open; DADataStreamer := TDABin2DataStreamer.Create(nil);
AStream := Binary.Create; ShowHourglassCursor;
DesconectarTabla(ATarget); ASource.DisableControls;
ATarget.DisableControls;
try try
ASource.SaveToStream(AStream); ATarget.LogicalName := ASource.LogicalName; // We need to specify new dataset LogicalName
AStream2 := AStream.Clone; ATarget.RemoteFetchEnabled := False; // "Desconectamos" la tabla destino del servidor
if not ASource.Active then
ASource.Open;
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
// ShowMessage(AStream.ToReadableString);
ATarget.LoadFromStream(AStream2); ///->>>>>>>>>>>>>>>>>>>>>>>>>>ERRORRRR
finally
FreeAndNil(AStream);
ConectarTabla(ATarget);
// Dejar el filtro de la tabla origen como estaba // Dejar el filtro de la tabla origen como estaba
if OnlySelectedRows then if OnlySelectedRows then
begin begin
@ -134,11 +132,17 @@ begin
if AFiltered then if AFiltered then
ASource.Filtered := True; ASource.Filtered := True;
end; end;
finally
FreeAndNil(DABin);
FreeAndNil(DADataStreamer);
ASource.EnableControls;
ATarget.EnableControls;
HideHourglassCursor;
end; end;
end; end;
function SetFieldNull(ATarget: TDADataTable; const FieldName: String): Boolean; function SetFieldNull(ATarget: TDADataTable; const FieldName: String): Boolean;
begin begin
Result := False; Result := False;
@ -154,34 +158,6 @@ begin
end; end;
end; end;
{procedure EliminarNoSeleccionados(const ASource : IDADataset;
var ATarget : TDADataTable);
var
AObj : ISelectedRowList;
i : Integer;
begin
if not Supports(ASource, ISelectedRowList, aObj) then
Exit;
// ATarget.DisableControls;
// ATarget.DisableEventHandlers;
ShowHourglassCursor;
try
ATarget.Open;
ATarget.Last;
while ATarget.RecordCount > AObj.SelectedRows.Count do
begin
if AObj.SelectedRows.IndexOf(ATarget.RecIDValue) < 0 then
ATarget.Delete
else
ATarget.Prior;
end;
finally
// ATarget.EnableControls;
// ATarget.EnableControls;
HideHourglassCursor;
end;
end;}
function DataTableModified (const ADataTable : TDADataTable): Boolean; function DataTableModified (const ADataTable : TDADataTable): Boolean;
var var
@ -301,15 +277,11 @@ var
begin begin
with ATarget do with ATarget do
begin begin
// ****** Inicio migración DA 5
{RemoteService := ASource.GetRemoteService;
Adapter := ASource.GetAdapter;}
if not Assigned(ASource.RemoteDataAdapter) then if not Assigned(ASource.RemoteDataAdapter) then
raise Exception.Create('No está asignado RemoteDataAdapter (' + ASource.Name + ')'); raise Exception.Create('No está asignado RemoteDataAdapter (' + ASource.Name + ')');
RemoteDataAdapter.Assign(ASource.RemoteDataAdapter); RemoteDataAdapter.Assign(ASource.RemoteDataAdapter);
// ****** Fin migración DA 5
BusinessRulesID := ASource.BusinessRulesID; BusinessRulesID := ASource.BusinessRulesID;
Randomize; Randomize;
@ -321,78 +293,9 @@ begin
if Assigned(ASource.LocalSchema) then if Assigned(ASource.LocalSchema) then
LocalSchema := ASource.LocalSchema LocalSchema := ASource.LocalSchema
else begin else begin
// ****** Inicio migración DA 5
{
with SchemaCall do
begin
MethodName := ASource.SchemaCall.MethodName;
for i := 0 to ASource.SchemaCall.Params.Count - 1 do
begin
with Params.Add do begin
Name := ASource.SchemaCall.Params[i].Name;
ParamType := ASource.SchemaCall.Params[i].ParamType;
DataType := ASource.SchemaCall.Params[i].DataType;
Value := ASource.SchemaCall.Params[i].Value;
UserClassName := ASource.SchemaCall.Params[i].UserClassName;
end;
end;
end;
}
// ****** Fin migración DA 5
ATarget.Fields.AssignFieldCollection(ASource.Fields); // o también ATarget.LoadSchema; ATarget.Fields.AssignFieldCollection(ASource.Fields); // o también ATarget.LoadSchema;
end; end;
// ****** Inicio migración DA 5
{
with DataUpdateCall do
begin
MethodName := ASource.DataUpdateCall.MethodName;
for i := 0 to ASource.DataUpdateCall.Params.Count - 1 do
begin
with Params.Add do begin
Name := ASource.DataUpdateCall.Params[i].Name;
ParamType := ASource.DataUpdateCall.Params[i].ParamType;
DataType := ASource.DataUpdateCall.Params[i].DataType;
Value := ASource.DataUpdateCall.Params[i].Value;
UserClassName := ASource.DataUpdateCall.Params[i].UserClassName;
end;
end;
end;
with ScriptCall do
begin
MethodName := ASource.ScriptCall.MethodName;
for i := 0 to ASource.ScriptCall.Params.Count - 1 do
begin
with Params.Add do begin
Name := ASource.ScriptCall.Params[i].Name;
ParamType := ASource.ScriptCall.Params[i].ParamType;
DataType := ASource.ScriptCall.Params[i].DataType;
Value := ASource.ScriptCall.Params[i].Value;
UserClassName := ASource.ScriptCall.Params[i].UserClassName;
end;
end;
end;
with DataRequestCall do
begin
MethodName := ASource.DataRequestCall.MethodName;
for i := 0 to ASource.DataRequestCall.Params.Count - 1 do
begin
with Params.Add do begin
begin
Name := ASource.DataRequestCall.Params[i].Name;
ParamType := ASource.DataRequestCall.Params[i].ParamType;
DataType := ASource.DataRequestCall.Params[i].DataType;
Value := ASource.DataRequestCall.Params[i].Value;
UserClassName := ASource.DataRequestCall.Params[i].UserClassName;
end;
end;
end;
end;
}
// ****** Fin migración DA 5
with MasterParamsMappings do with MasterParamsMappings do
for i := 0 to ASource.MasterParamsMappings.Count - 1 do for i := 0 to ASource.MasterParamsMappings.Count - 1 do
Add(ASource.MasterParamsMappings.Strings[i]); Add(ASource.MasterParamsMappings.Strings[i]);
@ -444,83 +347,6 @@ begin
end; end;
procedure CopyDataTableDA3(ASource : TDADataTable; ATarget : TDADataTable;
const OnlySelectedRows : Boolean = False);
var
DABin: Binary;
DAAdapter : TDABINAdapter;
AFilter : String;
AFiltered : Boolean;
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)');
if ASource.Filtered then
begin
AFiltered := True;
AFilter := ASource.Filter;
ASource.Filtered := False;
end;
ASource.Filter := '';
if ASource.Active then
ASource.Close;
//Si no hay elemento seleccionados filtramos para que ATarget se quede vacia
if (AObj.SelectedRecords.Count = 0) then
ASource.Filter := ASource.Filter + '(ID = ' + IntToStr(ID_NULO) + ')'
//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 ';
ASource.Filter := ASource.Filter + '(ID = ' + IntToStr(AObj.SelectedRecords.Items[i]) + ')';
end;
ASource.Filtered := True;
end;
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
if not ASource.Active then
ASource.Open;
ASource.First;
DAAdapter.WriteDataset(DABin, ASource, [woRows]);
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
if OnlySelectedRows then
begin
ASource.Filtered := False;
ASource.Filter := AFilter;
if AFiltered then
ASource.Filtered := True;
end;
finally
FreeAndNil(DABin);
FreeAndNil(DAAdapter);
end;
end;
procedure DuplicarRegistro(ASource : TDADataTable; ATarget : TDADataTable; Const WithPKKey: Boolean = False; Const WithFKKey: Boolean = False); procedure DuplicarRegistro(ASource : TDADataTable; ATarget : TDADataTable; Const WithPKKey: Boolean = False; Const WithFKKey: Boolean = False);
var var
i, j: Integer; i, j: Integer;
@ -528,14 +354,14 @@ var
ASourceField: TDAField; ASourceField: TDAField;
ADetailFields : TStringList; ADetailFields : TStringList;
begin begin
ADetailFields := Nil;
if not ASource.Active then if not ASource.Active then
ASource.Open; ASource.Open;
if not ATarget.Active then if not ATarget.Active then
ATarget.Open; ATarget.Open;
ADetailFields := Nil;
// ¿ATarget es una tabla detalle? // ¿ATarget es una tabla detalle?
if Assigned(ATarget.MasterSource) then if Assigned(ATarget.MasterSource) then
begin begin
@ -550,7 +376,9 @@ begin
ADetailFields.Add(ATarget.DetailFields); ADetailFields.Add(ATarget.DetailFields);
end; end;
end; end;
end; end
else
ADetailFields := Nil;
ATarget.Insert; ATarget.Insert;
{ Hay que desactivar los eventos para que dejan de funcionar { Hay que desactivar los eventos para que dejan de funcionar
@ -572,20 +400,21 @@ begin
begin begin
//Si no es campo clave //Si no es campo clave
//Si no es autoinc (podria desaparecer pero no lo quitamos por si acaso //Si no es autoinc (podria desaparecer pero no lo quitamos por si acaso
if not (ATargetField.InPrimaryKey) if not (ATargetField.InPrimaryKey) and
and (ATargetField.DataType <> datAutoInc) then (ATargetField.DataType <> datAutoInc) then
begin begin
//En el caso de no copiar las claves foraneas //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 //Si no hay campos foreing key o los hay pero el campo a copiar no es uno de ellos
if not WithFKKey then if not WithFKKey then
begin begin
if (not Assigned(ADetailFields) or not ADetailFields.Find(ATargetField.Name, j)) then if (not Assigned(ADetailFields) or not ADetailFields.Find(ATargetField.Name, j)) then
//Copiamos el campo //Copiamos el campo
ATargetField.Value := ASourceField.Value; ATargetField.Value := ASourceField.Value;
end end
else else
//Copiamos el campo //Copiamos el campo
ATargetField.Value := ASourceField.Value; ATargetField.Value := ASourceField.Value;
end; end;
end end
else else
@ -632,11 +461,11 @@ begin
while not ASource.EOF do while not ASource.EOF do
begin begin
if APermitirRepetidos then if APermitirRepetidos then
DuplicarRegistro(ASource, ATarget, WithPKKey, WithFKKey) DuplicarRegistro(ASource, ATarget, WithPKKey, WithFKKey)
else else
begin begin
ATarget.First; ATarget.First;
if not ATarget.Locate('ID', ASource.FieldByName('ID').AsVariant, []) then if not ATarget.Locate(ATarget.RecIDField.FieldName, ASource.GetRowRecIDValue, []) then
DuplicarRegistro(ASource, ATarget, WithPKKey, WithFKKey); DuplicarRegistro(ASource, ATarget, WithPKKey, WithFKKey);
end; end;