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

View File

@ -22,9 +22,6 @@ 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); overload;
@ -58,34 +55,30 @@ uses
Dialogs, Variants, uDBSelectionListUtils, uROClasses, uDADataStreamer, uDABin2DataStreamer;
procedure CopyDataTableDA5(ASource : TDADataTable;
ATarget: TDADataTable;
const OnlySelectedRows : Boolean);
procedure CopyDataTableDA5(ASource : TDADataTable; ATarget: TDADataTable;
const OnlySelectedRows : Boolean = False);
var
AStream : Binary;
AStream2 : Binary;
AFilter : String;
DABin: Binary;
DADataStreamer : TDABin2DataStreamer;
AFiltered : Boolean;
AFilter : String;
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)');
{ 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
begin
AFiltered := True;
@ -94,38 +87,43 @@ begin
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) + ')'
ASource.Filter := ASource.Filter + '(' + ASource.RecIDField.FieldName + ' = ' + 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]) + ')';
ASource.Filter := ASource.Filter + '(' + ASource.RecIDField.FieldName + ' = ' + IntToStr(AObj.SelectedRecords.Items[i]) + ')';
end;
ASource.Filtered := True;
end;
if not ASource.Active then
ASource.Open;
AStream := Binary.Create;
DesconectarTabla(ATarget);
DABin := Binary.Create;
DADataStreamer := TDABin2DataStreamer.Create(nil);
ShowHourglassCursor;
ASource.DisableControls;
ATarget.DisableControls;
try
ASource.SaveToStream(AStream);
AStream2 := AStream.Clone;
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;
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
if OnlySelectedRows then
begin
@ -134,11 +132,17 @@ begin
if AFiltered then
ASource.Filtered := True;
end;
finally
FreeAndNil(DABin);
FreeAndNil(DADataStreamer);
ASource.EnableControls;
ATarget.EnableControls;
HideHourglassCursor;
end;
end;
function SetFieldNull(ATarget: TDADataTable; const FieldName: String): Boolean;
begin
Result := False;
@ -154,34 +158,6 @@ begin
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;
var
@ -301,15 +277,11 @@ var
begin
with ATarget do
begin
// ****** Inicio migración DA 5
{RemoteService := ASource.GetRemoteService;
Adapter := ASource.GetAdapter;}
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;
@ -321,77 +293,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;
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;
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
for i := 0 to ASource.MasterParamsMappings.Count - 1 do
@ -444,83 +347,6 @@ begin
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);
var
i, j: Integer;
@ -528,14 +354,14 @@ var
ASourceField: TDAField;
ADetailFields : TStringList;
begin
ADetailFields := Nil;
if not ASource.Active then
ASource.Open;
if not ATarget.Active then
ATarget.Open;
ADetailFields := Nil;
// ¿ATarget es una tabla detalle?
if Assigned(ATarget.MasterSource) then
begin
@ -550,7 +376,9 @@ begin
ADetailFields.Add(ATarget.DetailFields);
end;
end;
end;
end
else
ADetailFields := Nil;
ATarget.Insert;
{ Hay que desactivar los eventos para que dejan de funcionar
@ -572,20 +400,21 @@ begin
begin
//Si no es campo clave
//Si no es autoinc (podria desaparecer pero no lo quitamos por si acaso
if not (ATargetField.InPrimaryKey)
and (ATargetField.DataType <> datAutoInc) then
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;
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;
end
else
@ -632,11 +461,11 @@ begin
while not ASource.EOF do
begin
if APermitirRepetidos then
DuplicarRegistro(ASource, ATarget, WithPKKey, WithFKKey)
DuplicarRegistro(ASource, ATarget, WithPKKey, WithFKKey)
else
begin
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);
end;