jueves, 31 de octubre de 2013

Smartform a 3 Niveles - parte 1

Después de mucho tiempo de haber abandonado este ejemplo, por fin puedo ponerlo a la luz.

Básicamente lo que se espera es lo siguiente:

(Agrande la imagen dando click en ella)




Como soy el típico hincha peruano que otra vez se quedó sin mundial pero fiel al castigo vivo al pendiente de mi interesante pero venido a menos futbol local, el ejemplo se basa desarrollar un reporte que muestre como cabecera (primer nivel) los datos del campeonato nacional, un detalle de los clubes que lo componen (segundo nivel) y los jugadores que componen su plantilla (tercer nivel).

Bueno, ¿como hacemos esto? Hay algunas maneras. Por mi parte mostraré la que se me a dado bien en los pocos casos que he visto de esto (uno más y este ejemplo jeje).


PASO 1 - OBTENER_DATA:

Por una cuestión de simplicidad, he hecho el ejemplo en el mismo smartform sin crear y utilizar un programa Z aparte para el llamado del mismo, esto quiere decir que he utilizado las definiciones globales para mis variables, estructuras y tablas.

Me dí el trabajo de llenar el campeonato, los 16 clubes del 2013 y algunos nombres de jugadores a la manera del comercial de la selección: "Soy hincha, y no me compadezcas... ni trates de entender una insanía, porque donde habita la pasión, no hay lugar para nada más..."
En fin a las imágenes me remito:



A explicar:
En el primer cuadro se declaranlas variables, constantes, estructuras o tablas que vamos a utilizar.
En el segundo cuadro, vamos a colocar los tipos para nuestras estructuras y tablas, y aquí si voy a indicar que, las estructuras y tablas tienen declaraciones de tipos diferentes. La declaración normal y típica para las estructuras y; como si estuviesemos creando una tabla interna excepto que en vez de DATA colocamos TYPES, es la declaración para los tipos de tabla.

*ESTRUCTURAS{
typesbegin of y_cab,
       cabid    type belnr_d,
       anio(4)  type n,
       pais     type ttet_descrip30,
       titulo   type txdim,
       descri   type cts_description,
       equips   type i,
       campnac  type cts_description,
       subcamp  type cts_description,
       terpsto  type cts_description,
       end   of y_cab. 
*}

*TABLAS{
typesgty_cab type standard table of y_cab.  
*}

En el tercer cuadro, la parte del initialization, hacemos las llamadas a las rutinas que van a llenar nuestras tablas de campeonatos, equipos y jugadores.
En el cuarto cuadro, creamos las rutinas y también una lógica que nos permita mostrar a los jugadores según el formato que observamos en la primera pantalla.

Veamos de manera general que datos nos pide el ejemplo:

CAMPEONATOS:
st_cab-cabid   '2013PER001'.
st_cab-anio    '2013'.
st_cab-pais    'Perú'.
st_cab-titulo  'Copa Movistar 2013'.
st_cab-descri  'Campeonato descentralizado de futbol Peruano.'.
st_cab-equips  '16'.
st_cab-campnac 'Alianza Lima'.
st_cab-subcamp 'Universitario'.
st_cab-terpsto 'Real Garcilazo'.
append st_cab to ti_cab.

EQUIPOS:
st_det1-det1id '2013EQP001'.
st_det1-cabid  '2013PER001'.
st_det1-club   'Alianza Lima'.
st_det1-ciudad 'Lima'.
st_det1-entren 'Francisco Pizarro'.
st_det1-estadi 'Alejandro Villanueva'.
append st_det1 to ti_det1.

JUGADORES:
st_det2-det2id '2013JUG001'.
st_det2-det1id '2013EQP001'.
st_det2-cabid  '2013PER001'.
st_det2-numero '1'.
st_det2-posic  'POR'.
st_det2-nombre 'George Forsyth'.
append st_det2 to ti_det2.

Las rutinas son simples: Agarramos la estructura, le pasamos datos y añadimos los datos a la tabla correspondiente, nada que resaltar aquí.

Ahora, el ejemplo nos pide que en una fila podamos mostrar a 3 jugadores, por tanto el recorrido que hagamos a la tabla para mostrar de esa manera a los jugadores no va a ser la forma común, tenemos que acondicionar los datos primero.

Para esto, se ha creado una rutina adicional y una tabla adicional donde se va a tener la data de tal forma que al imprimirse en el smartform nos de el formato que buscamos. Deben haber de seguro otras mejores formas de hacerlo, pero yo me decanto por esta ya que la he utilizado en mis proyectos y
POR QUE ES LA ÚNICA QUE SÉ



Bueno directo al grano:

  form formato_det2   using st_det2     type y_det2
                           ti_det2     type gty_det2
                  changing st_detout   type y_detout
                           ti_detout   type gty_detout.

Se utilizan la estructura y tabla de los jugadores enviadas desde el initialization, y llenamos en fin la tabla TI_DETOUT que es la que al final se tiene que mostrar en el smartform. Esta tabla a tener los campos siguientes:

       det1id   type belnr_d,"Código de Equipo
       cabid    type belnr_d,"Código de Campeonato

       num1(2)  type n,      "Número de camiseta
       pos1(20) type c,      "Posición dentro del campo
       nom1(30type c,      "Nombre del jugador

       num2(2)  type n,      "Número de camiseta
       pos2(20) type c,      "Posición dentro del campo
       nom2(30type c,      "Nombre del jugador


       num3(2)  type n,      "Número de camiseta
       pos3(20) type c,      "Posición dentro del campo
       nom3(30type c,      "Nombre del jugador 


Como se puede observar, esta tabla tiene la forma para que en una fila se ingresen 3 jugadores.


         
        datalv_ord type i."Tenemos una variable local que nos va a servir para agrupar de 3 en 3 las filas.

        sort ti_det2 by det1id cabid posic numero."Ordenamos por código de equipo y código de campeonato. En la tabla TI_DET2, DET1ID tiene que ser el primero (incluso primero que el código de campeonato y jugador) ya que esto nos podrá permitir realizar los quiebres dentro del bucle correctamente.

        loop at ti_det2 into st_det2."Hacemos el bucle

          lv_ord lv_ord + 1."añadimos al contador 1

"En esta parte simplemente condicionamos que cuando el contador sea 1, 2 o 3, envíe al jugador dentro de la fila a la columna correspondiente. Cuando el contador llegue a 3, entonces le haga un append a la tabla, agregando esos 3 jugadores en una sola fila. Inicializamos el contador y limpiamos la estructura de la tabla.
            if lv_ord eq 1.
            st_detout-det1id st_det2-det1id.
            st_detout-cabid  st_det2-cabid.
            st_detout-num1   st_det2-numero.
            st_detout-pos1   st_det2-posic.
            st_detout-nom1   st_det2-nombre.
          elseif lv_ord eq 2.
            st_detout-num2   st_det2-numero.
            st_detout-pos2   st_det2-posic.
            st_detout-nom2   st_det2-nombre.
          elseif lv_ord eq 3.
            st_detout-num3   st_det2-numero.
            st_detout-pos3   st_det2-posic.
            st_detout-nom3   st_det2-nombre.
            append st_detout to ti_detout.
            clearlv_ordst_detout.
          endif.

          at end of det1id."Se ingresa cuando es el último código de equipo que se ha venido repitiendo. Al ingresar valida si no ha hecho un append anteriormente (ST_DETOUT no es vacío) para hacer el append e inicializar el contador. Esto es en el caso de que sea el ultimo jugador del equipo pero que no sea el tercero de la columna en la fila.
            if st_detout is not initial.
              append st_detout to ti_detout.
              clearlv_ordst_detout.
            endif.
          endat.

        endloop.

endform.




Aquí tenemos a 2 diferentes equipos: 2013EQP001 (3 jugadores), 2013EQP006 (4 jugadores), 2013EQP009 (1 jugador) y 2013EQP011 (2 jugadores).


Al final la tabla que nos arrojaría sería:


De esta última tabla deducimos:

Inicio del bucle{
Línea 1:
Ingresa a la condición LV_ORD = 3 para hacer append e inicializar el contador.
Ingresa a la ruptura pero no cumple la condición  por que el append ya se hizo.

Línea 2:
Ingresa a la condición LV_ORD = 3 para hacer append e inicializar el contador.
NO ingresa a la ruptura pues no es el último código de equipo que se repite.
Línea 3:
NO ingresa a la condición LV_ORD = 3, sino a la 1.
Ingresa a la ruptura y cumple condición haciendo el append e inicializando el contador.

Línea 4:
NO ingresa a la condición LV_ORD = 3, sino a la 1.
Ingresa a la ruptura y cumple condición haciendo el append e inicializando el contador.

Línea 5:
NO ingresa a la condición LV_ORD = 3, sino a las 1 y 2.
Ingresa a la ruptura despues de ingresar a la condición 2 y cumple la condición haciendo el append e inicializando el contador.

}Fin del bucle.

Hasta aquí aunque no hemos visto nada de la estructura interna del smartform, tenemos cubierta la parte de la data que debe mostrarse y como debe mostrarse.

Bueno, hagamos pase a la segunda parte.

No hay comentarios:

Publicar un comentario