Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Varios (https://www.clubdelphi.com/foros/forumdisplay.php?f=11)
-   -   A ver, una consulta rápida (https://www.clubdelphi.com/foros/showthread.php?t=68438)

AzidRain 14-06-2010 00:16:59

A ver, una consulta rápida
 
Tengo un formulario que edita los campos de una tabla x. La tabla tiene tantos campos que a duras penas caben todos en el formulario de manera que implementé 2 formularios auxiliares para editar algunos campos que solo se usan ocasionalmente.

Lo que hago es abrir la tabla, ponerla en modo edición o inserción según el caso, y luego abro el formulario, el cual esta ligado mediante Datasources con sus campos correspondientes. Los formularios auxiliares tienen sus campos (dbedits) también ligados a la misma tabla de manera que mediante unos botones en el formulario principal abro el auxiliar que se requiera segun el caso y ahi edito los campos.

Hasta aquí no hay problema, pero ahorita revisando, se supone que los formularios auxiliares tendrán 2 botones: "cancelar" y "aceptar". En el caso de aceptar no hay problema con simplemente cerrar el formulario los datos ya están "guardados" en el registro que se está editando o insertando, sin embargo en el caso de "cancelar" no se me ocurre una idea "elegante" de borrar todos los cambios hechos a los campos (recordemos que el registro aún no ha sido posteado ya que el Post lo hace el formulario principal) que no sea la de recorrer los databindings de los controles de estos formularios y limpiar manualmente sus valores. Un simple "for cada control en el formulario limpia los datos del campo que tenga ligado".

Igual y me estoy complicando mucho...pero a lo mejor a a alguien se le ocurre una solución mas elegante.

Saludos...

Casimiro Notevi 14-06-2010 00:29:31

Si he entendido bien, son componentes asociados a un datasource, entonces para "limpiarlos" será suficiente un cancel, no?

dado 14-06-2010 01:15:06

Yo te recomendaria usar un ScrollBox, asi en un solo formulario tendrias todos los campos que necesitas.

Adicional al ScrollBox, tambien he usado GroupBox 's para agrupar los TEdit

AzidRain 14-06-2010 01:59:08

Si Casimiro, pero si hago un cancel elimino el total de los campos lo cual no es lo que quiero. Sino digamos que un formulario "principal" edita los 50 principales campos y un auxiliar edita unos 5 o 7 ocasionales (que casi siempre quedan vacios), si hago un cancel en el auxiliar voy a eliminar el contenido de los 50 campos que si deben llevar datos. La solución del scrollbox no funciona porque los campos adicionales a editar no todos son tedits, sino hay memos y otras cosas. Como ya les comenté tengo ya una solución solo quiero explorar alguna otra alternativa.

Casimiro Notevi 14-06-2010 02:14:23

No había entendido bien la pregunta. Creo que no te queda más que recorrerlos. Puede que te venga bien añadirle un valor en la propiedad 'tag (por ejemplo), para diferenciar los que están en cada form.

dado 14-06-2010 03:23:21

1 Archivos Adjunto(s)
Cita:

Empezado por AzidRain (Mensaje 367173)
Si Casimiro, pero si hago un cancel elimino el total de los campos lo cual no es lo que quiero. Sino digamos que un formulario "principal" edita los 50 principales campos y un auxiliar edita unos 5 o 7 ocasionales (que casi siempre quedan vacios), si hago un cancel en el auxiliar voy a eliminar el contenido de los 50 campos que si deben llevar datos. La solución del scrollbox no funciona porque los campos adicionales a editar no todos son tedits, sino hay memos y otras cosas. Como ya les comenté tengo ya una solución solo quiero explorar alguna otra alternativa.

Los Scrollbox son contenedores, igual que los Form. Eso significa que pueden contener a cualquier otro objeto, incluso otros scrollbox.

Te dejo un ejemplo, si te sirve.............

Neftali [Germán.Estévez] 14-06-2010 10:53:38

Cita:

Empezado por AzidRain (Mensaje 367169)
...no se me ocurre una idea "elegante" de borrar todos los cambios hechos a los campos (recordemos que el registro aún no ha sido posteado ya que el Post lo hace el formulario principal) que no sea la de recorrer los databindings de los controles de estos formularios y limpiar manualmente sus valores. Un simple "for cada control en el formulario limpia los datos del campo que tenga ligado".

Ese form se puede hacer utilizando RTTI. Posees funciones para saber si un componente posee una propiedad (DataField) y también para conocer el valor que tiene. Con eso debería bastar para poder realizar ese FOR, que necesitas.

Con un ADOTable sería así:

Código Delphi [-]
procedure TForm1.Button2Click(Sender: TObject);
var
  i:integer;
  b:Boolean;
  vprop:string;
  comp:TComponent;
begin
  // recorrido
  for i := 0 to (Self.ComponentCount - 1) do begin
    // componente
    comp := Self.Components[i];
    // Tiene la propiedad
    b := ExistProp(comp, 'DataField');
    if (b) then begin
      // Obtener el valor
      vprop := GetPropAsString(comp, 'DataField');
      // Tiene la prop. rellena?
      if (vprop <> '') then begin
        // posee la propiedad
        ADOTable1.FieldByName(vprop).Clear;
      end;
    end;
  end;
end;

Te adjunto las 2 funciones que aparecen; ExistProp y GetPropAsString; Sólo te queda añadir al USES la unit TypInfo.

Código Delphi [-]
function ExistProp(Instance: TObject; const PropName: string):Boolean;
var
  PropInfo: PPropInfo;
begin
  // Busca la propiedad y deviuelve la estructura nil
  PropInfo := GetPropInfo(Instance, PropName);
  Result := not (PropInfo = nil);
end;

{:Recupera valor a una propiedad a través de su nombre (via RTTI).}
function GetPropAsString(AObj: TObject; const PropName:String):String;
const
  EBLOCK = 'SetPropAsString';
var
  PInfo: PPropInfo;
  LObject: TObject;
Begin

  Result := '';

  // Existe la propiedad
  if not ExistProp(AObj, PropName) then begin
    Exit;
  end;

  // Intentamos acceder (con un puntero) a la info. de la propiedad
  PInfo := GetPropInfo(AObj.ClassInfo, PropName);

  // Se ha encontrado la propiedad con éste nombre; Chequear el tipo...
  if (PInfo^.Proptype^.Kind = tkString) or
     (PInfo^.Proptype^.Kind = tkLString) or
     (PInfo^.Proptype^.Kind = tkWString) then begin
    // Obtener el resulatado
    Result := GetStrProp(AObj, PInfo);
  end
  else if (PInfo^.Proptype^.Kind = tkInteger) then begin
    // recuperar el valor...
    Result := IntToStr(GetInt64Prop(AObj, PInfo));
  end
  else if (PInfo^.Proptype^.Kind = tkEnumeration) then begin
    Result := GetEnumProp(AObj, PInfo);
  end
  else if (PInfo^.PropType^.Kind = tkClass) then begin

    LObject := GetObjectProp(AObj, PInfo);
    // Nada...
    if (LObject <> nil) then begin
      // Es un componente?
      if (LObject is TComponent) then begin
        Result := TComponent(LObject).Name;
        LObject.Free;
      end;
    end;
  end
  else begin
    Result := '';
  end;

end;

roman 14-06-2010 18:24:21

Estimado AzidRain, te recomiendo darle una repasada a la guía de estilo, en particular, lo correspondiente al título de los mensajes.

// Saludos

AzidRain 15-06-2010 20:11:12

Gracias por el jalón de orejas Román, al final esto fue lo más compacto que pude hacer:

Código Delphi [-]
var
  I: Integer;
begin
   for I := 0 to ComponentCount - 1 do
   Begin
     If Components[i] is TcxDBTextEdit Then
       TcxDBTextEdit(Components[i]).Text := '';
   End;

afunez2007 15-06-2010 20:28:35

Hola AzidRain

Yo cuando tengo casos de formularios que tienen muchos datos, hago 2 cosas:
1era: Organizar todos los campos en TPageControls, y creo tantas paginas como necesite en el formulario, una sola barra de herramientas, puesto que se trabaja en la misma tabla.

2do: Deje de utilizar dbedits, y los sustitui por edits normales o currency edtis para campos floats e intedits para enteros, datetimepickers para fechas, pero bueno que logro con esto, es que mando a guardar los datos a traves de un tquery, con el cual no tengo la tabla cargada en memoria si no que solo consulto el registro que quiero editar y le hago el update o insert en caso de registros nuevos.

No se si logras entenderme, la dificultad que esto me provocaba era continuos deadlocks por trabajar directamente en la tabla, sobre todo cuando mas de un usuario estaba trabajando en el sistema, con las querys puedo usar transacciones y controlar el grabado de los datos.

Tambien me provocaba un error que no se podian actualizar los datos porque otro usuario habia modificado el registro, eso lo resolvi con lo que te he comentado

Saludos

AzidRain 15-06-2010 21:06:07

La elección natural es usar los tabpages pero en verdad, estoy hablando de un megaformulario que casi ocupa el total vertical de la pantalla. Mientras que los campos que hacen falta son unos 5 a lo mucho, la pega es que esos campos son Memos que como te decia, rara vez se llegan a ocupar, asi como lo resolvi me funciona y pues es para una "adición" de emergencia de mi cliente (la cual no pretende pagar..jijiji) así que para otra ocasión le echo mas crema a mis tacos.

rgstuamigo 15-06-2010 22:18:01

Cita:

Empezado por AzidRain (Mensaje 367330)
Gracias por el jalón de orejas Román, al final esto fue lo más compacto que pude hacer:

Código Delphi [-]
var   I: Integer; 
begin    
for I := 0 to ComponentCount - 1 do 
   Begin      
     If Components[i] is TcxDBTextEdit Then      
      TcxDBTextEdit(Components[i]).Text := '';   
   End;

Sería un poco mas eficiente si lo hicieras así :D:D:
Código Delphi [-]
var   I: Integer;
 begin    
for I := 0 to ControlCount - 1 do//Iteramos solo los controles  
  Begin      
  If Components[i] is TcxDBTextEdit Then 
    TcxDBTextEdit(Components[i]).Text := '';  
  End;
End;
Pues al trabajar con la propiedad ControlCount solo estamos iterando con todos los controles(componentes que son Controles) de nuestro formulario, en cambio si trabajamos con ComponentCount tambien estamos trabajando con todos los componentes del formulario ya sean controles o no, sean visuales en tiempo de ejecucion o no. He ahí la diferencia.;).
Saludos...:)


La franja horaria es GMT +2. Ahora son las 04:52:58.

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