Curso de Gambas - Primer proyecto (5)

7 - Primer proyecto (5)

[editar]
Tutorial creado por KDE-Hispano. Extraido de: http://www.kdehispano.org/curso_gambas
09 de Noviembre de 2005
En este post veremos como mostrar el contenido de una tabla en un tableView y como insertar nuevos valores en la base de datos.

Dividiremos el post en dos partes, mostrar datos, insertar datos (dar cera, pulir cera).

Mostrar datos:

Bueno, en el último capítulo vimos como conectar con la base de datos y ahora que ya somos amigos intimos de ella, vamos a "verla por dentro" ...

Para ello, debemos crear una función en el modulo (modulo de base de datos) que rellene el tableview que hemos insertado, porque lo hemos insertado ¿verdad? ...
(si, eso de añadir la libreria o biblioteca de qt.ext en proyecto - propiedades y seleccionar el tableview de las nuevas herramientas que aparecerán).

Muy bien, tenemos un gran cuadro blanco que no hace nada, vamos a rellenarlo.
Para ello , debemos usar una funcion en el modulo Mdb que ... ups, esto ya lo he dicho antes, ayyy ese Alemán que me vuelve loco ... bueno la función es la siguiente y lo que hace es determinar cuantas filas y columnas le pondremos a esa tableview, ya que estas dependen de la consulta :

'
' Rellenar una tabla con los resultados '
'
PUBLIC SUB fill_view(tbv AS tableview, qry AS String)
  rs1 = db.exec(qry)
  WITH rs1
    tbv.rows.count=0 ' Muy importante
    IF .count<>0 THEN
      tbv.columns.count=.fields.count
      tbv.rows.count=.count
    END IF
  END WITH
END


Expliquemos un poquillo el código:
Comentarios al principio, ejecutamos la consulta (que, como vemos es pasada con el parametro qry) con db.exec y guardamos el resultado en la variable global ya definida rs1.

El WITH significa que a partir de esa linea y hasta que encontremos un END WITH si ponemos un punto (.) es como si hubiesemos puesto rs1, esto hace que tengamos que escribir menos.

Con (WITH) rs1 (la consulta) ...
Ponemos el numero de filas a cero. (Muy importante cuando eliminamos, que si no, habria una fila de menos y daria error (buffer overflow, jijiji)).
Si el numero de filas de la consulta (rs1) es distinto de cero (o sea, que hay datos que mostrar) ENTONCES hacer:

a) - Poner el numero de columnas a la tableview (que se la hemos pasado como parámetro a la función con el nombre de tbv) igual al de campos que tenga el resultado de la consulta.

b) - Poner el número de filas de la table view igual que el número de filas devueltas por la consulta.

Cerramos todo lo abierto y ala, ya esta dimensionada la tabla.

Ahora hemos de rellenar la tabla ...

Y aquí es donde estuve dejándome los ojos un buén rato hasta que me dió por leer la ayuda,

Pués lo que me decia la cabeza es que una primera lectura habia que hacerla nada más cargar el formulario ... asi que en el evento open del formulario inicial le añadí lo siguiente:

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)
  WITH TVultGastos
    .columns.Resizable = TRUE
    .columns.Moveable = TRUE
    .columns.count=5
    .columns[0].text="Cod"
    .columns[0].Width = 50
    .columns[1].text="Fecha"
    .columns[1].Width = 100
    .columns[2].text="Concepto"
    .columns[2].Width = 248
    .columns[3].text="Cantidad"
    .columns[3].Width = 100
    .columns[4].text="Origen"
    .columns[4].Width = 100
  END WITH


Que es una consulta cuya única cosa a destacar son las funciones DATE_FORMAT (que podreis adivinar para que sirve) y CONCAT (que tambien es muy sencillo, concatena).
Y después llamo a la funcion que creamos antes.

Luego "acondiciono" el tableview, poniendole titulos, dimensiones y demas ...

Y al darle a ejecutar lo único que sale es la tableview, con sus títulos con el número de columnas y filas correcto, pero ningún dato en su interior.

Y es que resulta que cargar los datos a la tableview se hace con una función propia del objeto.

O sea, que hay que usar el "evento" de la tableview Data(boton secundario sobre la tabla y evento, seleccionamos Data). y escribimos lo siguiente en ese evento:

PUBLIC SUB TVultGastos_Data(Row AS Integer, Column AS Integer)
  'el nombre de los campos del array
  arrtable[0]="cod"
  arrtable[1]="fecha"
  arrtable[2]="concepto"
  arrtable[3]="cantidad"
  arrtable[4]="origen"
  WITH Mdb
    .rs1.MoveTo(Row)
    TVultGastos.data.Text = Str(.rs1[arrtable[Column]])
  END WITH
END


Que hace lo siguiente ...
En arrtable (que es un array que hemos definido al principio del código, y si aún no lo hemos hecho, lo hacemos ahora con:


' Gambas class file
' Variables del modulo
arrtable[5] AS

Siempre al principio del código.)
En arrtable metemos el nombre de los campos que devuelve nuestra consulta, que son cod, fecha, concepto, cantidad, origen.

Es conveniente segur el mismo orden que en la query que hicimos, si no nos liaremos más, también decir que habra una forma 10.000 veces mas facil de rellenar un tableview con gambas sin armar tanto follón, pero en estas pocas horas que le he hechado al gambas no la he encontrado.

Bueno, despues y CON (WITH) Mdb vamos a la fila de la consulta que lleve el tableview (don't worry, la cuenta la lleva Gambas), ya que Row le llega como parámetro y es la fila actual de la tabla.

Y despues:
TVultGastos.data.Text = Str(.rs1[arrtable[Column]])
que es más dificil explicarlo que entenderlo ... pero bueno, se intentará:

Bueno, pues el data.text (que no esta documentado en la ayuda ...) es el texto que irá en la celda actual (recordemos que gambas lleva la cuenta de la columna, fila y, por tanto, la celda donde estamos). ¿Y que debemos meter en esa celda? pues, pasandolo antes a cadena con la función Str, (aqui viene lo liante, preparaos !!) se coje de Mdb.rs1 (la consulta actual con la fila correspondiente ya seleccionada antes) y se lee el campo correspondiente a la Columna (Column) actual del tableView (cuenta que lleva gambas), con lo cual se escribe el contenido correcto ... y la parte contratante de la segunda parte corresponde a la parte contratante de la primera parta y ....

En resumen, cuando se guarde todo y se le dé a ejecutar debe rellenarse el tableview con los datos de la base de datos y si, funcionó. (UUuuufffff, trabajito costo).

Insertar datos:

Bueno, ahora que la base de datos está mostrandonos todo lo que tiene y hemos jugado con ella, será más facil la "penetración" en ella de los datos (me parezco a la Verdú, dos rombos, jeje).

Para ello nos vamos al evento de click del boton insertar(doble click sobre el boton)
y rellenamos el evento con el siguiente código:

PUBLIC SUB Button1_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 = "INSERT INTO HomeGestion.gastos "
     query = query & "SET fecha='" & fechaSQL & "', "
     query = query & "cantidad='" & Val(cantidad.Text) & "', "
     query = query & "concepto='" & concepto.Text & "', "
     query = query & "origen='" & CBorigen.Current.Text & "'"
     'Message.Info(query) ' Test de query
     Mdb.consulta(query)
     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 IF
END


Este codigo podemos dividirlo en dos partes, Insercion y muestreo.

Primero definimos algunas variables que nos harán falta
y "rompemos" la cadena de la fecha por el simbolo "/" (barra del siete, jeje) y creamos la fecha tal y como le gusta a mysql. (que si, que hay mejores manera, pero bueno, cada cuál hace lo que puede, o lo que tiene ganas de poder)

Una vez creado el formato de la fecha y pasado las comprobaciones (ya comentado en anteriores post) pasamos a la insercción de los datos.
A mi personalmente me gusta crear la query o consulta a "cachos" asi que es facil deducir lo que hace cada trozo, aunque merece especial atención la función Val() que parsea (pasa a un tipo) el valor que recibe (Más info en la ayuda).
Es muy conveniente ver que se ha creado antes de darselo a mysql, de ahí ese test de query, aunque ahora este comentado.

Para insertar la consulta podriamos haber usado Mdb.db.exec(), pero me pareció más "bonito" hacer una funcion en Mdb (asi practicaba un poquillo las funciones en Gambas).

'
' Realiza una consulta en la db '
'
PUBLIC SUB consulta(qry AS String)
  rs1 = db.exec(qry)
END


Lo mas simple, no creo que merezca la pena ni comentarlo.

Aquí me di cuenta de un "pequeño" error, y es que las fechas no las formateaba bién (ese jodio formato inglés), entonces, me tocó usar la función Format$(), en todas las funciones que escribian en la caja de texto de la fecha.


Format$(DPselFecha.Value, "dd/mm/yyyy")
Esto en las funciones del datapicker (ya que aún sigo sin saber como se pone en español)
y esto:
fecha.Text = Format$(Date(), "dd/mm/yyyy")
En la función open del formulario principal (la fecha por defecto).

Una vez hecho esto ya estamos insertando datos en nuestra queridisima base de datos.
Pero no debemos olvidar que hay que decirle a la tableview que atualice los datos (nueva fila), asi que repetimos la consulta inicial y le cambiamos el numero de filas y columnas (el refresco de los datos lo hace el solito).

Y con esto y un bizcocho, ya insertamos y vemos lo que hay en la base de datos ... pero somos humanos y nos equivocaremos al meter gastos, y querremos corregirlo (modificar datos) o eliminarlo (eliminar datos), pero eso ya lo veremos en el siguiente post.
[editar]

4 opiniones

Excelente

Soy el del comentario anterior, ya me di de alta...
Excelente

Excelente aporte llevo menos de 4 horas en GAMBAS y este a sido el mejor aporte, muy bien explicado y me entusiasma a seguir con el lenguaje excelente muchas gracias
Codigo fuente.

Excelentes tus "memorias" con gambas, quisiera pedirte el código fuente sino no es mucha molestia para poder probar tu aplicación, ya que estoy interesado en el tema de gambas.
Tableview.

Estoy desarrollando un programita con gambas, me tope con un problema con el tableview,:
1)los datos del texbox deseo insertarlos en la tabla, de uno por ves, para el primero funciona ok, el segundo se despelota, me rellena 2 filas con el mismo dato!
2) alguien sabe como saltar este problema. (las ayudas del gambas no estan presentes para elte punto. Gracias.

Tutoriales relacionados con 'Curso de Gambas'

Hace muuuuucho tiempo, cuando empezaba a aprender algo sobre php, me llamó la atención un... Más »

Autor y licencia de 'Curso de Gambas'


Tutorial de KDE-Hispano. Extraido de: http://www.kdehispano.org/curso_gambas CopyLeft
Creative Commons License
Este contenido ha sido recopilado por el equipo de Wikilearning. Todo el contenido recopilado se ha obtenido respetando y comunicando en nuestro site la licencia de cada fuente.
Wikilearning tiene permiso expreso por escrito de los autores para publicar los contenidos que ha extraído de otras webs, incluyendo su uso comercial.