Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Conexión con bases de datos (https://www.clubdelphi.com/foros/forumdisplay.php?f=2)
-   -   Problemas en busqueda (https://www.clubdelphi.com/foros/showthread.php?t=34181)

destrukthor 31-07-2006 14:04:49

Problemas en busqueda
 
Hola nuevamente a todos y gracias por sus ayudas de ante mano.
Mi problema es el siguiente:
Estoy usando FindKey para realizar una busqueda y q me diga si existe ya un registro para no repetirlo, pero como utilizo los TDBEdit para mostrar he ingresar los datos me dice que siempre existen y esto es cuando hago el Insert correspondiente.

Código Delphi [-]
    cRut:=Md.tbCompra.FieldByName('Rut').AsString;
    cTipDoc:=Md.tbCompra.FieldByName('TipDoc').AsString;
    nDoc:=Md.tbCompra.FieldByName('NumDoc').AsInteger;
    Md.tbCompra.IndexName:='CompCom';
    If MD.tbCompra.FindKey([cRut,cTipDoc,nDoc])=True THEN
      ShowMessage('El registro ya existe');

Estoy usando bases Paradox 7

Y si uso este codigo me arroja un error de violacion.

Código Delphi [-]
    cRut:=DBedit4.Text;
    cTipDoc:=DBComboBox1.Text;
    nDoc:=StrToInt(DBEdit3.Text);
    Md.tbCompra.IndexName:='CompCom';
    If MD.tbCompra.FindKey([cRut,cTipDoc,nDoc])=True THEN
      ShowMessage('El registro ya existe');

Gracias de ante mano.

afxe 31-07-2006 16:46:41

Provocas un posteo al realizar la búsqueda.
 
Cuando estás añadiendo o modificando un registro de una tabla no debes provocar que el cursor se mueva del registro, que es lo que pasa cuando haces un FindKey: El registro actual que estás insertando se posteará automáticamente y siempre te dará que existe... claro, acabas de grabarlo...
Lo más rápido, sin entrar en validaciones a nivel de registros y etc, es que antes de lanzar tu MD.tbCompra.Post, hagas la búsqueda en otra tabla que contenga el mismo conjunto de datos, es decir, haz el FindKey sobre TbBuscaCompra (por ejemplo) que debe apuntar a la misma tabla de compras:

Código:


// OnClick del Boton Grabar
 
// Comprobamos que estoy en insercción, pues si estoy modificando un
// registro y es lógico e irrefutable que ya exista  ;-)
 
if MD.tbCompra.State = dsInsert then begin
    cRut := Md.tbCompra.FieldByName('Rut').AsString;
    cTipDoc := Md.tbCompra.FieldByName('TipDoc').AsString;
    nDoc := Md.tbCompra.FieldByName('NumDoc').AsInteger;
    Md.tbBuscaCompra.Open;  // abro justo antes de buscar
    Md.tbBuscaCompra.IndexName:='CompCom';
    If MD.tbBuscaCompra.FindKey([cRut,cTipDoc,nDoc]) THEN begin
      ShowMessage('El registro ya existe');
    end else begin
      MD.tbCompra.Post;
      ShowMessage('Registro grabado');
    end;
    md.tbBuscaCompra.Close;
end else begin
  MD.tbCompra.Post;
  // Se supone que si estamos modificando no se han modificado los
  // campos claves.
end;

He reutilizado lo que has escrito, espero que te sirva.

vtdeleon 31-07-2006 17:31:56

Saludos

Es extraño este código :confused::
Cita:

Código Delphi [-]
    cRut:=Md.tbCompra.FieldByName('Rut').AsString;
    cTipDoc:=Md.tbCompra.FieldByName('TipDoc').AsString;
    nDoc:=Md.tbCompra.FieldByName('NumDoc').AsInteger;
    Md.tbCompra.IndexName:='CompCom';
    If MD.tbCompra.FindKey([cRut,cTipDoc,nDoc])=True THEN
      ShowMessage('El registro ya existe');

Estás mandado a buscar DATOS qeu están en la misma tabla:confused:, y es claro que te diga que existan.

Me parece que falta otra tabla!

destrukthor 01-08-2006 08:24:38

Siiiii
 
Y como verificas q la informacion no quede duplicada.
Como sabes cuando un conjundo de datos digitados esta duplicado en el momento de Agregar un registro o modificarlo.
Me puedes dar alguna señal
REcuerda q ingresos con TDbEdit y sus componentes.
Gracias.

destrukthor 01-08-2006 08:45:09

Gracias Afxa
 
Pero creo q mi problema radica en q ocupo mucho los DBEdit y esos a su vez no me permiten la validacion de los datos q se ingresas a las tablas ya q los hace directo sobre ellas.
Creo q tendre q hacerlo a la antiguita ingresarlos a un MarkEdit o Edit y transferirlos a las tablas, claro esta despues de validar la información digitada.
Es un poco largo y arcaico pero no veo otra solucion.
Gracias a todos por la ayuda...

PepeLolo 01-08-2006 10:36:46

Una manera muy simple y que siempre aplico a rajatabla es la siguiente:
a) TQuery para consultas de validación, independiente de la tabla sobre la que actuas
b) Dependiendo del tipo de Control (DataWare, no DataWare)
b.1) Validación en el evento OnValidate del TField, usando el TQuery indicado.
b.2) En el evento "OnExit" del control, usando el TQuery indicado.

Siguiendo esta simple regla, NO PROBLEM jamas.;)

un saludo.

destrukthor 01-08-2006 10:40:31

Gracias amigo ya resolvi el problema
 
Buenop muchas gracias por las repuestas, y la encontre en aquellas q me hicieron recordar q al encotrar un registro existente este cambia automaticamente de posicion y eso me llevo a verificar las posiciones de un registro nuevo por el insert y verificar el registro encontrado.

De esa forma no tuve q cambiar nada de mi formulario y seguir trabajando con los TDBedit y seguir confiando en ellos.

Solo tengo un detalle y es q el Tabla1.Cancel no me anula el Registro nuevo y sigue existiendo, no le he dado la instruccion de Tabla1.Post sino el Cancel, pero = me sigue guardando los datos.

Alguna sujerencia a mi problema
Gracias nuevamente.:D ;)

destrukthor 01-08-2006 10:44:41

Para PepeLolo porfis
 
Oye amigo primero gracias por las reglas esta buenas.
Segundo soy algo novato en esto, me puedes hacer una sujerencia en donde encontrar ejemplos en relacion a estos puntos mencionas por ti, o es su defecto podrias tu darme algunos ejemplos para realizar estas validaciones y no tener q hacerme volas con procesos algo engorrozos, (pero q me sirve), y optimizar mi programacion en Delphi.
En serio desde ya muchas Gracias, eres un gran aporte.:)

roman 01-08-2006 11:01:34

Cita:

Empezado por destrukthor
Solo tengo un detalle y es q el Tabla1.Cancel no me anula el Registro nuevo y sigue existiendo, no le he dado la instruccion de Tabla1.Post sino el Cancel, pero = me sigue guardando los datos.

Hola, no quisiera ser pesimista pero es justamente este detalle el que indica que en realidad no has resuelto el problema. Como ya te indicó afxe, al moverte de posición, el registro que estabas insertando se "postea" automáticamente por lo cual el Cancel ya no tiene ningún efecto.

Hasta donde veo tienes dos opciones.

1. La que ya usas que es escribir los datos en un Edit normal (por lo menos los datos de la llave de la tabla) y hacer la búsqueda. Si no hay registro con esa llave entonces puedes pasar a una segunda parte del formulario donde captures el resto de datos, ahora sí con DBEdits.

2. Olvidarte de la búsqueda y prepararte en el evento OnPostError de la tabla para avisarle al usuario que el registro está duplicado.

// Saludos

destrukthor 01-08-2006 11:07:51

Gracias Roman
 
Bien ahora entiendo porq no funciona el cancel, efectivamente cambia la posicion de registro al encontrarlo.
Bien ahora solo si puedes me darias un ejemplo para el evento OnPostError, si no fuese molestia.
Desde ya Gracias.

roman 01-08-2006 11:22:27

OnPostError puede generarse por diversas razones así que debes distinguir cuál fue. Aquí tienes un ejemplo de marcoszorrilla donde se trata esto.

// Saludos

destrukthor 01-08-2006 12:26:56

Hola de nuevo
 
Sorry por mis problemas.
este es codigo q coloque...

if (E is EDBEngineError) then Begin
if (E as EDBEngineError).Errors[0].Errorcode = 9729 then
begin
ShowMessage('Documento Para Proveedor ya Existe');
Abort;
End;
end;
Bien me lo hace pero solo una vez despues vuelvo a digitadar otros datos y no vuelve a salir el mensage y me los grava.
¿Porque en q me equivoco?
Gracias nuevamente..

PepeLolo 01-08-2006 12:47:40

Como dice roman, puedes usar el ejemplo que te indica o esta otra forma; esto depende del metodo que quieras usar para la validación de la clave.

Este ejemplo es para cualquier tipo de validación (clave primaria, clave foranea)

Código Delphi [-]
{
*Documentación*
*Nombre: QCatalogosCDPROVEEDORValidate
*Tipo: procedure
*Título: Mantenimiento de Proveedores
*Autor: JMCDM INFOSERVICIOS U.S.Y.P. (Unidad de Soluciones y Proyectos)
*Descripción:
       Comprobar si el proveedor ya existe 

*Parámetro de entrada:


*Modificaciones*
*Fecha:
*Autor:
*Descripción:
}
begin
  if Sender.AsString = '' then Exit;
  if BuscarSql('SELECT CDPROVEEDOR FROM HABI_PROVEEDORES WHERE CDPROVEEDOR = ' + '''' + Sender.AsString + '''') <> '' then
   begin
     Sender.FocusControl;
     ECDPROVEEDOR.Clear;
     DataBaseError('Ya existe el Proveedor');
   end;
end;

Espero que te sirva.

destrukthor 01-08-2006 12:58:37

Fiuuuu paso volando ;)
 
Uffff..
Amigo viendo tu codigo, creo q me falta mucho para llegar a entender este codigo.
Sorry no lo entendi, te recuerdo q soy novato y estoy haciendolo en Paradox 7, creo q no entiendo mucho la validacion en delphi, antes trabajabaz en Clipper y el control de los ingresos lo hacia yo directamente estaba acostumbrado a validarlo con comandos y mensajes propio.
Sorry nuevamente por mis problemas.;)
Pero quiero aprender bien por eso mi insistencia me parece q Delphi fue mi mejor opcion antes programaba en VisualFox Pro, pero los metodos de programacion es muy larga y engorroza.


La franja horaria es GMT +2. Ahora son las 08:43:06.

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