En esta última (si, última de este proyecto) parte vamos a ver como modificar y eliminar los datos que ya hemos insertado en la base de datos.
Bien, pues al lio ...
Creamos un nuevo formulario, para ello botón secundario en la carpeta de formularios y nuevo y formulario :D
Marcamos la casilla de contructor (esto es para que cuando se cree ejecute un funcion _new(), que también podriamos haber usado el evento open del formulario, pero asi completamos más la enseñanza con la aplicación), en esa función rellenaremos los campos con el valor actual.
Dibujamos el formulario (los mismos campos que hay en el formulario principal) y ya está listo:

ahora falta abrirlo ¿cuando?
Bueno, lo más rápido es abrirlo haciendo doble click en una fila del tableview, para ello, botón secundario sobre el tableview y seleccionamos el evento DblClick.
Lo rellenamos con el siguiente código:
PUBLIC SUB TVultGastos_DblClick()
DIM query AS String
f AS FmodEli
f = NEW FmodEli(TVultGastos[TVultGastos.row, 0].text, TVultGastos[TVultGastos.row, 1].text, TVultGastos[TVultGastos.row, 2].text, TVultGastos[TVultGastos.row, 3].text, TVultGastos[TVultGastos.row, 4].text)
f.ShowModal()
query = "SELECT cod, DATE_FORMAT(fecha, '%d/%m/%Y') as fecha, concepto, CONCAT(cantidad, ' €') as cantidad, origen FROM HomeGestion.gastos ORDER BY fecha ASC"
Mdb.fill_view(TVultGastos, query)
END
Definimos la variable query como una cadena, que es donde pondremos la consulta para refrescar el tableview una vez que modifiquemos los datos.
Abrimos la ventana !!
Definimos f como FmodEli (que es el nombre que le he puesto al formulario de edición que creamos antes, que se ha convertido en una clase) y luego CONTRUIMOS (utilizando el contructor que definimos antes) con los siguientes parámetros (los valores actuales):
TVultGastos[TVultGastos.row, 0] - que es el primer valor de la fila (el 0, cod).
TVultGastos[TVultGastos.row, 1] - que es el segundo valor de la fila (el 1, fecha).
TVultGastos[TVultGastos.row, 2] - que es el tercero valor de la fila (el 2, concepto).
TVultGastos[TVultGastos.row, 3] - que es el cuarto valor de la fila (el 3, cantidad).
TVultGastos[TVultGastos.row, 4] - que es el quinto valor de la fila (el 4, origen).
Hay que fijarse que todos son del tipo STRING (cadena de texto), ya veremos un poquito más adelante para que vale esto que pasamos.
Luego con la función ShowModal() mostramos el formulario (en forma modal, o sea, que no podemos tocar al "padre" hasta que ya no esté el "hijo").
El resto es conocido, refrescamos los datos del tableView.
Y ahora corriendo, corriendo, antes de que se nos olvide los parametros que hemos pasado al constructor, vamos a escribir la función. En el formulario de edición (ese que yo he llamado FmodEli, anda que soy para los nombrecitos ...) escribimos lo siguiente en la función _new:
PUBLIC SUB _new(codigoAct AS String, fechaAct AS String, conceptoAct AS String, cantidadAct AS String, origenAct AS String)
DIM i AS Integer
IF (NOT Mdb.conexion()) THEN ME.Close()
ME.codigo = codigoAct
fecha.Text = fechaAct
cantidad.Text = Val(cantidadAct)
concepto.Text = conceptoAct
FOR i=0 TO (CBOrigen.Count-1) STEP 1
IF CBOrigen[i].Text = origenAct THEN CBOrigen.Index = i
NEXT
END
<code>
Que como vemos, los parámetros que recojen son cadenas y son los campos que hemos enviado al CONSTRUIR el formulario.
Ahora definimos i como entero (el clásico i de todos los for), ya veremos para qué lo necesitamos.
Ahora caigo que debo guardar el código del actual registro para saber que tengo que modificar u eliminar en la base de datos, aiiisss, que cabeza ..., nada, creamos una variable global (de las que se ponen al principio del todo) que, inteligentemente, llamaremos <b>codigo</b>.
<code>
' Gambas class file
PUBLIC codigo AS String
Y la rellenamos con el valor que recojemos del parámetro codigoAct.
Las siguientes tres lineas no creo que haga mucha falta explicarlas, salvo por la opción Val() que parsea un valor (función que ya hemos visto antes).
Y ahora viene el bucle for, que lo use para "marcar" la opción actual en el comboBox de origen. (DESDE cero HASTA nº de filas del combo -1, importante el -1, y dando PASOS de 1, no creo que haga falta explicar más de un bucle for).
En resumen, recorro el combo hasta que encuentre el origenActual (que me llegó por parámetro) y entonces lo selecciono.
Una vez realizado esto si ejecutamos veremos como los datos se pasan pero ya está, no hace nada más, vamos a darle vida y funcionamiento al formulario ...
Le pondremos todo lo que tiene el otro formulaio (anda, si solo es copiar y pegar) en el tema de funcionamiento y protecciones, las funciones que me quedaron despues de todo el copy&paste son:
PUBLIC SUB Button3_Click()
ME.Close()
END
PUBLIC SUB fecha_DblClick()
DPselFecha.Enabled = TRUE
DPselFecha.Visible = TRUE
DPselFecha.SetFocus()
END
PUBLIC SUB DPselFecha_DblClick()
fecha.Text = Format$(DPselFecha.Value, "dd/mm/yyyy")
DPselFecha.Enabled = FALSE
DPselFecha.Visible = FALSE
END
PUBLIC SUB DPselFecha_KeyPress()
IF (key.Code = key.Enter OR key.Code = key.Return) THEN
fecha.Text = Format$(DPselFecha.Value, "dd/mm/yyyy")
DPselFecha.Enabled = FALSE
DPselFecha.Visible = FALSE
ELSE IF (key.Code = key.Esc) THEN
DPselFecha.Enabled = FALSE
DPselFecha.Visible = FALSE
END IF
END
Comentaremos por encima ...
Click Boton 3 cierra la ventana sin hacer nada (muy sencillito).
Y las demas funciones son clavaditas a las del formulario padre (seguramente habrá una forma de reutilizarla, pero hoy estoy vago para buscarla)
Los dos botones que quedan son los importantes, empezaremos por el complicado, click en modificar.
PUBLIC SUB Button2_Click()
DIM query AS String
DIM fechaArray AS String[]
DIM fechaSQL AS String
fechaArray = Split(fecha.Text, "/")
fechaSQL = fechaArray[2] & "-" & fechaArray[1] & "-" & fechaArray[0]
IF ((NOT cantidad.Text) OR Val(cantidad.Text) = 0) THEN
Message.Warning("Debe especificar una cantidad")
ELSE IF (NOT concepto.Text) THEN
Message.Warning("Debe especificar un concepto")
ELSE
query = "UPDATE HomeGestion.gastos "
query = query & "SET fecha='" & fechaSQL & "', "
query = query & "cantidad='" & Val(cantidad.Text) & "', "
query = query & "concepto='" & concepto.Text & "', "
query = query & "origen='" & CBorigen.Current.Text & "'"
query = query & " WHERE cod='" & codigo & "'"
Mdb.consulta(query)
ME.Close()
END IF
END
Que nos sonará muchisimo al insertar del formulario padre, vamos, que lo único que cambia es la consulta (es un UPDATE en vez de un INSERT).
Por lo demás, todo conocido y , por tanto, mu facilito. Ya veis que complicado ha sido el modificar ¿no?, pues ahora el eliminar:
PUBLIC SUB Button1_Click()
DIM confirmacion AS Integer
DIM query AS String
confirmacion = message.Warning("¿Desea eliminar este gasto?", "Eliminar", "Cancelar")
IF confirmacion = 1 THEN
query = "DELETE FROM HomeGestion.gastos WHERE cod='" & codigo & "'"
Mdb.consulta(query)
ME.Close()
END IF
END
Al hacer click en eliminar generamos un par de variables (confirmación y query, la ya famosa query).
Después utilizamos la función message (la cual ya usamos antes para el testeo de la inserción), pero esta vez el método Warning, que nos sacará una ventana MODAL, que ya sabemos lo que es ;-) con el texto que le pongamos y un par de botones con el texto que le pongamos.
Solo si el usuario contesta en el primero (eliminar) devolvera un 1, en caso contrario devolverá 0. Así nos aseguramos que de verdad quiere borrar y no es que le haya dado sin querer :D
Una vez confirmado hacemos la consulta (DELETE en este caso) y cerramos (con la funcion Close()).
Listo, ya está funcional la aplicación, ahora la podemos mejorar tooooodo cuanto queramos, pero como a mi el programa "ya me arrasca lo que me picaba", no lo seguiré por ahora, hasta que la "jefa" me exija una revisión, jeje.
Si alguien se "atreve" a seguirlo o quiere echarle un ojito al código, o simplemente no se cree que todo este código tan malo funcione, podrá descargarse tanto el código fuente, como los ejecutables y la base de datos de aquí.
Bueno, en resumen he de decir que no es nada dificil programar en Gambas y que se desarrollan aplicaciones "de andar por casa" muy rápido (este programa lo hice en tres dias, sacar tiempo para escribir como lo hice en mi diario es otro tema :D).
Y ahora que ya sabemos manejar los formularios y las bases de datos, en el próximo ejemplo experimentaré con las conexiones entre un cliente y un servidor.