Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   OOP (https://www.clubdelphi.com/foros/forumdisplay.php?f=5)
-   -   Vincular dos DBGrids !!! (https://www.clubdelphi.com/foros/showthread.php?t=29943)

TriLoCBA 04-02-2006 23:50:24

Vincular dos DBGrids !!!
 
Estoy tratando de vincular dos DBGrid, haciendo que el primero (DBGrid1) muestre una lista de productos, y que el segundo (DBGrid2) muestre información sobre el producto (en el ejemplo el Stock del mismo).
Cada DBGrid se completa con un Stored Procedure SQL.
El SP del segundo DBGrid deberia ejecutarse cada vez que cambia el producto seleccionado en el primero...

Desde ya muchas gracias por vuestra ayuda.

Un abrazo.

Ej.
Código Delphi [-]
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, Grids, DBGrids, DB, ADODB;

type
  TForm1 = class(TForm)
    DBGrid1: TDBGrid;
    DBGrid2: TDBGrid;
    Label1: TLabel;
    Label2: TLabel;
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  conSQL: TADOConnection;
  cadenaSQL: String;
  sp1:TADOStoredProc;
  sp2:TADOStoredProc;
  ds1:TDataSource;
  ds2:TDataSource;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
  //Conexion al Servidor SQL...
  cadenaSQL:='Provider=SQLOLEDB.1;Password=MiPass;Persist Security Info=True;'+
          'User ID=MiUsuario;Initial Catalog=MiBase;Data Source=10.0.0.1;'+
          'Use Procedure for Prepare=1;Auto Translate=True;Packet Size=4096;'+
          'Workstation ID=MiEstacion;Use Encryption for Data=False;'+
          'Tag with column collation when possible=False';

  conSQL:=TADOConnection.Create(self);
  conSQL.ConnectionString:= cadenaSQL;
  conSQL.LoginPrompt:=False;
  conSQL.Connected:= True;

  //Completa el listado de productos en DBGrid1...
  with sp1 do begin
    sp1:=TADOStoredProc.Create(self);
    Connection:= conSQL;
    ProcedureName:= 'spListaProductos';
    Parameters.Refresh;
    Active:= true;
  end;
  ds1:=TDataSource.Create(self);
  ds1.DataSet:= sp1;

  DBGrid1.DataSource:= ds1;

  //Muestra detalles de un producto especifico...
  with sp2 do begin
    sp2:= TADOStoredProc.Create(self);
    Connection:= conSQL;
    ProcedureName:= 'spStockProducto';
    Parameters.Refresh;
    Parameters.ParamByName('@Producto').Value:= ???; // Que pongo Aqui ???...
    Active:= true;
  end;
  ds2:=TDataSource.Create(self);
  ds2.DataSet:= sp2;

  DBGrid2.DataSource:= ds2;

end;
end.
Código:

/* Datos SQL para probar el ejemplo... */
CREATE TABLE tProductos (CodProducto INT,NomProducto VARCHAR(20))

INSERT INTO tProductos VALUES(1,'AZUCAR')
INSERT INTO tProductos VALUES(2,'MANTECA')
INSERT INTO tProductos VALUES(3,'LECHE')

CREATE TABLE tStockProducto (Producto INT, Edificio VARCHAR(10), Unidades INT)

INSERT INTO tStockProducto VALUES(1,'Deposito1',100)
INSERT INTO tStockProducto VALUES(1,'Deposito2',50)
INSERT INTO tStockProducto VALUES(1,'Deposito4',200)
INSERT INTO tStockProducto VALUES(2,'Deposito1',90)
INSERT INTO tStockProducto VALUES(2,'Deposito3',110)
INSERT INTO tStockProducto VALUES(3,'Deposito4',1000)

/* Lista de productos... (DBGrid2) */
CREATE PROCEDURE spListaProductos
AS
 SELECT NomProducto AS [Producto]
 FROM tProductos
GO

/* Stock de un producto... (DBGrid2) */
CREATE PROCEDURE spStockProducto
@Producto INT
AS
 SELECT Edificio, Unidades
 FROM tStockProducto
 WHERE Producto = @Producto
GO


ContraVeneno 05-02-2006 17:32:24

Generalmente cuando alguien pone mucho código, yo no lo leo, así que pido una disculpa por no haber leído tu código.


Como se suele decir por este foro, el problema no esta en los DBGrids, si no en el dataset asociado a los mismo.

Pensando un poco se me ocurre, que tienes un Dataset para cada dbgrid, el primero llena la lista de productos normalmente. Ahora, para lograr lo que quieres, lo que yo haría sería mas o menos así:

Ejecutar el SP del primer dataset para llenar el primer DBgrid.
En el evento OnDataChange de este primer dataset, pongo el código para ejecutar el SP del segundo dataset, enviándole como parámetro el artículo que esta seleccionado en el primer dataset.

Código:

dataset2.params('articulo').AsString:=dataset1.fieldsByname('IDArticulo').AsString;

//Obviamente esto no es código, es la idea de como lo haría


Y creo que mas o menos eso es todo lo que yo haría para tener un dbgrid con la lista de productos y cada que cambie, se muestre la información del prodcuto en el segundo dbgrid.

TriLoCBA 07-02-2006 17:39:32

Muchas gracias !!!
 
Muchas gracias ContraVeneno... tu solución funciono perfecta !!!...

Copio el codigo completo :) :
Código Delphi [-]
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, Grids, DBGrids, DB, ADODB;
type
TForm1 = class(TForm)
DBGrid1: TDBGrid;
DBGrid2: TDBGrid;
Label1: TLabel;
Label2: TLabel;
procedure FormCreate(Sender: TObject);
procedure FormShow(Sender: TObject);
private
procedure ActualizarDBGrid2(Sender: TObject; Field: TField); //Metodo para mostrar el Stock del producto seleccionado en el DBGrid1
public
{ Public declarations }
end;
var
Form1: TForm1;
conSQL: TADOConnection;
cadenaSQL: String;
sp1:TADOStoredProc;
sp2:TADOStoredProc;
ds1:TDataSource;
ds2:TDataSource;
implementation
{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject);
begin
//Conexion al Servidor SQL...
cadenaSQL:='Provider=SQLOLEDB.1;Password=MiPass;Persist Security Info=True;'+
'User ID=MiUsuario;Initial Catalog=MiBase;Data Source=10.0.0.1;'+
'Use Procedure for Prepare=1;Auto Translate=True;Packet Size=4096;'+
'Workstation ID=MiEstacion;Use Encryption for Data=False;'+
'Tag with column collation when possible=False';
conSQL:=TADOConnection.Create(self);
conSQL.ConnectionString:= cadenaSQL;
conSQL.LoginPrompt:=False;
conSQL.Connected:= True;
//Completa el listado de productos en DBGrid1...
with sp1 do begin
sp1:=TADOStoredProc.Create(self);
Connection:= conSQL;
ProcedureName:= 'spListaProductos';
Parameters.Refresh;
Active:= true;
end;
ds1:=TDataSource.Create(self);
ds1.DataSet:= sp1;
DBGrid1.DataSource:=ds1;
ds1.OnDataChange:= ActualizarDBGrid2;
end;
procedure TForm1.ActualizarDBGrid2(Sender: TObject; Field: TField);
begin
//Muestra detalles de un producto especifico...
with sp2 do begin
sp2:= TADOStoredProc.Create(self);
Connection:= conSQL;
ProcedureName:= 'spStockProducto';
Parameters.Refresh;
Parameters.ParamByName('@Producto').Value:= ds1.DataSet.FieldByName('Producto').AsString;
Active:= true;
end;
ds2:=TDataSource.Create(self);
ds2.DataSet:= sp2;
DBGrid2.DataSource:= ds2;
end;
procedure TForm1.FormShow(Sender: TObject);
begin
ActualizarDBGrid2(nil,nil);
end;
end.


PD: Disculpa la cantidad de codigo, pero como soy un novato en esto, tener toda la codificacion a la hora de ejecutar un ejemplo siempre me ayuda mucho !!!


La franja horaria es GMT +2. Ahora son las 19:44:24.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi