David
10-01-2008, 09:09:32
Hola
Tengo dos clientDataSet uno para los clientes CDClientes y otro para las facturas CDFacturas. Establezco por código una relación maestro detalle y a la Query a la que va unido el CDFacturas, a veces le añado para que filtre por un sólo cliente, pero me he dado cuenta que para que salga bien, antes tienes que filtrar en el CDClientes por el mismo campo.
La query de Clientes es : SELECT * FROM TABLACLIENTES
La de Facturas SELECT * FROM TABLAFACTURAS
Pongo un ejemplo:
Así sale mal :
CDFacturas.close;
//Si es false sale todo este código bien, pero con todos los clientes y sus facturas
if HeFiltroPorCliente then // Suponemos es true
QueryFacturas.SQL.ADD := 'WHERE CLIENTE = 4';
CDFacturas.open;
CDFacturas.MasterSource := dataSourceCLIENTES;
CDFacturas.MasterField := 'CLIENTE';
CDFacturas.indexName := 'CLIENTE'; // indice que ordena por Clientes,necesario
CDClientes.open;
// Con este código la tabla de facturas aparece vacia
Bien, en el código que he puesto, no sale nada, y todo por que la SQL que le he pasado.
Ahora he hecho una pequeña chapuza, y con esto me sale bien, pero no me gusta el sistema:
var
Cliente : interger;
begin
CDFacturas.close;
if HeFiltroPorCliente then // Suponemos es true
QueryFacturas.SQL.ADD := 'WHERE CLIENTE = 4';
CDFacturas.open;
CDFacturas.MasterSource := dataSourceCLIENTES;
CDFacturas.MasterField := 'CLIENTE';
CDFacturas.indexName := 'CLIENTE'; // indice que ordena por Clientes,necesario
CDClientes.Last;
Cliente := CDClientes.FieldByName('CLIENTE').AsInteger;
CDClientes.First;
if Cliente = CDClientes.FieldByName('CLIENTE').AsInteger then
begin
CDClientes.Filter := 'Cliente = '+IntToStr(Cliente);
CDCliente.Filtered := true;
end;
CDClientes.open;
//ahora ya sale bien, pero el sistema no me acaba de gustar
end;
Lo que hago en el segundo código, es ver si ha introducido la SQL que filtra por Clientes, es decir si la opcion HeFiltradoPorClientes se cumple, entonces como esta ordenado por Clientes, el último y primera facturas tienen el mismo cliente,por lo que filtro la tabla de clientes por el cliente en cuestión, sino es así y no ha filtrado por Clientes y esta hecho para todos los clientes, pues entonces siempre sale bien con el código que he puesto.
Este es el dilema, al final sale bien, pero no me gusta tener que ir al último y primer registro, tiene que haber una forma más fácil y más lógica de hacer esto.
Estoy con Firebird, aunque no creo que sea relevante, con la paleta de interbase, a una IBQuery le adjunto su provider y el ClientDataSet.
Un saludo
Tengo dos clientDataSet uno para los clientes CDClientes y otro para las facturas CDFacturas. Establezco por código una relación maestro detalle y a la Query a la que va unido el CDFacturas, a veces le añado para que filtre por un sólo cliente, pero me he dado cuenta que para que salga bien, antes tienes que filtrar en el CDClientes por el mismo campo.
La query de Clientes es : SELECT * FROM TABLACLIENTES
La de Facturas SELECT * FROM TABLAFACTURAS
Pongo un ejemplo:
Así sale mal :
CDFacturas.close;
//Si es false sale todo este código bien, pero con todos los clientes y sus facturas
if HeFiltroPorCliente then // Suponemos es true
QueryFacturas.SQL.ADD := 'WHERE CLIENTE = 4';
CDFacturas.open;
CDFacturas.MasterSource := dataSourceCLIENTES;
CDFacturas.MasterField := 'CLIENTE';
CDFacturas.indexName := 'CLIENTE'; // indice que ordena por Clientes,necesario
CDClientes.open;
// Con este código la tabla de facturas aparece vacia
Bien, en el código que he puesto, no sale nada, y todo por que la SQL que le he pasado.
Ahora he hecho una pequeña chapuza, y con esto me sale bien, pero no me gusta el sistema:
var
Cliente : interger;
begin
CDFacturas.close;
if HeFiltroPorCliente then // Suponemos es true
QueryFacturas.SQL.ADD := 'WHERE CLIENTE = 4';
CDFacturas.open;
CDFacturas.MasterSource := dataSourceCLIENTES;
CDFacturas.MasterField := 'CLIENTE';
CDFacturas.indexName := 'CLIENTE'; // indice que ordena por Clientes,necesario
CDClientes.Last;
Cliente := CDClientes.FieldByName('CLIENTE').AsInteger;
CDClientes.First;
if Cliente = CDClientes.FieldByName('CLIENTE').AsInteger then
begin
CDClientes.Filter := 'Cliente = '+IntToStr(Cliente);
CDCliente.Filtered := true;
end;
CDClientes.open;
//ahora ya sale bien, pero el sistema no me acaba de gustar
end;
Lo que hago en el segundo código, es ver si ha introducido la SQL que filtra por Clientes, es decir si la opcion HeFiltradoPorClientes se cumple, entonces como esta ordenado por Clientes, el último y primera facturas tienen el mismo cliente,por lo que filtro la tabla de clientes por el cliente en cuestión, sino es así y no ha filtrado por Clientes y esta hecho para todos los clientes, pues entonces siempre sale bien con el código que he puesto.
Este es el dilema, al final sale bien, pero no me gusta tener que ir al último y primer registro, tiene que haber una forma más fácil y más lógica de hacer esto.
Estoy con Firebird, aunque no creo que sea relevante, con la paleta de interbase, a una IBQuery le adjunto su provider y el ClientDataSet.
Un saludo