PDA

Ver la Versión Completa : Ayuda con refactorización


Dexter182
22-08-2021, 05:27:55
Hola a todos!

Otra vez molestando... :o

Quiero armar un procedimiento para no acceder directamente a Modulo.Consulta_Int y a diferencia de otro hilo que abrí, se me presenta la dificultad de que voy cambiando el valor del parámetro en el loop y no tengo la menor idea de como solucionarlo.
El código es el siguiente:

Grid.Perform(WM_SETREDRAW, 0, 0);

Try
Modulo.Consulta_Int.Active := FALSE;
Modulo.Consulta_Int.SQL.Clear;
Modulo.Consulta_Int.SQL.Add('SELECT Cod_Producto, Desc_Producto, Precio FROM Productos');
Modulo.Consulta_Int.SQL.Add('WHERE Cod_Producto = : pCod_Producto');

Repeat
ParseRecord(Datos[i],Delimitador, Codigo_Articulo, Precio_Articulo);

Modulo.Consulta_Int.Active := FALSE;
Modulo.Consulta_Int.Parameters.ParamByName('pCod_Producto').Value := Codigo_Articulo;
Modulo.Consulta_Int.Active := TRUE;

If not Modulo.Consulta_Int.IsEmpty then //Si el artículo existe en la base de datos

//Y si el precio anterior y el nuevo son diferentes
If Modulo.Consulta_Int.FieldByName('Precio').AsString <> Precio_Articulo then
begin
//Rellena el StringGrid con los datos de los artículos a modificar
Grid.Cells[0, Grid.RowCount -1] := Modulo.Consulta_Int.FieldByName('Cod_Producto').AsString;
Grid.Cells[1, Grid.RowCount -1] := Modulo.Consulta_Int.FieldByName('Desc_Producto').AsString;
Grid.Cells[2, Grid.RowCount -1] := Modulo.Consulta_Int.FieldByName('Precio').AsString;
Grid.Cells[3, Grid.RowCount -1] := Precio_Articulo;
//Si el precio nuevo es un número válido
If (TryStrToFloat(Grid.Cells[3, Grid.RowCount -1], temp) = TRUE) then
Grid.Cells[4, Grid.RowCount -1] := Format('%.2n',[((StrToFloat(Precio_Articulo) / Modulo.Consulta_Int.FieldByName('Precio').AsFloat) - 1) * 100]);
Grid.RowCount := Grid.RowCount + 1;
end
Else
Omitidos := Omitidos + 1;

i := i + 1;

Until i > Datos.Count -1;

Finally
Grid.Perform(WM_SETREDRAW, 1, 0);
Grid.Invalidate;
end; {try}


Cualquier consejo será bienvenido.

Saludos!!! ^\||/^\||/^\||/

cloayza
23-08-2021, 17:36:45
Estimado Dexter182, le propongo esta opción.

La idea es crear una clase que se encarga de recuperar la información requerida del producto a través del código.

La clase se encarga de realizar la consulta y asignar los datos a sus propiedades. Como no indica que componentes de acceso a datos utiliza, asumo que son FireDac (TFDConnection, TFDQuery).

Por supuesto los puede cambiar por los que usa.


TProducto=Class
private
FConexion:TFDConnection;
fQry :TFDQuery;
fCod_Producto :string;
fDesc_Producto:String;
fPrecio :Single;
public
constructor Create(AConexion:TFDConnection);
destructor Destroy;

property Cod_Producto : integer read fCod_Producto write fCod_Producto;
property Desc_Producto: String read fDesc_Producto write fDesc_Producto;
property Precio : single read fPrecio write fPrecio;

function GetData(pCod_Producto):Boolean;
end;

implementation

constructor TProducto.Create(AConexion:TFDConnection);
begin
fConexion:=AConexion;
fqry := TFDQuery.Create(nil);
fqry.Connection := fConexion;
end;

destructor TProducto.Destroy;
begin
fqry.close;
fqry.free;
fConexion:=nil;
end;

function TProducto.GetData(pCod_Producto:String):Boolean;
begin
try
result:=false;

fqry.Sql.Add('SELECT Cod_Producto, Desc_Producto, Precio ');
fqry.Sql.Add('FROM Productos');
fqry.Sql.Add('WHERE Cod_Producto = : pCod_Producto');
fqry.Parameters.ParamByName('pCod_Producto').Value := pCod_Producto;
fqry.Active:=true;

result:=not fQry.IsEmty;

if result then
begin
fCod_Producto :=fqry.FieldByName('Cod_Producto').AsString;
fDesc_Producto:=fqry.FieldByName('Desc_Producto').AsString;
fPrecio :=fqry.FieldByName('Precio').AsSingle;
end;

finally
fqry.close;
end;
end;

....
Var
Producto:TProducto;
begin
Grid.Perform(WM_SETREDRAW, 0, 0);

Try
{Crea la clase y asigna la conexion a utilizar}
Producto:=TProducto.Create(Conexion_A_DB);

Repeat
ParseRecord(Datos[i],Delimitador, Codigo_Articulo, Precio_Articulo);

{Llama al método GetData pasando el código, GetData retorna un Boolean, True: hay datos, false: No hay datos }
If Producto.GetData(Codigo_Articulo) then //Si el artículo existe en la base de datos

//Y si el precio anterior y el nuevo son diferentes
If Producto.Precio <> StrToFloat(Precio_Articulo) then
begin
//Rellena el StringGrid con los datos de los artículos a modificar
Grid.Cells[0, Grid.RowCount -1] := Producto.Cod_Producto;
Grid.Cells[1, Grid.RowCount -1] := Producto.Desc_Producto;
Grid.Cells[2, Grid.RowCount -1] := Producto.Precio;
Grid.Cells[3, Grid.RowCount -1] := Precio_Articulo;

//Si el precio nuevo es un número válido
If (TryStrToFloat(Grid.Cells[3, Grid.RowCount -1], temp) = TRUE) then
Grid.Cells[4, Grid.RowCount -1] := Format('%.2n',[((StrToFloat(Precio_Articulo) / Producto.Precio).AsFloat) - 1) * 100]);
Grid.RowCount := Grid.RowCount + 1;
end
Else
Omitidos := Omitidos + 1;

i := i + 1;

Until i > Datos.Count -1;

Finally
Producto.free;

Grid.Perform(WM_SETREDRAW, 1, 0);
Grid.Invalidate;
end; {try}
end;

End.

Espero que esta sugerencia le sirva.

Saludos cordiales

Dexter182
24-08-2021, 05:09:11
La idea es crear una clase que se encarga de recuperar la información requerida del producto a través del código.

La clase se encarga de realizar la consulta y asignar los datos a sus propiedades. Como no indica que componentes de acceso a datos utiliza, asumo que son FireDac (TFDConnection, TFDQuery).
¡Gracias cloayza por la respuesta! ^\||/^\||/^\||/

Aunque olvidé aclarar que uso ADO, el ejemplo se entendió perfectamente.

Saludos!!!