PDA

Ver la Versión Completa : No entra al evento OnPostError


Pablo Carlos
16-04-2005, 16:54:32
Hola gente... tengo este código...

procedure TdmTablas.tblBibliotecaPostError(DataSet: TDataSet;
E: EDatabaseError; var Action: TDataAction);
begin
ShowMessage('Hola error');
end;

Al provocar un error en el post jamás sale mi saludito, es como que no existe ese evento...
Alguna sugerencia...
Gracias Pablo

marcoszorrilla
16-04-2005, 17:11:20
Pues tiene que funcionar, lo que puede pasar es que estés haciendo la prueba en tiempo de diseño y entonces te saldrá antes el mensaje de Delphi, pero si pulsas Aceptar y luego F8 al final se verá tu mensaje.

Un Saludo.

Pablo Carlos
16-04-2005, 17:22:56
Gracias por responder
Pues tiene que funcionar, lo que puede pasar es que estés haciendo la prueba en tiempo de diseño.-

Te comento que no funciona tanto dentro o fuera de delphi.- (corriendo normal o ejecutando desde delphi) :confused:
Saludos

marcoszorrilla
16-04-2005, 17:27:59
Lo cierto es que yo acabo de probarlo y si me funciona, lo que he hecho es duplicar un registro con un campo con clave única.

Primer erro:.......Key violation.
F8
Erroorr


procedure TForm1.Table1PostError(DataSet: TDataSet; E: EDatabaseError;
var Action: TDataAction);
begin
ShowMessage('Errooor.');
end;


Un Saludo.

Pablo Carlos
16-04-2005, 17:40:18
Lo cierto es que yo acabo de probarlo y si me funciona, lo que he hecho es duplicar un registro con un campo con clave única.

Te comento, aunque parezca cosas de brujas, he creado una tabla nueva (paradox) con tres campos uno autoincremental, uno apellido y otro fecha.
En OnPostError de la tabla nueva pongo el ShowMessage y lleno mal el campo fecha (00/00/0000) y dentro o fuera de delphi no sale el mensaje :confused:
Gracias por responder tan rápido
Saludos

Lepe
16-04-2005, 18:19:40
claro que no da error.

Al campo apellido, en el database desktop, marcale la casilla Required. Despues de eso, añade un registro, deja el apellido en blanco y dale a guardar. Ahora si sale el error.

El BDE solo mostrará los errores cuando:
- Un campo es requerido (lo dicho anteriormente)
- un campo en cuestion, tiene un índice único creado, y se repite el valor en 2 registros.
- La clave primaria de la tabla se repite. En tu caso, es un autoincremento, por tanto, jamás vas a tener problemas de clave primaria ...(salvo errores graves)

Para introducir una fecha correcta, tu aplicación debe tener un TdateTimePicker, por ejemplo, para validar que la fecha que se guarde, sea una correcta.

Un saludo

Lepe
16-04-2005, 18:26:55
bueno.... en realidad puede dar muchos más errores el BDE. El tema está en que el BDE debe entender si "debe lanzar un error o no", y para ello, se lo tienes que decir tú de alguna forma (indices únicos, requerir un campo, etc.)

Si no pones ninguna restricción, el BDE acepta barco como animal acuático ;)

Un saludo de nuevo

Pablo Carlos
16-04-2005, 18:30:09
Hola Lepe... gracias por responder... te comento que me parece que si debería capturar el error de la fecha. Mira este código, es de la demo de delphi

const
{Declare constants we're interested in}
eKeyViol = 9729;
eRequiredFieldMissing = 9732;
eForeignKey = 9733;
eDetailsExist = 9734;
eFechaNoValidad = 10059;


implementation

{$R *.DFM}

procedure TDM.CustomerPostError(DataSet: TDataSet;
E: EDatabaseError; var Action: TDataAction);
begin
if (E is EDBEngineError) then
if (E as EDBEngineError).Errors[0].Errorcode = eFechaNoValida then
begin
MessageDlg('Fecha no valida.', mtWarning, [mbOK], 0);
Abort;
end;
end;

A la Const le agrego el 10059 que corresponde a fecha no válida (y esto sacado de delphi, usando la demo, y tampoco me lo captura
Saludos

Pablo Carlos
16-04-2005, 19:12:54
Hola... hice la prueba de ponerle campo requerido y tampoco sale el error, es como si mi OnPostError no existe, fallecio, crepo, colgo los tenis, se puso el sobretodo de madera, etc, etc... :D :D
Saludos

Pablo Carlos
16-04-2005, 23:45:38
Será la versión de Windows... tengo 2000 prof
Saludos

Pablo Carlos
17-04-2005, 01:07:41
Bue... este sigo aqui.
comento hice la siguiente prueba... puse un label en el form y en el evento OnPostError el siguiente código

if E is EDBEngineError then
begin
form1.label4.Caption := IntToStr((E as EDBEngineError).Errors[0].Errorcode);

Con esto verifico que si entra en el evento y no hay caso (se supone que la propiedad caption del label me daría el número de error)
Errores con que hice pruebas son dos -> 1.- fecha (le ingrese 00/00/0000) y 2.- un campo lo tengo como requerido -> no llene dicho campo y guarde.
En ningún caso el label me acuso el número de error.-
Saludos

marcoszorrilla
17-04-2005, 10:05:55
El error en la fecha no es del BDE sino de la VCL, mira yo lo he traducido y recompilado.

Const.Pas

unit Consts;

interface

resourcestring
SOpenFileTitle = 'Open';
......
//SMaskEditErr = 'Invalid input value. Use escape key to abandon changes';
SMaskEditErr = 'Valor incorrecto de entrada. Pulse escape para abandonar
.....

Un Saludo.

Lepe
17-04-2005, 10:13:18
Alguna tontería estará pasando, porque eso debe fallar fijo.


if E is EDBEngineError then
form1.label4.Caption := IntToStr((E as EDBEngineError).Errors[0].Errorcode)
else
raise;

Pablo Carlos
17-04-2005, 15:15:01
Gracias marcoszorrilla ya tenemos el tema de fecha lo hare en el evento exit del dbedit pero el BDE tiene al error $274B (10059) = Invalid Date.
Gracias Lepe seguramente debe ser una tontería pero llevo desde el jueves tratando esa tonteria :( . Hasta reinstale el delphi. Pero es muy raro que no entre al evento OnPostError. Debe estar faltando algo que no logro verlo.-
Gracias de todos modos
Saludos

Pablo Carlos
17-04-2005, 16:12:48
Alli adjunto el prg de prueba para tratamiento de errores. si pueden verlo, les agradecería.- (no hay prolijidad ni nada sólo tire los componentes)
Gracias

Lepe
18-04-2005, 09:48:27
Acabo de ejecutar tu programa y el fallo es el siguiente:

-El campo nombres debes indicar que es REQUERIDO en el Database Desktop, tu lo tienes en delphi, por tanto el error no lo controla el bde, sino delphi, y por tanto, los labels no se actualizan.

Basta con que lo hagas en el database desktop, para ver que ahora, efectivamente los labels si muestran el error 9732 en tu caso.

if (E is EDBEngineError) then
begin
form1.label4.Caption := IntToStr(EDBEngineError(e).Errors[0].Errorcode);
if EDBEngineError(e).Errors[0].ErrorCode = 9732 then
begin
ShowMessage(' fecha incorrecta');
Action := daAbort;
end;
end

Con esta modificación, sacas tu mensaje y eliminas el propuesto por el BDE.

Por cierto, una vez modificado el campo en el Database desktop, vete a la tabla en delphi, borra el campo modificado y añadelo de nuevo para que actualice todas sus propiedades.

Un saludo

Pablo Carlos
19-04-2005, 01:41:12
Hola Lepe... aunque no lo creas sigue sin salir el error... de todos modos ya se ha extendido demasiado este hilo y bue... ya encontraré de que se trata.-
Te agradezco la molestia...
Saludos

marcoszorrilla
19-04-2005, 07:04:12
El hilo puede y debe extenderse todo lo que seea necesario, por otra parte dices que ya encontraste el error, pues sería conveniente que lo publicaras para que todos aquellos que hayan seguido el hilo sepan cual fue la posible solución.

Un Saludo.

Nelson Polanco
19-04-2005, 17:24:52
Hola, foristas Soy Nelson Polanco nuevo en este foro, me gusta buscar y compartir ideas.
Disculpenme, mi opinion es que el error si funciona, lo que pasa es que hay que provocar una excepcion que corresponda a este tipo de evento. Ejemplo Key_violation es un tipo de excepcion de EDatabaseError, por eso aparece. Verificas en la ayuda sobre EDatabaseError para ampliar. Suerte.

Lepe
19-04-2005, 17:51:29
Subo el archivo modificado.

Modificaciones:

Hay un error, por defecto Delphi crea un componente Tsession, y tu tenias otro en el datamodule, modificabas 1 parametro del Session1 (el tuyo) y otro parámetro del Session (que crea delphi).

Por tanto la configuración no era correcta. La solución tomada es quitar el que tu pusiste y usar el que propone delphi.

Por otro lado, he puesto Requerido en el Database desktop el campo Nombres y el campo Apellidos, Pero en delphi, haciendo doble clic sobre la tabla le quito la propiedad REquired a ambos campos; ¿por qué? bueno, acabo de ver que si tienes en delphi el campo requerido, el error que se produce no lo controla el BDE, sino el propio delphi, por tanto tampoco se actualizan los campos.

Ahora no tengo tiempo para mirarlo más a fondo, pero el archivo adjunto furula muy bien.

Solo un detalle más. Yo he creado una carpeta en C:\PRUEBA y dentro está todo, las tablas y el proyecto, para que no difiera en tu ordenador, haz lo mismo.

Un saludo

Lepe
19-04-2005, 18:04:46
Vale, mirando un poco más, el error que se produce es de tipo EDatabaseError

Recordemos que EDBEngineError hereda de EDatabaseError, pero al estar en delphi puesto como Requerido, el error que salta es de tipo EDatabaseError a secas.

Para que se produzca el EDBEngineError, hay que poner el campo requerido en el Database Desktop, y quitar el requerido en delphi.

Creo que ahora me he explicado mejor. (o eso espero :D)

Y.... ahora si sale.


Todo esto se puede comprobar poniendo un BreakPoint en la linea:

if (E is EDBEngineError) then
begin
form1.label4.Caption := IntToStr(EDBEngineError(e).Errors[0].Errorcode);
if EDBEngineError(e).Errors[0].ErrorCode = 9732 then
begin
ShowMessage(' Campo Requerido');
Action := daAbort;
end
end
else if (E is EDatabaseError) then
ShowMessage('database error');

Y modificando en Delphi las propiedades Required de ambos campos.

otro saludo de nuevo.

Pablo Carlos
19-04-2005, 22:51:48
Gracias marcoszorrilla por la paciencia y la extensión... quizas me haya expresado mal pero no he encontrado la solución y de hecho en cuanto sepa que paso (como en todos los hilos que inicie) lo publicaré

Todo esto se puede comprobar poniendo un BreakPoint en la linea:

Gracias Lepe... todo lo básico no tengo problemas... el problema es que por más que ponga un break ni siquiera entra a ese evento... (ponga o no el break... como dije en los anteriores es como si el evento no existiera), cuando se produce el error el cursor se "para" en la línea que hago el ShowModal del formulario que quiero capturar el error.
por ejemplo

procedure TdmTablas.tblBibliotecaPostError(DataSet: TDataSet;
E: EDatabaseError; var Action: TDataAction);
begin
if (E is EDBEngineError) then
frmBiblioteca.label4.Caption := IntToStr(EDBEngineError(e).Errors 0].Errorcode); //aqui pongo el breac
end;
///////////////////
procedure TfrmNivelUno.Biblioteca1Click(Sender: TObject);
begin
frmBiblioteca := TfrmBiblioteca.Create(Application);
try
frmBiblioteca.ShowModal; // aqui se posiciona el cursor cuando da error
finally
frmBiblioteca.Free;
end;
end;

Ahora estará mas claro :D
Debe haber "algo en delphi" que me anule ese evento y por lo tanto no pueda capturar el error.-
Los errores que intento capturar son varios, fecha, campo requerido, key violation, formato hora, y algún otro por lo que estoy probando con todas esas alternativas
Saludos

Pablo Carlos
20-04-2005, 02:14:01
:eek: :eek: :eek:
Señores... cuando el campo es requerido en el desktop (asi lo tenía) en delphi debe estar en "false" aunque cuando lo traes mediante el table se pone requerido = true (es lógico) se debe pasar a false... ya probe de esa manera y funcionó.- (idea, consejo, estudio del Sr. Lepe) en cuanto a la fecha, aunque lo contemple el BDE con el número de error 10059, deberá tratarse en el evento onexit del dbedit.- (idea, consejo, estudio del Sr. marcoszorrilla) y a todos los que participaron de este hilo muuuuuchas gracias. Empezaré a "retocar mi aplicación"
Saludos

roman
20-04-2005, 03:25:09
en cuanto a la fecha (...) deberá tratarse en el evento onexit del dbedit

No creo que esto te funcione. La validación de la fecha se hace antes de que se genere dicho evento.

// Saludos

Lepe
20-04-2005, 13:20:16
Señores... cuando el campo es requerido en el desktop (asi lo tenía) en delphi debe estar en "false" aunque cuando lo traes mediante el table se pone requerido = true (es lógico) se debe pasar a false...

En realidad depende de lo que quieras hacer. EDatabaseError, es una excepción más abstracta, que engloba tanto al BDE, como ADO, como otra tecnología de acceso a Bases de datos, así que podríamos tratar el error directamente para mostrar un mensaje general: " Por favor introduzca todos los campos marcados con asterisco"; y de un plumazo nos quitamos de problemas.

EDBEngineError es más concreto, de hecho, para el acceso a datos mediante BDE, por eso tenemos que hacer ese pequeño truco de quitar el "required en Delphi" ... o al menos eso deduzco yo :D

Pablo Carlos
21-04-2005, 00:35:17
Gracias Roman... ya hare las pruebas para tratar de elegir el mejor evento...
:eek: :eek: :eek: Gracias Lepe y como si esto fuera poco "un postresito"
Lo que más me gusta de este Club es que además de no dejarte sólo es que no te "tiran" el código necesario (en muchos casos) sino que, además, hay una fundamentación, explican el por qué, y eso es muchisimo. En alguna oportunidad he dejado el código que creia correcto y listo, quizas por tiempo (muy tirano) o por comodidad. Prometo tomar el ejemplo de todos ustedes y en la medida que tenga el fundamento lo pondré.- Eso es todo, me despido con este antigüo versito infantil.- :D
"El club enseña, el club entretiene
y yo les digo contento,
hasta la clase que viene" :p
Saludos

roman
21-04-2005, 02:27:37
ya hare las pruebas para tratar de elegir el mejor evento...


Lamento informarte que creo que no lo encontrarás.

Hasta donde he visto la situación es así: cuando intentas pasar el foco a otro control, Delphi genera el mensaje CM_EXIT. El DBEdit maneja este mensaje más o menos así:



Validate;
DoExit;


Es en Validate (el nombre no es exacto) donde se produce la excepción y no es sino hasta DoExit donde se llama al evento OnExit, pero en caso de una excepción nunca se llega a este procedimiento.

Antes de CM_EXIT lo que hay son eventos del DataLink asociado al DBEdit (que es interno) y del DataSource. Quizá pudieras usar este último pero no estoy seguro de que se adaptara a tus necesidades.

Lo que yo posiblemente haría es crear un descendiente de TDBEdit que, o bien redefina el método Validate (no recuerdo si es virtual o no) o bien que reimplemente el manejador del mensaje CM_EXIT.

// Saludos

Pablo Carlos
24-04-2005, 23:22:07
Gracias Roman...
Lamento informarte que creo que no lo encontrarás.

Tienes razon... (comprobado)

Antes de CM_EXIT lo que hay son eventos del DataLink asociado al DBEdit (que es interno) y del DataSource. Quizá pudieras usar este último pero no estoy seguro de que se adaptara a tus necesidades.

Vuelves a tener razon :eek:

Lo que yo posiblemente haría es crear un descendiente de TDBEdit

Creo que sería lo más saludable y terminaríamos el problema de raiz, me pondre en ello.-
Gracias por tus explicaciones.-
Saludos