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 12-03-2010
_CALI _CALI is offline
Miembro
 
Registrado: mar 2008
Posts: 99
Poder: 17
_CALI Va por buen camino
ayuda con el evento OnValidate!!

Hola amigos, voy a resumir lo mas que pueda el problema q tengo y quisierea que por favor me ayudaran :

tengo un DBGrid asociado a Table1, y un boton




en el evento OnClick del boton tengo esto:

Table1.Append;
Table1.FieldByName('codigo').AsString := '005';
Table1.Post;
****************************
en el evento OnValidate del campo 'codigo' tengo esto:

Showmessage(Sender.Text);
Abort;
****************************
tengo registros cuyos valores en 'codigo' son 001,002,003 y 004;
mi problema es q cuando hago click en el boton, el DBGrid o mejor dicho el Dataset repite todos los valores contenidos en el campo 'codigo' a 005 , en vez que solo se afecte al nuevo registro que estoy ingresando.

Muchas Gracias!!!
Responder Con Cita
  #2  
Antiguo 12-03-2010
BrunoBsso BrunoBsso is offline
Miembro
 
Registrado: nov 2009
Ubicación: Berisso, Buenos Aires, Argentina
Posts: 239
Poder: 15
BrunoBsso Va por buen camino
Probá con Insert en vez de Append.
Si el campo codigo se ordena automáticamente, el nuevo dato 005 debería ponerse último.
Probalo y después comentá si te sirvió.
Saludos!
Responder Con Cita
  #3  
Antiguo 12-03-2010
_CALI _CALI is offline
Miembro
 
Registrado: mar 2008
Posts: 99
Poder: 17
_CALI Va por buen camino
probe con insert y me sigue causando ese problema

Cita:
Empezado por BrunoBsso Ver Mensaje
Probá con Insert en vez de Append.
Si el campo codigo se ordena automáticamente, el nuevo dato 005 debería ponerse último.
Probalo y después comentá si te sirvió.
Saludos!

probe con insert y me sigue causando ese problema
Responder Con Cita
  #4  
Antiguo 12-03-2010
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
Cita:
Empezado por _CALI Ver Mensaje
repite todos los valores contenidos en el campo 'codigo' a 005 , en vez que solo se afecte al nuevo registro que estoy ingresando.
¿Podrías aclarar a que te refieres? ¿Se coloca el valor 005 en todos los registros previos?

// Saludos
Responder Con Cita
  #5  
Antiguo 12-03-2010
_CALI _CALI is offline
Miembro
 
Registrado: mar 2008
Posts: 99
Poder: 17
_CALI Va por buen camino
Cita:
Empezado por roman Ver Mensaje
¿Podrías aclarar a que te refieres? ¿Se coloca el valor 005 en todos los registros previos?

// Saludos
asi es;
es que lo quiero a grandes rasgos es mostrar un mensaje advirtiendo que no existe el codigo que se esta ingresando en mi tabla1, abortando luego la grabacion de dicho registro, en este caso el codigo 005 no existe , los codigos los jalo de otra tabla (tabla2) y esta tabla solo tinene los codigos 001,002,003 y 004

OnValidate del campo 'codigo' de tabla1

if not tabla2.locate('codigo', '005', []) then
begin
Showmessage('el codigo no existe');
Abort;
end;

previamnete mi tabla 1 ya tiene 4 registros bien validados q son el 001,002,003 y 004
cuando intento ingresar el 005
la columna que representa al campo 'codigo' de la tabla 1 muestra en todas sus filas el valor 005 cuando aparece le mensaje
pero se restablecen cuando pulso Ok en el mensaje

Gracias por responder y porsupuesto por la ayuda
Responder Con Cita
  #6  
Antiguo 12-03-2010
Avatar de Al González
[Al González] Al González is offline
In .pas since 1991
 
Registrado: may 2003
Posts: 5.604
Poder: 30
Al González Es un diamante en brutoAl González Es un diamante en brutoAl González Es un diamante en brutoAl González Es un diamante en bruto
El problema tiene que ver con la forma en que trabajan los métodos SetData, Validate y GetData de la clase base nativa TField.

Primero, el método SetData establece en el campo (variable) FValueBuffer el valor que está por ser asignado al campo:

Código Delphi [-]
procedure TField.SetData(Buffer: Pointer; NativeFormat: Boolean = True);
begin
  if FDataSet = nil then DatabaseErrorFmt(SDataSetMissing, [DisplayName]);
  FValueBuffer := Buffer;
  try
    FDataSet.SetFieldData(Self, Buffer, NativeFormat);
  finally
    FValueBuffer := nil;
  end;
end;

Luego el método SetFieldData del conjunto de datos (sea BDE, ADO, etc.), llama al método Validate del campo:

Código Delphi [-]
procedure TBDEDataSet.SetFieldData(Field: TField; Buffer: Pointer);
var
  RecBuf: PChar;
  Blank: LongBool;
begin
  with Field do
  begin
    if not (State in dsWriteModes) then DatabaseError(SNotEditing, Self);
    if (State = dsSetKey) and ((FieldNo < 0) or (FIndexFieldCount > 0) and
      not IsIndexField) then DatabaseErrorFmt(SNotIndexField, [DisplayName]);
    GetActiveRecBuf(RecBuf);
    if FieldNo > 0 then
    begin
      if State = dsCalcFields then DatabaseError(SNotEditing, Self);
      if ReadOnly and not (State in [dsSetKey, dsFilter]) then
        DatabaseErrorFmt(SFieldReadOnly, [DisplayName]);
      Validate(Buffer);
...

El método TField.Validate es quien se encarga de llamar al evento OnValidate, estableciendo temporalmente una bandera, FValidating, en True:

Código Delphi [-]
procedure TField.Validate(Buffer: Pointer);
begin
  if Assigned(OnValidate) then
  begin
    { Use the already assigned FValueBuffer if set }
    if FValueBuffer = nil then
      FValueBuffer := Buffer;
    FValidating := True;
    try
      OnValidate(Self);
    finally
      FValidating := False;
    end;
  end;
end;

Dicha bandera tiene efecto en la forma en que trabaja el método TField.GetData, el cual se ejecuta siempre que algo requiere leer el valor del campo.

Código Delphi [-]
function TField.GetData(Buffer: Pointer; NativeFormat: Boolean = True): Boolean;
begin
  if FDataSet = nil then DatabaseErrorFmt(SDataSetMissing, [DisplayName]);
  if FValidating then
  begin
    Result := LongBool(FValueBuffer);
    if Result and (Buffer <> nil) then
      CopyData(FValueBuffer, Buffer);
  end else
    Result := FDataSet.GetFieldData(Self, Buffer, NativeFormat);
end;

Como puede verse, cuando no se está ejecutando el método Validate (FValidating es False), el valor del campo es obtenido a través del método GetFieldData del conjunto de datos, el cual traerá el valor real del campo que corresponda a la fila actual.

Pero si la bandera FValidating es True, el valor NO será leído del registro actual, sino del buffer FValueBuffer establecido desde que se llamó a TField.SetData (cuando la captura del dato fue recién ingresada).

El problema con este mecanismo ya tan antiguo de la VCL es que si, durante la ejecución del evento OnValidate, algo necesita leer el valor del campo en cuestión pero de diferentes filas —tal como ocurre siempre en un control TDBGrid cuando éste se despliega—, se estará leyendo y dibujando en pantalla el mismo valor para todos los registros.

Cuando la validación termina, el método Validate vuelve a poner la bandera FValidating en False, permitiendo que, la siguiente vez que la rejilla se dibuje, el método GetData lea el valor del registro real y ya no del buffer temporal FValueBuffer.

Saludos.

Al González.

Última edición por Al González fecha: 22-03-2010 a las 04:09:50.
Responder Con Cita
  #7  
Antiguo 12-03-2010
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
Interesante Al. Como dices, no es recomendable recorrer el dataset en uno de sus eventos. Como no da mayores detalles no se me ocurrió que quizá tuviera enlazadas ambas tablas. De hecho, me uno a la invitación de exponer más claramente el código y el contexto. De entrada, la condición

Código Delphi [-]
if not tabla2.locate('codigo', '005', []) then

no parece ser correcta, lo que me sugiere que no nos está poniendo el código realmente usado.

// Saludos
Responder Con Cita
  #8  
Antiguo 12-03-2010
_CALI _CALI is offline
Miembro
 
Registrado: mar 2008
Posts: 99
Poder: 17
_CALI Va por buen camino
Smile

***************************************
realmante es muy interesante lo q dices, es bueno saber el orden de los eventos como se disparan.

Bueno; Basicamente hago refernecia a dos conjuntos de datos , una es una tabla donde almaceno mis productos representado por un ADOTable (tbArticulos) y el otro es una lista de precios para mis productos representado por un ADOQuery (qryListaPrecios), ademas tengo un formulario de busqueda de articulos

como mensione antes tengo un DBGrid conectado a qryListaPrecios
donde el campo1 almacena el item del registro, el campo2(id_articulo) es donde ingreso el codigo del articulo ya sea digitandolo o llamando al formulario de busqueda de articulos

aqui les muestro el codigo real

Código Delphi [-]
//procedimiento para llamar al formulario donde busco el articulo
procedure TfrmListaPrecios.BuscarProducto;
begin
 frmBuscarArticulo := TfrmBuscarArticulo.Create(Application);

  try
    if frmBuscarArticulo.ShowModal = mrOk then
       begin
       if qryListaprecios.State = dsBrowse then
          qryListaprecios.Edit;
          //le envio el codigo del articulo a id_articulo de mi lista de precios
          qryListaprecios.FieldByName('id_articulo').AsString
          :=    frmBuscarArticulo.qryBuscarArticulo.FieldByName('id_articulo').AsString;
      end;
   finally
     frmBuscarArticulo.Free;
  end;

end;


//validaciones a nivel de campo para id_articulo

procedure TfrmListaPrecios.qryListapreciosid_articuloValidate(
  Sender: TField);
begin
     {buscar en articulos}
  if not tbArticulos.Locate('id_articulo', Sender.Text, []) then
     begin
       MessageDlg('No existe el producto', mtWarning, [mbOk], 0);
       Abort;
     end;
    {si existe el articulo, buscar en la lista de precios}
     Query1.Close;
     Query1.SQL.Clear;
     Query1.SQL.Add('select id_articulo from _listaprecios_detalle');
     Query1.SQL.Add('where id_articulo = ''' + Sender.Text + '''' );
     Query1.SQL.Add('and id_listaprecios = ''' + cboLista.KeyValue + '''' );
     Query1.Open;

     if not Query1.IsEmpty then {si existe en la lista de precios}
        begin

        MessageDlg('Ya existe el producto en lista de precios actual',   mtWarning, [mbOk], 0);

        Abort;
        end;

        //si todo va bien completar campos restantes
         qryListaprecios['UM_compra'] := tbArticulos['um_compra'];
         qryListaprecios['UM_venta'] := tbArticulos['um_venta'];
         qryListaprecios['UM_consumo'] := tbArticulos['um_consumo'];
         qryListaprecios['precio_compra'] := 0;
         qryListaprecios['precio_venta'] := 0;
         qryListaprecios['precio_consumo'] := 0;
         qryListaprecios['precio_compra'].FocusControl;


end;


//cuando apreto f1 en la segunda columna, llamar a mi formulario de busqueda

procedure TfrmListaPrecios.DBGrid1KeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
  if (Key = VK_F1) and (DBGrid1.selectedIndex = 1) then
      BuscarProducto;


end;


cuando ingreso tecleando en el campo id_articulo (segunda columna de mi grilla) no hay problema, si digamos ingreso un articulo q ya esta registrado en la lista de precios aparece el mensaje advirtiendome q ya existe en la lista de precios actual y luego aborta la oparacion sin problemas

el problema es es cuando presiono F1 para llamar a mi formulario de busqueda y selecciono un articulo que ya esta ingresado en la lista de precios, al momento de aparecer el mensaje es donde se repite en valor del articulo validado en todas las filas, pense que se trataria de formulario de busqueda o d mi query pero me di cuenta que resumiendolo hasta lo mas sencillo causa ese problema con BDE, ADO tabla y/o consulta

aunque pasando la logica al evento Onchange y BeforePost, resulta bien, pero me gustaria saber si se puede gestionar las validaciones en OnValidate


Muchas Gracias denuevo!!!!

Última edición por _CALI fecha: 17-03-2010 a las 13:58:47. Razón: editar sintaxis delphi
Responder Con Cita
  #9  
Antiguo 14-03-2010
Avatar de Al González
[Al González] Al González is offline
In .pas since 1991
 
Registrado: may 2003
Posts: 5.604
Poder: 30
Al González Es un diamante en brutoAl González Es un diamante en brutoAl González Es un diamante en brutoAl González Es un diamante en bruto
Hola de nuevo _Cali.

Por favor usa las etiquetas Delphi para que tu código no pierda el sangrado y pueda leerse con mucho mayor facilidad.

Esto lo puedes hacer fácilmente editando tu último mensaje, seleccionando todo lo que es código y oprimiendo el pequeño botón que parece un partenón en miniatura, a la izquierda del botón SQL ("Resaltar sintaxis Delphi").

Gracias.
Responder Con Cita
  #10  
Antiguo 17-03-2010
_CALI _CALI is offline
Miembro
 
Registrado: mar 2008
Posts: 99
Poder: 17
_CALI Va por buen camino
Smile

Cita:
Empezado por Al González Ver Mensaje
Hola de nuevo _Cali.

Por favor usa las etiquetas Delphi para que tu código no pierda el sangrado y pueda leerse con mucho mayor facilidad.

Esto lo puedes hacer fácilmente editando tu último mensaje, seleccionando todo lo que es código y oprimiendo el pequeño botón que parece un partenón en miniatura, a la izquierda del botón SQL ("Resaltar sintaxis Delphi").

Gracias.

Ok, ya esta con las estiquetas obviamnete se ve mucho mejor, Al Gonzales, espero puedas ayudarme con esto
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

Temas Similares
Tema Autor Foro Respuestas Último mensaje
onvalidate lejia Varios 12 12-10-2007 22:08:49
como validar en el evento onvalidate con numeros... uper Varios 1 25-10-2005 20:06:49
OnValidate javiermorales OOP 5 13-11-2003 15:52:52
ayuda sobre evento en php jfvoviedo PHP 2 22-08-2003 16:12:04
ayuda sobre evento en php jfvoviedo PHP 6 26-07-2003 18:24:22


La franja horaria es GMT +2. Ahora son las 04:16:40.


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