10 de Agosto de 1998
Continuo con la descripción y explicación de los aspectos más interesantes del programa. Empezando por el borrado de registros, que es un tema que hace algo de tiempo se comentaba en las News. Si has ejecutado el programa, fijate que cuando se va a borra un registro, se muestra un cuadro de dialogo en castellano, y no el mensaje en inglés, que es el mensaje que muestra el control DbGrid por defecto. Lo que hace exactamente el programa es que el borrado del registro actual no se hace por orden del control DbGrid. Sino que la orden proviene de la opción Borrar Regristro del menú Registros. Este es el procedimiento responsable.
procedure TForm1.BorrarRegistro1Click(Sender: TObject); Var Boton : Integer; begin Boton := Application.MessageBox ('¿Está seguro que desea borrar este registro', 'Borrar registro',MB_YESNO+MB_ICONINFORMATION); If Boton = ID_YES Then DataModule2.Table1.Delete Else DataModule2.Table1.Cancel; end;
Lo que hace este procedimiento es sencillo, lo primero que hace es mostrar el cuadro de dialogo para pedir la conformidad del usuario, y según su valor devuelto toma una decisión. Hay un detalle que quizas despiste, y es que la primera línea hay una variable de tipo entero que recoge el valor devuelto por la función Application.MessageBox. Esto es posible ya que esta función es propia de windows (una Api), y como tal devuelve enteros, y Delphi la tiene definida como tal. La siguiente línea se comprueba el valor contenido en Boton con una constante. Una vez aclarado esto, fijate que si el usuario contesta que si se procede a borrar el registro, sino se cancela el proceso actual de la tabla. Aunque la tabla no esta haciendo nada, por si las moscas decido cancelar.
Por otra parte, si el usuario decide borrar el registro pulsando sobre la barra de navegación, este será borrado y el mensaje no será mostrado siempre y cuando la propiedad ComfirgDelete de la barra de navegación valga Falso.Lo cual nos obliga a tomar cartas en el asunto. Cuando hablé de la barra de navegación comenté que tenia un evento que se producia cuando se registraba la pulsación de un botón, y antes de que se produzca la acción según el botón pulsado.
procedure TForm1.DBNavigator1BeforeAction(Sender: TObject; Button: TNavigateBtn); begin If Button = nbDelete Then BorrarRegistro1CLick (Sender); end;
Este procedimiento tiene la variable Button que contiene el identificador del botón pulsado, así que si el botón pulsado (recuerda que este evento se produce para cualquier botón de la barra de navegación) es el de borrado llamo al evento procedimiento que os acabo de comentar.
Este es el sistema que he usado, pero todo esto está sujeto a la condición que el componente Dbgrid no permita la edición, osea que su propiedad ReadOnly valga True. En otras circustancias sino se quiere que apararezca el mensaje en Inglés debemos indicar que no queremos que se muestre mensaje en las propiedades correspondientes de los controles DbGrid y DbNavigator, y mostrar nosotros nuestro propio mensaje. Lo cual se hace en el evento BeforeDelete de la tabla correspondiente. Aqui os pongo un ejemplo de ello.
procedure TForm1.Table1BeforeDelete(DataSet: TDataSet); Var Valor : integer; begin Valor := Application.MessageBox ('¿Borrar este registro?','Borrar un registro', mb_YESNO+MB_ICONSTOP); If Valor = ID_NO Then Abort; end;
Como acabo de comentar que el componente DbGrid no permite la edición e inserción de datos en la tabla porque he puesto su propiedad ReadOnly en True. La opción para editar los datos puede estar la página de detalles, donde hay controles para ello. Pero decidí hacerlo en una ventana propia, para hacer el proceso más amigable al usuario.
Este es el formulario que
diseñe. He usado un control DbEdit, un DbMemo y un DbComboBox. Los tres botones que
contiene son para añadir un dato y no salir, para salir añadiendo los datos, y para
cancelar la operación. Este formulario se no se crea automaticamente cuando arranca la
aplicación, sino que es creado cada vez que es necesitado. Sobre la creación que
formularios en tiempo de ejecución es algo que no he hablado hasta ahora.
Cada vez que añades un formulario a tu proyecto, Delphi lo añade a la lista de creación automática, así cuando se ejecuta la aplicación se crean todos los formularios, empezando por el principal que es el primero, hasta el último. Esto se puede evitar, dejando solo que se cree el formulario principal, y que los formularios "secundarios" los creemos cuando los necesitamos. La lista de formularios que se crean al arrancar esta el fichero del proyecto, el que tiene extensión DPR, lo puede ver su pulsas Project Source, en el menú View. Pero cuidado no toques ahi, a la ligera, si deseas quitar o añadir un formulario debes usar la ventana que pone Delphi a tu disposición. Para ello pulsa en la opción Options del menú Project. En ella tienes una pestaña que pone Forms, seleccionala y veras dos ListBox, en uno estan los formularios que se crean automaticamente y en el otro los disponibles.
Cuando el usario decide que quiere añadir un registro a la tabla, pulsará la opción correspondiente en un menú, así que es aqui cuando debemos crear el formulario antes de mostrarlo. Vemos como se puede hacer esto.
procedure TForm1.InsertarRegistro1Click(Sender: TObject); Var Form4 : TForm4; begin Form4 := TForm4.Create (Self); Try Form4.BorderStyle := BsDialog; Form4.DBComboBox1.Items := Form1.DBComboBox1.Items; Form4.ShowModal; Finally Form4.Destroy; DataModule2.NumeroRegistros (DataModule2.Table1); End; end;
Lo primero es crear el formulario, antes he defino un variable que es del tipo TForm4, lo cual esta definido en la unidad que contiene este formulario. Recuerda que el formulario desde el cual llamas al nuevo, debe hacer referencia al nuevo formulario en la línea uses. Creo el formulario inicializando la variable que he creado (Form4), luego dentro de un bloque Try Finally, hago modificaciones en el formulario, le paso la lista de Temas que esta contenido en el DbComboBox1 del formulario Form1 al DbComboBox del Form4, luego muestro el formulario de manera Modal, cuando retorna el control destruyo el formulario y actualizo el número de registros. El motivo de que exista el bloque Try Finally es que si algo va mal cuando trata de pasarle los datos al formulario recién creado, o cuando trato de mostrar el formulario, me aseguro de que el formulario es destruido (liberando la memoria ocupada), o sino todo ha ido bien tambien libero la memoria.
Cuando se crea el formulario coloca la tabla en modo inserción para poder modificar el valor del registro actual.El formulario tiene tres botones, que son del tipo BitBtn, los cuales al ser pulsado cierran el formulario, pero a mi solo me interesa que se cierre el formulario cuando se pulse el botón Cancelar o Salir. Para ello he declarado una variable a nivel privado que se llama PuedoCerrar y es de tipo lógico. La cual compruebo su valor en el evento OnCloseQuery del formulario. Hay que tener en cuenta que cuando se añade un registro, el nombre del juego no puede existir, ya que la tabla cuando la diseñe indique que el valor de ese campo era único. Si el valor está repetido se produce una excepción. Este es el procedimiento que realiza esta operación.
procedure TForm4.BitBtn1Click(Sender: TObject); begin With DataModule2.Table1 Do Begin Try Post; Except Application.MessageBox ('El nombre introducido no es correcto'+chr(13)+ 'El nombre esta repetido, prueba con otro', 'Insertar registro', Mb_Ok+Mb_IconStop); Cancel; Insert; End; Insert; End; end;
El botón de salir, realiza un par de comprobaciones antes de salir. La primera es avisar si hay campos vacios, si el usuario decide salir de todos modos, se cancela la edición de la tabla, para evitar que haya campos sin datos. Si los campos están correctamente llenos, se trata de guardar los datos, si hay algún error se dispara la excepción, así cancelo la operación de inserción, y se cierra el formulario.
procedure TForm4.BitBtn2Click(Sender: TObject); begin If (DbEdit1.Text = '') or (DbComboBox1.Text = '') Then Begin IF Application.MessageBox ('No se puede grabar con los campos vacios.'+ Chr(13)+'¿Deseas salir sin grabar?', 'Campos vacios',mb_YesNoCancel+MB_IconStop) = idYes Then Begin DataModule2.Table1.Cancel; PuedoCerrar := True; End; End Else Begin Try DataModule2.Table1.Post; Except DataModule2.Table1.Cancel; End; PuedoCerrar := True; End; end;
Recuerda que el formulario se cierra siempre y cuando la variable PuedoCerrar valga True, ten en cuenta que cuando se crea el formulario, la tabla se pone en modo inserción por la orden que hay en el evento OnCreate de este formulario, y cuando se cancela la operación actual de la tabla, la tabla pasa a modo normal (Browse).
Para la edición de los datos, he puesto otro formulario, el cual se crea y se destruye igual que el anterior. Estos son los tres procedimiento del formulario que controlan todo el proceso.
procedure TForm3.BitBtn3Click(Sender: TObject); begin DataModule2.Table1.Cancel; PuedoCerrar := True; end; procedure TForm3.BitBtn1Click(Sender: TObject); begin If (DbEdit1.Text = '' ) or (DbComboBox1.Text = '' ) Then IF Application.MessageBox ('No se puede grabar con los campos vacios.'+ Chr(13)+'¿Deseas salir sin grabar?', 'Campos vacios',mb_YesNoCancel+MB_IconStop) = idYes Then Begin DataModule2.Table1.Cancel; PuedoCerrar := True; End Else PuedoCerrar := False Else Begin PuedoCerrar := True; Try DataModule2.Table1.Post; Except DataModule2.Table1.Cancel; End; //De la excepción. End; end; procedure TForm3.FormCreate(Sender: TObject); Begin PuedoCerrar := False; Resolucion; End; procedure TForm3.FormCloseQuery(Sender: TObject; var CanClose: Boolean); Begin CanClose := PuedoCerrar; End;
El primero de todos es el del botón Cancelar, lo único que hace es cancelar la
operación de la tabla, por si esta en modo edición y luego cambiar el valor de la
varible PuedoCerrar, que hace la misma función que en el formulario principal. En este
procedimiento cancelo la operación de la tabla, pero fijate que no hay ninguna línea que
ponga la tabla en modo edición, pero te aseguro que la tabla entra en modo edición. Esto
es posible ya que son los propios controles de bases de datos (Data Aware) los que lo
hacen.
El siguiente procedimiento es el que esta asociado a la pulsación del botón Aceptar, de
nuevo verifica que no haya campos vacios, si el usuario decide que quiere salir de todos
modos, se cancela la edición de la tabla y se cambia el valor de la ya conocida variable
PuedoCerrar. Si los campos estan llenos correctamente se guardan en la tabla las
moficaciones (método Post), si hay algun problema se cancela la edición y se cierra de
todos modos el formulario.
Basicamente este es el "despiece" de este programa, como podies ver no es difícil hacer un programa que gestiones una base de datos, todo depende de lo que se quiera complicar. Creo que quedan explicados los aspectos generales sobre este programa. Os recuerdo que solo es un ejemplo y que hay más maneras de hacer las cosas todas iguales o mejores que esta.