Club Delphi  
    Paypal   FTP   CCD     Buscar   Trucos   Trabajo   Foros

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

Coloboración Paypal con ClubDelphi

 
 
Herramientas Buscar en Tema Desplegado
  #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.610
Poder: 32
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
 



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 09:23:42.


Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi
Copyright 1996-2007 Club Delphi