Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Conexión con bases de datos (https://www.clubdelphi.com/foros/forumdisplay.php?f=2)
-   -   DBGRID y un menu de BOTONES (https://www.clubdelphi.com/foros/showthread.php?t=38591)

neosyoshiran 20-12-2006 01:30:44

DBGRID y un menu de BOTONES
 
Buenas , la verdad no sabia donde poner, este problema que tengo , me puse a buscar en una s9 paginas si habia el mismo problema pero no lo encontre asi que tengo el siguiente problema

tengo varios botones en un Panel , NUEVO, MODIFICAR, BORRAR
y abajo un DBGRID

lo que quiero es lo siguiente cuando el dbgrid este en "vacio<--sin ningun registro" solo quiero que aparescan los botones NUEVO activado, los demas desactivados, de la misma manera si existe un registro en el DBGRID solo que aparescan los botones MODIFICAR, BORRAR activado los demas desactivados.
Ahi tengo una imagen.
http://img155.imageshack.us/img155/6...toneseata6.gif

:)
saludos

AzidRain 20-12-2006 02:05:56

Yo estoy haciendo una aplicación y precisamente tengo unas ventanas identicas, no he llegado a hacer esa parte con los botones, pero en vista de que tu estas en eso aqui te va como lo veo:

Por defecto ponlos desactivados, de manera que siempre aparezcan inactivos. Agrega un DataSource ligado a la tabla que vamos estar checando que tenga datos. En el evento OnDataChange escribes un manejador que verifique si ya hay registros, en cuyo caso activará los botones.

OnDataChange se ejecuta al modificar o insertar un registro.
Este método es el indicado para convertir un control cualquiera en "Data-aware"

Aqui un ejemplo de manejador de un control TDataSource llamado MyData y CopYData es un botón que solo sirve si no estamos al prinicipio de los registros:
Código Delphi [-]

procedure TForm1.MyDataDataChange(Sender: TObject; Field: TField);
begin
  if MyData.Bof then  //Si estamos al principio del archivo
    CopyData.Enabled := False  // Deshabilitar el boton
  else
    CopyData.Enabled := True; // De lo contrario habilitarlo
end;

Neftali [Germán.Estévez] 20-12-2006 11:02:32

Cita:

Empezado por neosyoshiran
...si existe un registro en el DBGRID solo que aparescan los botones MODIFICAR, BORRAR activado los demas desactivados.

Debes preguntar no al DBGrid, sino al DataSet asociado. Puedes usar las propiedades BOF y EOF.

Código Delphi [-]
var
  Empty:Boolean;
begin
  empty := (DBGrid.DataSet.EOF) and (DBGrid.DataSet.BOF);
  Nuevo.Enabled := empty;
  Modificar.Enabled := not empty;
  Borrar.Enabled := not empty;

AzidRain te ha mostrado el camino, pero BOF sólo te dice si estás al principio o no, nada de si está vacío o con registros.

rcarrillom 20-12-2006 12:35:10

Sencillo, ya está hecho en Delphi :D, usando un componente TActionList, (yo lo uso en mi MainForm para *todos* los DBGrids de mi app):
- En la ventanita de la lista de acciones del TActionList, selecciona la opción "New standard action" del botón New Action y selecciona los TDataSetXXXX que quieras usar.
- Si defines un valor para la propiedad DataSource de los TDataSetXXXX, sólo funcionan con ese en específico, si lo dejas en blanco toman el DataSource del control de BD con el focus, aún si te cambias de ventanas y son diferentes DataSets.
- Enlazalos a un TButton, TMenuItem o cualquier objeto que tenga la propiedad llamada Action.
- Si necesitas llamar una ventana adicional para capturar los campos,
asígnale el evento OnExecute del TDataSetXXXX. Yo creo un procedure en la form MDI y lo asigno dinámicamente en el OnActivate (para Altas y Cambios) y lo pongo a Nil en el OnDeactivate de la misma MDI, para cuando la destruya no mande llamar al código del evento que ya no es válido.
Y eso es todo. Con esto es automático el Enabled/Disabled de los botones, sin código. Y es válido para toda la app.


Déjenme saber si me dí a entender y funciona mi método.

neosyoshiran 21-12-2006 00:13:27

Gracias a todos por su respueste.
Para tener un poco mas claro utilizo lo siguiente
un DATAMODULE"aqui tengo mis ttables y datasoruce" y un FormPrincipal"aqui tengo mis dbrids y demas"

Utilizando informacion de AzidRain

Código Delphi [-]
procedure DATAMODULE.DSE_TRABAJODataChange(Sender: TObject; Field: TField);
begin
  if DSE_TRABAJO.DataSet.Bof then  //Si estamos al principio del archivo
    FormPrincipal.TBnuevoV.Enabled := False  // Deshabilitar el boton
  else
    FormPrincipal.TBnuevoV.Enabled:=true;
end;

oh si fuera. Neftali
Código Delphi [-]
procedure TDMTe.DSE_TRABAJODataChange(Sender: TObject; Field: TField);
var
  Empty:Boolean;
begin
  Empty:=(FormPrincipal.dbgrid.DataSource.DataSet.EOF) and (FormPrincipal.dbgrid.DataSource.DataSet.BOF);
  FormPrincipal.TBnuevoV.Enabled := empty;
  FormPrincipal.TBmodificarV.Enabled := not empty;
  FormPrincipal.TBborrarV.Enabled := not empty;
end;
Cuando compilo todo sale bien, pero cuando lo ejecuto me sal eun error
de "accesviolation"


rcarrillom
La idea del TActionList nunca lo utilize, ando algo perdido :) pero los botones que utilizo como Nuevo, MOdificar , Borrar, llaman a otras Forms, donde ahi pongo los datos y recien los guardo con SQL.

Me pueden orientar mas por favor.

Saludos

ramiretor 21-12-2006 00:53:56

Hola:
Lo que está pasando es que estas referenciando en tu código a un objeto que ni siquiera está asignado (FormPrincipal.dbgrid.DataSource.DataSet.EOF, o alguno de los de abajo) , debes de hacer lo mismo que está haciendo pero como veo tu código debe ser otro objeto.

Por otro lado te recomiendo que uses el evento "ONSTATECHANGE" del datasource y no en el "DATACHANGE" , la razon es que el primero se ejecuta cuando cambia el estado del dataset de datos (lectura, insercion, borrado,
edicion, etc), el segundo se ejecuta cada vez que entras en un campo o cambias de registro y por ultimo, como breviario cultural, yo lo haría asi (supongo que el TDataset se llama Dataset):

Código Delphi [-]

  Nuevo.Enabled := DataSet.RecordCount = 0;
  Modificar.Enabled := DataSet.RecordCount > 0;
  Eliminar.Enabled := DataSet.RecordCount > 0;

Espero te sirva mi comentario.
Un abrazo a todos

rcarrillom 21-12-2006 10:16:36

Cita:

Empezado por neosyoshiran
rcarrillom
La idea del TActionList nunca lo utilize, ando algo perdido pero los botones que utilizo como Nuevo, MOdificar , Borrar, llaman a otras Forms, donde ahi pongo los datos y recien los guardo con SQL.

Me pueden orientar mas por favor.

Saludos

Por supuesto, es más fácil incluso (en mi opinión personal) usar los TDataSetXXXX que asignar código en el OnStateChange u OnDataChange del DataSet, lo menciono porque yo uso esta metodología y no escribo ni una sola línea de código para habilitar/deshabilitar los botones, opciones de menú, speedbuttons, etc. Lo que comentas de mandar llamar otras Forms para la captura de los datos, ya mencioné en mi anterior post que lo debes de hacer en el evento OnExecute del TDataSetXXXX.
A más detalle uso esta técnica (tiene patente y es mía, y de licencia jamonware):

* Definir los TDataSetXXX, que en mi caso lo hago en el form principal. En mi anterior post aparece la forma de hacerlo.
* Los TDataSetXXX que se usan son TDataSetInsert, TDataSetEdit y opcionalmente TDataSetDelete y TDataSetRefresh.
* Mis aplicaciones de BD son casi siempre MDI (pero mi método puede aplicar a forms no MDI).
* Casi siempre una form MDIChild tiene un DBGrid.
* El susodicho MDIChild tiene como características:

* Dos métodos del tipo TNotifyEvent para llamar al Form de captura de datos (uno para editar y otro para modificar). Opcionalmente se puede poner un tercero para el caso Eliminar y un cuarto para actualizar la vista o consulta en caso de ser SQL.

Código Delphi [-]
procedure TfrmCuentas.actInsertarExecute(Sender: TObject);
begin
  dlgCuenta := TdlgCuenta.Create(Self);
  with dlgCuenta do begin
    if ShowModal = mrOk then begin
      {Tu código para insertar el nuevo registro}
    end;
    Free
  end
end;

procedure TfrmCuentas.actEditarExecute(Sender: TObject);
begin
  dlgCuenta := TdlgCuenta.Create(Self);
  {Tu código para leer elos datos y pasarlos al Formulario}
  with dlgCuenta do begin
    if ShowModal = mrOk then begin
      {Tu código para insertar el nuevo registro}
    end;
    Free
  end
end;

procedure TfrmCuentas.actBorrarExecute(Sender: TObject);
begin
  {Tu código para manejar la eliminación del registro}
end;

* Código en el evento OnActivate para asignar los métodos anteriores a los TDataSetXXX

Código Delphi [-]
procedure TfrmCuentas.FormActivate(Sender: TObject);
begin
  frmMain.actBDInsertar.OnExecute := actInsertarExecute;
  frmMain.actBDEditar.OnExecute := actEditarExecute;
  frmMain.actBDBorrar.OnExecute := actBorrarExecute
end;

* Código en el evento OnDeactivate para cuando se seleccione otro form,

Código Delphi [-]
procedure TfrmCuentas.FormDeactivate(Sender: TObject);
begin
  frmMain.actBDInsertar.OnExecute := nil;
  frmMain.actBDEditar.OnExecute := nil;
  frmMain.actBDBorrar.OnExecute := nil
end;

* Código en el evento OnClose del MDI para autodestruirse (me sonó a M:I )

Código Delphi [-]
procedure TfrmCuentas.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  Action := caFree
end;

* Código en el evento OnDestroy para asegurarme que se desactive correctamente el evento personalizado de los TDataSetXXX

Código Delphi [-]
procedure TfrmCuentas.FormDestroy(Sender: TObject);
begin
  FormDeactivate(Self);
  {Tu código para manejar otras destrucciones}
end;

Y eso es todo. Recuerda enlazar los botones, opciones de menú, botones de barras de herramientas al TDataSetXXX a través de la propiedad Action.
Una nota, si los TDataSetXXX no tienen asociado código en su evento OnExecute, realizan la accion predeterminada por ejemplo el TDataSetEdit pone en modo edición a un DBGrid (dependiendo si la consulta es o no editable), en cambio si tiene código asociado ejecuta éste en vez de la acción predeterminada, ésta es la magia y es lo que permite llamar las forms personalizadas de captura como mencionas.
Yo hago abuso extensivo de los menús, botones, popups y barras de herramientas, por eso uso el TActionList, código en un solo lugar, asociado a muchos componentes.
Creo que más claro y explicado no puedo ser, esperando no sonar vanidoso y gurú, que aún no lo soy .

neosyoshiran 09-01-2007 21:55:36

Perdon por la demora, pero muchas gracias, lo logre con tada la info que me daron gracias por lo de Actionlist, es super util gracias, ahora funciona :)
pero ahora tengo una duda
Logre hacer que mis botones, nuevo,modificar,ver,borrar, funcionaran correctamnte, ahora en el DBgrid tengo asignado en el evento onDblclick <-- ahi llamo a la forma formVer, pero como no lo asigne a un action, cuando esta vacio el dbgrid igual se activa

saludos
:)


La franja horaria es GMT +2. Ahora son las 03:06:01.

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