PDA

Ver la Versión Completa : filtro entre dos tablas en tiempo de ejecucion


Goyo
26-09-2006, 17:29:20
tengo dos tablas: Vehiculos (catalogo de vehiculos) y Bitacora (control de gastos de los vehiculos)
En la tabla vehiculos tengo un campo que es la llave principal: NumeroVehiculo y este tambien lo grabo en un campo NumeroVehiculo (tipo cadenas de 3) de la tabla Bitacora (que es donde llevo todos los servicios y reparaciones que se hacen a los vehiculos), en la tabla bitacora tengo un indice con los campos: NumeroVehiculo y Fecha, esto para que me ordene todos los vehiculos de acuerdo a la fecha.

cuando trato de imprimir en Quickreport, llamo a un formulario llamado FrmImprimirVehiculos donde tengo un componente DBLookupComboBox donde enlazo la tabla vehiculos, en su propiedad ListSource=DM.DSVehiculos, ListField=NumeroVehiculo y KeyField=NumeroVehiculo, ademas tengo otro componente TEdit, con la finalidad de que tenga la opcion de seleccionar el vehiculo directamente desde DBLookupComboBox o desde el TEdit (aqui escribiria el numero del vehiculo).

Bueno mi problema es que cuando ejecuto el programa y selecciono algun vehiculo, siempre me toma el primer vehiculo, por ejemplo si quiero imprimir el vehiculo='020' me toma el '017' o si quiero imprimir el '099', me toma el '017' , tengo que seleccionar dos veces (y cargar el Quickreport) antes de que me acepte el vehiculo que quiero. En el QuickReport imprimo datos de la tabla Vehiculos en la cabecera del reporte y el cuerpo corresponde a la tabla Bitacora. de esta forma ejecuto el filtro..


procedure TFrmImprimirVehiculo.SpeedButton1Click(Sender: TObject);
var Filtro:string;
begin
dm.TbBitacora.Active:=True;
dm.TbBitacora.Filter := '';
dm.TbBitacora.Filtered := False;
If (DBNumeroVehiculo.Text <> 'Todos')
then
Begin
If Filtro > '' then
Filtro := Filtro + ' And ' ;
Filtro := Filtro + ' NumeroVehiculo = ' + dm.TbVehiculos.FieldByname('NumeroVehiculo').AsString;
End;
dm.TbBitacora.Filter := Filtro;
dm.TbBitacora.Filtered := True;
FrmReporte1.QuickRep1.Preview;
end;


si hay alguna otra forma de mejorar los filtros les agradecere... :confused:

Caral
26-09-2006, 17:55:48
Hola
En el qreport tienes un query?
Saludos

Caral
26-09-2006, 18:31:26
Esto yo lo hago por sentencia sql y no por filtro, me explico:
Coloco un query en el QReport, en el from que llama al qreport pongo:


If (DBNumeroVehiculo.Text <> 'Todos') then
Begin
FrmReporte1:=TFrmReporte1.Create(self);
FrmReporte1.ADOQuery1.SQL.Add('SELECT NumeroVehiculo');
FrmReporte1.ADOQuery1.SQL.Add('FROM TbBitacora RIGHT JOIN TbVehiculos ON TbBitacora.NumeroVehiculo = TbVehiculos.NumeroVehiculo ');
FrmReporte1.ADOQuery1.SQL.Add('WHERE TbVehiculos.NumeroVehiculo = '+DBLookupComboBox1'');
FrmReporte1.ADOQuery1.Open;
If RadioGroup1.ItemIndex = 0 then FrmReporte1.Print
else FrmReporte1.Preview;
finally
FrmReporte1.Free;
end;
end;

Coloco un RadioGroup para que lo envie a impresion o preview y ya.
Ha en el QReport en DataSet le pongo el ADoQuery1 porque si no me da, como a ti, solo el primer registro y no todos.
Como notaras esto esta hecho con ado no se que usas tu, pero es lo mismo.
Saludos
Saludos

Goyo
26-09-2006, 18:51:51
a lo que me explicas te comento que son bases de datos de paradox, y en componente DBLookupComboBox me muestra todos los vehiculos, solo que al seleccionar por decir el 020 me toma el 017 (que es primer vehiculo de mi tablas) o cualquiera entre 017 y 099 que es ultimo vehiculo de mi tabla.

Caral
26-09-2006, 18:57:01
Normalmente se tiene ese problema y desconozco porque, cuando no se conecta el dataset del qreport con el query es independiente del motor de base de datos uses.
saludos

Goyo
26-09-2006, 19:26:23
implemente lo que me indicaste, solo cambiando el componente ADOQuery por Query y quedo de la siguiente manera:


procedure TFrmImprimirVehiculo.SpeedButton1Click(Sender: TObject);
begin
if (DBNumeroVehiculo.Text <> 'Todos') then
Begin
FrmReporte1:=TFrmReporte1.Create(self);
FrmReporte1.Query1.SQL.Add('SELECT NumeroVehiculo');
FrmReporte1.Query1.SQL.Add('FROM BitacoraVehiculos RIGHT JOIN Vehiculos ON BitacoraVehiculos.NumeroVehiculo = Vehiculos.NumeroVehiculo');
FrmReporte1.Query1.SQL.Add('WHERE TbVehiculos.NumeroVehiculo = '+DBNumeroVehiculo.Text);
FrmReporte1.Query1.Open;
if RadioGroup1.ItemIndex = 0 then FrmReporte1.QuickRep1.Print
else FrmReporte1.QuickRep1.Preview;
FrmReporte1.Free;
end;
end;


me marca un error al ejecutarlo y no me muestra nada

Caral
26-09-2006, 19:40:38
Que error?

Goyo
26-09-2006, 19:42:31
que no encuentra la tabla BitacoraVehiculos.

De hecho tengo dos tablas de paradox: Vehiculos (que es catalogo principal de vehiculos) y BitacoraVehiculos (que es donde se graban todos sus gastos de los vehiculos).

Caral
26-09-2006, 19:58:03
Aqui Hay varias cosas.
Primero si copiaste y pegaste el codigo, hay un error fijate:
El tuyo:


procedure TFrmImprimirVehiculo.SpeedButton1Click(Sender: TObject);
begin
if (DBNumeroVehiculo.Text <> 'Todos') then
Begin
FrmReporte1:=TFrmReporte1.Create(self);
FrmReporte1.Query1.SQL.Add('SELECT NumeroVehiculo');
FrmReporte1.Query1.SQL.Add('FROM BitacoraVehiculos RIGHT JOIN Vehiculos ON BitacoraVehiculos.NumeroVehiculo = Vehiculos.NumeroVehiculo');
FrmReporte1.Query1.SQL.Add('WHERE TbVehiculos.NumeroVehiculo = '+DBNumeroVehiculo.Text);
FrmReporte1.Query1.Open;
if RadioGroup1.ItemIndex = 0 then FrmReporte1.QuickRep1.Print
else FrmReporte1.QuickRep1.Preview;
FrmReporte1.Free;
end;
end;



El mio ya con query:


procedure TFrmImprimirVehiculo.SpeedButton1Click(Sender: TObject);
begin
If (DBNumeroVehiculo.Text <> 'Todos') then
Begin
FrmReporte1:=TFrmReporte1.Create(self);
FrmReporte1.Query1.SQL.Add('SELECT NumeroVehiculo');
FrmReporte1.Query1.SQL.Add('FROM TbBitacora RIGHT JOIN TbVehiculos ON TbBitacora.NumeroVehiculo = TbVehiculos.NumeroVehiculo ');
FrmReporte1.Query1.SQL.Add('WHERE TbVehiculos.NumeroVehiculo = '+DBLookupComboBox1'');
FrmReporte1.Query1.Open;
If RadioGroup1.ItemIndex = 0 then FrmReporte1.Print
else FrmReporte1.Preview;
finally
FrmReporte1.Free;
end;
end;
end;



Revisa el la parte:



FrmReporte1.Query1.SQL.Add('FROM BitacoraVehiculos RIGHT JOIN Vehiculos ON BitacoraVehiculos.NumeroVehiculo = Vehiculos.NumeroVehiculo');


la tabla BitacoraVehiculos
tiene un campo NumeroVehiculo
y
la tabla Vehiculos tambien ?
Recuerda que no veo las tablas ni los campos, es dificil adivinar.
Ademas te falta el finally, si no simplemente no lo ejecuta.
Prueba, revisa y me dices
Saludos

Goyo
26-09-2006, 20:12:16
aqui te muestro los campos de cada tabla para que te des una idea mejor... te recuerdo que son bases de datos de Paradox

Tabla: Vehiculos
NumeroVehiculo - tipo A de 3
Placas - tipo A de 15
Marca - tipo A de 15
Tipo - tipo A de 10
Modelo - tipo N
NumeroSerie - tipo A de 20
Cilindros - tipo N
ResguardoA - tipo A de 60

Tabla: BitacoraVehiculos
Clave - tipo + (autonumerica) - este campo no lo uso
NumeroVehiculo - tipo A de 3
FechadeServicio - tipo D
ConceptoReparacion - tipo M de 50
ConceptoServicio - tipo M de 50
DiasdeComision - tipo A de 16
LitrosGasolina - tipo A de 9
NumeroFactura - tipo A de 16
Importe - Tipo N
ImporteTotal - Tipo N

Caral
26-09-2006, 20:33:58
Pon esto:

procedure TFrmImprimirVehiculo.SpeedButton1Click(Sender: TObject);
begin
If (DBNumeroVehiculo.Text <> 'Todos') then
Begin
FrmReporte1:=TFrmReporte1.Create(self);
FrmReporte1.Query1.SQL.Add('SELECT NumeroVehiculo');
FrmReporte1.Query1.SQL.Add('FROM BitacoraVehiculos RIGHT JOIN Vehiculos ON BitacoraVehiculos.NumeroVehiculo = Vehiculos.NumeroVehiculo ');
FrmReporte1.Query1.SQL.Add('WHERE Vehiculos.NumeroVehiculo = '+DBLookupComboBox1'');
FrmReporte1.Query1.Open;
If RadioGroup1.ItemIndex = 0 then FrmReporte1.Print
else FrmReporte1.Preview;
finally
FrmReporte1.Free;
end;
end;
end;

Seguro TbBitacora, no lo encuentra.?
Prueba y Me dices
Saludos

Goyo
26-09-2006, 21:08:59
que tal Caral. mira lo implemente de esta otra forma, solo que me marca error, el mismo error implementando la forma que tu me sugeriste...


procedure TFrmImprimirVehiculo.SpeedButton1Click(Sender: TObject);
var consulta : string;
begin
If (DBNumeroVehiculo.Text <> 'Todos') then
Begin
try
FrmReporte1:=TFrmReporte1.Create(self);
consulta:='SELECT NumeroVehiculo FROM BitacoraVehiculos RIGHT JOIN Vehiculos ON BitacoraVehiculos.NumeroVehiculo = Vehiculos.NumeroVehiculo WHERE Vehiculos.NumeroVehiculo ='+chr(39)+DBNumeroVehiculo.Text+chr(39);
FrmReporte1.Query1.SQL.Add(consulta);
FrmReporte1.query1.Active:=False;
FrmReporte1.query1.Active:=True;
If RadioGroup1.ItemIndex = 0 then FrmReporte1.QuickRep1.Print
else FrmReporte1.QuickRep1.Preview
finally
FrmReporte1.QuickRep1.Free;
end;
end;
end;


te comento que ruve que ponerle Try para que pueda funcionar el Finally , asimismo, te comento que escribi esto porque asi se llama mi componente DBLookupComboBox1: chr(39)+DBNumeroVehiculo.Text+chr(39) si no le ponto el .text al final me marca error, al igual que cuando llamo el reporte en FrmReporte1.QuickRep1.Print, FrmReporte1.QuickRep1.Preview y FrmReporte1.QuickRep1.Free, me marca un error que desconoce el campo preview y free. y el error que me marca al final... de hecho haciendo estas correcciones al igual que al tuyo, me marca este error...

project bitacoravehiculos.exe tabla bitacoravehiculos

Caral
26-09-2006, 21:15:07
No tengo ni idea del porque.
A mi me funciona perfectamente como te indique, creo que tendras que revisar mas el codigo para entender el error, si esta en mis manos te ayudo con mucho gusto.
Saludos

Goyo
26-09-2006, 21:23:38
mira Caral, ahora creo que puedo explicarte: el error que me marca es que dice que no encuentra la base de datos o la tabla BitacoraVehiculos.. yo tengo mi programa en c:\Mis Documentos\BitacoraVehiculos\
y mis datos osea mis tablas en : c:\Mis Documentos\BitacoraVehiculos\Datos

el error que me marca es el siguiente:


project BitacoraVehiculos.exe raides exception class DBEngineError with message 'table does not exist.
File o directory does not exist
File c:\Mis Documentos\BitacoraVehiculos\BitacoraVehiculos.db
File c:\Mis Documentos\BitacoraVehiculos\BitacoraVehiculos.dbf
File c:\Mis Documentos\BitacoraVehiculos\BitacoraVehiculos.txt
File c:\Mis Documentos\BitacoraVehiculos\BitacoraVehiculos'. process stoped. Use step or run to continue.

y disculpa tanta molestia...
saludos:confused:

Caral
26-09-2006, 21:27:14
Es un placer Goyo
Ya lo resolviste ?
Saludos

Goyo
26-09-2006, 21:31:25
de hecho uso un modulo de datos (Data Module) donde tengo mis bases de datos y en cada programa lo pongo en...

implementation
uses ModuloDatos,.....;

es por ello que cuando ejecuto mi programa me debería de respetar ese modulo, pero creo que no lo esta tomando en cuenta... y aun no resuelvo mi problema...

saludos

Caral
26-09-2006, 21:39:31
Es muy estraño
Si usas un query y este esta ligado al datamodule, la conexion esta hecha,
verdaderamente no entiendo porque no funciona.
Saludos