Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > Varios
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Grupo de Teaming del ClubDelphi

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 18-11-2005
Mathom Mathom is offline
Miembro
 
Registrado: nov 2005
Posts: 72
Poder: 19
Mathom Va por buen camino
Problema de código

Hola, este es el código de un botón "aceptar". Es un pequeño formulario donde hay 2 DBEdits, el tema es que quiero que si los dos han sido rellenados inserte el nuevo registro pero si uno de los dos está vacio aparezca un mensaje de advertencia pero sin grabar el dato que si que está. Utilizo un "if" donde si los dos son "<>" de vacio inserte el registro pero cuando solo relleno uno no entre en el with y por lo tanto no grabe nada, sin embargo aunque sólo rellene uno de los dos me entra en el with modificando el registro. Os dejo el código a ver si veis el fallo, yo me he encabezonado y no lo veo...

Código Delphi [-]
 procedure TForm2.BitBtn2Click(Sender: TObject);
  begin
    If ((DBEdit1.text <> '') and (DBEdit2.text <> '')) then
    begin
      With DataModule7.Table1 Do
      Begin
        Try
          Insert;
          Post;
         Except
          Application.MessageBox ('El nombre introducido no es correcto'+chr(13)+
          'El nombre esta repetido, prueba con otro',
          'Insertar registro',
          Mb_Ok+Mb_IconStop);
          Cancel;
          Insert;
        End;
       End;
     end
    else
    ShowMessage ('¡Debe rellenar todos los campos!')
  end;
  
  end.
aleee

Última edición por dec fecha: 18-11-2005 a las 17:17:03. Razón: ¡¡Encerrad el código fuente entre las etiquetas [DELPHI] ... [/DELPHI]!!
Responder Con Cita
  #2  
Antiguo 18-11-2005
Avatar de vtdeleon
vtdeleon vtdeleon is offline
Miembro
 
Registrado: abr 2004
Ubicación: RD & USA
Posts: 3.236
Poder: 24
vtdeleon Va por buen camino
Saludos
Prueba con esto (trim())
Código Delphi [-]
If ((trim(DBEdit1.text) <> '') and (trim(DBEdit2.text) <> '')) then
__________________
Van Troi De León
(Not) Guía, Code vB:=Delphi-SQL, ¿Cómo?
Viajar en el tiempo no es teóricamente posible, pues si lo fuera, ya estarían aqui contándonos al respecto!
Responder Con Cita
  #3  
Antiguo 18-11-2005
Avatar de lucasarts_18
lucasarts_18 lucasarts_18 is offline
Miembro
 
Registrado: mar 2005
Ubicación: Villa Alemana,Chile
Posts: 1.087
Poder: 21
lucasarts_18 Va por buen camino
Hola:

Prueba así:

Código Delphi [-]
 procedure TForm2.BitBtn2Click(Sender: TObject);
 begin
   If (DBEdit1.text <> '') and (DBEdit2.text <> '') then
   begin
   With DataModule7.Table1 Do
   Begin
     Try
     Insert;
     Post;
      Except
     Application.MessageBox ('El nombre introducido no es correcto'+chr(13)+
     'El nombre esta repetido, prueba con otro',
     'Insertar registro',
     Mb_Ok+Mb_IconStop);
     Cancel;
     Insert;
     End;
    End;
    end
   else
   ShowMessage ('¡Debe rellenar todos los campos!')
 end;
 
 end.

Tenías unos parentesis demás..
__________________
No todo es como parece ser...
Responder Con Cita
  #4  
Antiguo 18-11-2005
Mathom Mathom is offline
Miembro
 
Registrado: nov 2005
Posts: 72
Poder: 19
Mathom Va por buen camino
Ante todo, gracias. La solción que me da LucasArt ya la he probado y no funciona correctamente (al menos como yo quería). Ahora probaré lo vtdeleon a ver que tal....
Responder Con Cita
  #5  
Antiguo 18-11-2005
Avatar de lucasarts_18
lucasarts_18 lucasarts_18 is offline
Miembro
 
Registrado: mar 2005
Ubicación: Villa Alemana,Chile
Posts: 1.087
Poder: 21
lucasarts_18 Va por buen camino
Hola.

Seguro debe ser un espacio que te queda en blanco, en ese sentido lo de VTDELEON debería funcionar, aún así yo te recomiendo que no uses de esa forma los parentesis, de hecho nunca he visto de esa forma la sentencia.

Hasta Luego -
__________________
No todo es como parece ser...
Responder Con Cita
  #6  
Antiguo 18-11-2005
Mathom Mathom is offline
Miembro
 
Registrado: nov 2005
Posts: 72
Poder: 19
Mathom Va por buen camino
No es lo normal. Me refiero a utilzar así los parentesis, lo que pasa es que como no me funcionaba como yo esperaba he empezado a hacer pruebas por si era algo de los parentesis. Lo normal es que los ponga:

Código:
if (DBEdit1.text = ' ') and (DBEdit2.text = ' ' ) then
aún no he probado lo de trim. Tengo tres frentes abiertos ahora con la aplicación.. en cuanto lo pruebe os comento como he quedado.

gracias a los dos.
Responder Con Cita
  #7  
Antiguo 18-11-2005
Mathom Mathom is offline
Miembro
 
Registrado: nov 2005
Posts: 72
Poder: 19
Mathom Va por buen camino
Bien, he probado tanto el que me ha dicho vtdeleon
Código:
If ((trim(DBEdit1.text) <> '') and (trim(DBEdit2.text) <> '')) then
...como...

Código:
If((trim(DBEdit1.text) <> '') and (trim(DBEdit2.text) <> '') then
...el resultado sigue siendo el mismo..me sigue entrando dentro del with de todos modos...
Responder Con Cita
  #8  
Antiguo 18-11-2005
Avatar de roman
roman roman is offline
Moderador
 
Registrado: may 2003
Ubicación: Ciudad de México
Posts: 20.269
Poder: 10
roman Es un diamante en brutoroman Es un diamante en brutoroman Es un diamante en bruto
Para empezar, pon un punto de corte en la línea que sigue al condicional y examina el valor de DBEdit1.Text y DBEdit2.Text. Muy posiblemente observes que sí tienen algún dato.

Por otra parte te comento que lo que haces es muy, pero muy raro y da pie a pensar que el error viene de otro lado.

¿Qué hace un Insert dentro del with? Eso va a provocar que el registro actual, el que estás comparando con los DBEdits, se guarde en la base y se inserte uno más en blanco. El post que le sigue guardará entonces tal registro en blanco.

Si lo que quieres es validar que ambos campos estén llenos tienes dos opciones. Una es asignar el evento OnValidate a cada campo y verificar que no esté vacío. Esta a mi no me gusta porque impide que el usuario pueda moverse de campos hasta no llenar uno.

La otra opción es usar el evento BeforePost del Table asociado y ahí checar que los campos se hayan llenado.

// Saludos
Responder Con Cita
  #9  
Antiguo 18-11-2005
[maeyanes] maeyanes is offline
Capo de los Capos
 
Registrado: may 2003
Ubicación: Campeche, México
Posts: 2.732
Poder: 24
maeyanes Va por buen camino
Trata con:

Código Delphi [-]
if not DBEdit1.Field.IsNull and not DBEdit2.Field.IsNull then
begin
  //...

otra forma podría ser:

Código Delphi [-]
if (DBEdit1.Field.AsString <> '') and (DBEdit2.Field.AsString <> '') then
begin
  //...



Saludos...
Responder Con Cita
  #10  
Antiguo 18-11-2005
Avatar de lucasarts_18
lucasarts_18 lucasarts_18 is offline
Miembro
 
Registrado: mar 2005
Ubicación: Villa Alemana,Chile
Posts: 1.087
Poder: 21
lucasarts_18 Va por buen camino
Cita:
Empezado por maeyanes
otra forma podría ser:

Código Delphi [-]
   if (DBEdit1.Field.AsString <> '') and (DBEdit2.Field.AsString <> '') then
   begin
     //...
Esta última tengo mis dudas, de esa forma pienso yo (no estoy seguro) que solo sirve cuando traes valores desde la base de datos, en este caso los datos se están ingresando por lo tanto que valor tendrá Field.asString ??

Hasta Luego -
__________________
No todo es como parece ser...
Responder Con Cita
  #11  
Antiguo 18-11-2005
Avatar de roman
roman roman is offline
Moderador
 
Registrado: may 2003
Ubicación: Ciudad de México
Posts: 20.269
Poder: 10
roman Es un diamante en brutoroman Es un diamante en brutoroman Es un diamante en bruto
Quizá me equivoque pero pienso que ni Field.AsString ni Field.IsNull serán seguros.

Cuando se edita en un DBEdit, los cambios no se reflejan en el buffer del registro activo sino hasta que el foco se mueve a otro campo. Si el botón que se intenta usar es un SpeedButton que no gana el foco, o tiene el atributo deafult y el usuario oprime enter, quizá no se vacíen los datos en el buffer.

Por ello insisto, ésta no es la forma de atacar la validación de campos. Más aún, en la parte del except, no tiene sentido un Insert luego de un Cancel.

Me da la impresión de que el compañero Mathom tiene algunos conceptos poco claros y convendría que los repensara antes de lanzarse en la búsqueda de una solución en un código que de por sí está planteado de forma poco ortodoxa.

// Saludos
Responder Con Cita
  #12  
Antiguo 18-11-2005
[maeyanes] maeyanes is offline
Capo de los Capos
 
Registrado: may 2003
Ubicación: Campeche, México
Posts: 2.732
Poder: 24
maeyanes Va por buen camino
Cita:
Empezado por lucasarts_18
Esta última tengo mis dudas, de esa forma pienso yo (no estoy seguro) que solo sirve cuando traes valores desde la base de datos, en este caso los datos se están ingresando por lo tanto que valor tendrá Field.asString ??

Hasta Luego -
Como bien dice Roman:

Cita:
Empezado por Roman
Cuando se edita en un DBEdit, los cambios no se reflejan en el buffer del registro activo sino hasta que el foco se mueve a otro campo.
Ahora, viendo el código que puso Mathom al inicio, se deduce que el control que usa es un TBitButton, el cual si agarra el foco cuando se presiona en él.

También es cierto lo que comenta Roman, de que existen mejores formas de hacer estas comprobaciones, solo que yo intenté darle una solución basado en lo que estaba intentando hacer desde un principio.


Saludos...
Responder Con Cita
  #13  
Antiguo 18-11-2005
Mathom Mathom is offline
Miembro
 
Registrado: nov 2005
Posts: 72
Poder: 19
Mathom Va por buen camino
Desde luego, estoy muy verde. EL tema es que esa parte de código la cogí de una explicación que me hicieron unos compañeros por lo que la estaba aprovechando. Entonces vosotros eliminariais el insert y para validar utilizaríais el OnValidate en cada campo, no es así??

Os agradezco ante todo que me digais que voy por mal camino, a ver si voy cogiendome pq cuantas más cosas voy aprendiendo más verde veo que estoy.
Responder Con Cita
  #14  
Antiguo 18-11-2005
Avatar de roman
roman roman is offline
Moderador
 
Registrado: may 2003
Ubicación: Ciudad de México
Posts: 20.269
Poder: 10
roman Es un diamante en brutoroman Es un diamante en brutoroman Es un diamante en bruto
No se trata de eliminar el Insert y ver si funciona. Se trata, pienso, en detenerte un momento para examinar qué es lo que haces y lo que debes hacer.

Vamos a suponer que en tu caso tienes un formulario con dos DBEdit. Estos están enlazados a un DataSource que a su vez estará enlazado a un Table. En cada DBEdit tienes asignado el campo al que se conectan.

En principio esto es todo lo que debes saber de los DBEdit. Esto es, normalmente no hace falta, ni se recomienda, acceder directamente a los datos del DBEdit, o sea, no usar propiedades como DBEdit.Text. Esto es así porque los controles enlazados a datos son meramente un intermediario entre el usuario y la tabla. Los datos que presentan son reflejo fiel de lo que contenga el registro activo y cualquier modificación que haga el usuario se transfiere automáticamente a la tabla.

Todas las operaciones se hacen a través del dataset asociado (el Table en este caso), los objetos TField del dataset, y sus eventos.

Cuando abres tu formulario, muy posiblemente tendrás un botón para agregar un nuevo registro con la instrucción:

Table.Append;

Esto inserta un registro en blanco y deja a tus DBEdit listos para comenzar a escribir sobre ellos sin hacer más nada. Pero observa, debes comenzar con el Append (o Insert, el que gustes), no se trata de una instrucción que se haga después de escribir los datos.

Como todos los datos son guardados en un buffer temporal, debes explícitamente indicar que queires grabar los datos con:

Table.Post;

que tendrías en otro botón.

Hasta aquí todo claro, sólo un par de líneas, una en el evento OnClick de cada botón.

Viene entonces el asunto de las validaciones. En tu caso debes asegurarte que ninguno de los dos campos esté vacío.

Lo que tú estás haciendo ahora, es hacer la validación en el botón que tienes, supongo, para guardar los datos. Pero este es el lugar incorrecto. ¿Por qué? Pues imagina que posteriormente debes manejar la misma tabla desde otro formulario distinto. Ahí tendrás que repetir la validación con lo que ya desperdiciaste código. Además, si en algún momento cambian las reglas de validación, tendrás que hacer las modificaciones pertinentes en todos los puntos donde accedas a esa tabla.

El punto es: normalmente la validación es independiente de la forma en que se inserten los registros. No importa si usas dbedits o un dbgrid u otro control similar, la regla debe ser siempre la misma: los campos no pueden estar vacíos.

Por ello, enfatizo, no debes basar tus validaciones en los valores de controles específicos. Lo recomendable es centralizar estas validaciones.

Hay dos lugares muy propicios para hacer las validaciones.

Uno es el evento OnValidate del campo asociado. Para ello debes agregar los objetos TField al dataset dando doble click sobre la componente (el Table) y escogiendo la opción "Select all fields" del menú contextual. O puedes agregar sólo los que requieras ver en tu aplicación. Cuando seleccionas uno de los campos, el inspector de objetos te mostrará las propiedades y eventos específicos para dicho objeto. Ahí encontrarás el evento OnValidate.

Ahora bien. Es cuestión de gustos, pero a mi no me acomoda esta forma de validar ya que el evento OnValidate se lanzará cada vez que el usuario intente mover el foco a otro campo, lo cual le impide navegar libremente por el formulario hasta estar satisfecho con lo escrito. En mi opinión esto era más de los tiempos de Clipper y sistemas en MS-DOS.

Otro punto donde puedes centralizar las validaciones, es en el evento BeforePost del dataset (el Table). Este evento se generará justo antes de que el registro se guarde en la tabla física, sin importar por qué medios se haga. Puede ser porque explíctamente usaste Table.Post o bien porque estabas en un DBGrid y moviste la selección a otro registro.

El evento BeforePost pasa como parámetro el DataSet que se está validando. En este momento ya puedes hacer uso de los valores de los campos:

DataSet.FieldByName('campo1').AsString

por ejemplo.

Si la validación no se cumple, usas abort para cancelar los cambios o

raise Exception.Create('mensaje aclarativo');

para indicar al usuario que hubo un problema y además cancelar los cambios.

Si observas, la importancia de esto (tanto OnValidate como BeforePost) es que en ningún momento haces referencia a un control en particular y por tanto, la parte medular de tu aplicación, como las validaciones, no dependen de los elementos que uses para la interfaz de usuario, de manera que puedes alterar ésta sin afectar lo importante.

Así pues, como ves, no se trata de eliminar el Insert, yo eliminaría todo el código del botón, por drástico que suene.

Y una recomendación. Si bien se puede aprender del código de otros, es importante que leas, antes de ponerte a teclear. Un buen lugar para empezar es el libro la Cara oculta de Delphi 4 de Ian Marteens, que podrás bajar gratuitamente de su sitio. Que no te mosquee la versión. Para los conceptos básicos te será igualmente bueno si usas un Delphi posterior.

Te aseguro que con una semana que leas la parte dedicada al acceso a datos, serás tú el que esté dando explicaciones a tus compañeros.

// Saludos
Responder Con Cita
  #15  
Antiguo 18-11-2005
Avatar de Lepe
[Lepe] Lepe is offline
Miembro Premium
 
Registrado: may 2003
Posts: 7.424
Poder: 29
Lepe Va por buen camino
De mayor quiero ser como roman

PD: roman, has hecho caso omiso a tu firma... pero no te lo tendremos en cuenta esta vez.
__________________
Si usted entendió mi comentario, contácteme y gustosamente,
se lo volveré a explicar hasta que no lo entienda, Gracias.
Responder Con Cita
  #16  
Antiguo 19-11-2005
Avatar de lucasarts_18
lucasarts_18 lucasarts_18 is offline
Miembro
 
Registrado: mar 2005
Ubicación: Villa Alemana,Chile
Posts: 1.087
Poder: 21
lucasarts_18 Va por buen camino
Cita:
Empezado por Lepe
De mayor quiero ser como roman
mmmmm....mejor me voy a dormir que me dió sueño.
Quizás mañana aprenda de verdad, claro después de un buen sueño

Hasta Luego -
__________________
No todo es como parece ser...
Responder Con Cita
  #17  
Antiguo 19-11-2005
Mathom Mathom is offline
Miembro
 
Registrado: nov 2005
Posts: 72
Poder: 19
Mathom Va por buen camino
que puedo decir después de toda la expicación....muchas gracias a todos y en especial a Roman.

Ahora sólo me queda aplicar lo que me has dicho y leerme el sitio que me has aconsejado e intentarlo...ya os diré como voy quedando.
Responder Con Cita
Respuesta



Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro


La franja horaria es GMT +2. Ahora son las 21:30:46.


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
Copyright 1996-2007 Club Delphi