Problema creacion de ALV OO y refresco

Colapsar
X
 
  • Tiempo
  • Mostrar
Limpiar Todo
nuevos mensajes
  • Siem
    Member
    • jul
    • 33

    #1

    Problema creacion de ALV OO y refresco

    Hola compañeros:

    Les expongo un caso que me esta ocurriendo y no se muy bien el motivo.

    Tengo una primera dynpro 0050 con un ALV el cual tiene varios botones. Algunos de esos botones me abren una dynpro 0200 que sirve para Crear/Modificar/Copiar registros y segun los datos que rellenemos, esta llama a otra dynpro 0300 que continene un ALV orientado a objetos.

    En el PBO del dynpro 0300, si no existe, creo el container, el catalogo y el ALVgrid, para finalemente llamar al método ->set_table_for_first_display.

    Hasta aqui funciona correcto.

    El problema viene cuando desde el dynpro 0050, pulso a un boton dde consulta que llama al dynpro 0300 sin pasar por el 0200. El PBO es el mismo, pero como ya existe el ALV OO, en lugar de crearlo, llamo al metodo ->refresh_table_display. Y me muestra la dynpro 0300 sin ALV.

    He probado a destruir el ALV y crearlo de nuevo y entonces si funciona, pero me hace cosas raras con los datos. Sin embargo, el caso anterior, las tablas internas se mantienen con los datos correctos.

    Mi duda es la siguiente:

    Puede ser que al crear 0050 --> 0200 --> 0300 --> ALV OO y luego intentar acceder 0050 --> 0300 --> ALV OO haya algun problema por haberme saltado la dynpro 0200?

    Disculpad si me he extendido demasiado, pero es que para mi este problema es muy raro.

    Muchas gracias por anticipado.
  • ballan
    Senior Member
    • oct
    • 671

    #2
    Buenos dias

    Creo que tu problema esta en como has definido el custom container y el objeto grid

    Supongo que en tu programa habras creado el custom container y el control grid con una llamada de este estilo

    CREATE OBJECT custom_container
    EXPORTING
    container_name = 'NOMBRE_CUSTOM_CONTAINER'
    lifetime = cntl_lifetime_dynpro
    EXCEPTIONS
    cntl_error = 1
    cntl_system_error = 2
    create_error = 3
    lifetime_error = 4
    lifetime_dynpro_dynpro_link = 5
    OTHERS = 6.

    La clave es que cuando crees tanto el custom container como el control grid tienes que crearlo pasandole el valor cntl_lifetime_dynpro al parametro lifetime

    Haciendolo asi si llamas al metodo free y luego haces un cl_gui_cfw=>flush( ).

    Cuando se salga de esa pantalla los objetos "moriran"

    El problema es que el parametro lifetime dynpro no se suele rellenar y por defecto es para toda la transaccion, por eso aunque llames al metodo free y hagas un flush los objetos "no mueren"

    Disculpas por la explicacion un poco bananera pero espero que se me haya entendido

    Comentario

    • Siem
      Member
      • jul
      • 33

      #3
      Muchas gracias Ballan.

      Bananera o no, por ahora es la unica respuesta que tengo

      El caso es que lo que tu propones es destruir el ALV y volverlo a crear, pero esa prueba ya la hice y funcionaba, aunque no se por que, los datos no eran los esperados. El caso es que yo quiero dejar el ALV activo y usarlo cuantas veces me haga falta con el metodo refresh_table_display, modificando solo la tabla interna de la que se nutre.

      Aun así, te digo que tu respuesta me ha aportado mas de lo que crees. Muchas gracias.

      Pero sigo sin saber por que no me muestra el ALV. Se supone que cuando yo lo creo, lo creo como global para el programa, pero debe depender de algo por ahi que si no existe, no me lo muestra.

      A ver si alguien da un poco de luz Thx.

      Comentario

      • ballan
        Senior Member
        • oct
        • 671

        #4
        Yo hace tiempo tuve una experiencia parecida, ya no recuerdo como era el caso exactamente pero yo cambiaba las lineas de mi tabla, hacia un refresh table display y o no me mostraba nada o bien me mostraba datos anteriores

        Lo primero de todo es asegurarte que lo que ves es lo que hay y me explico, añade el boton de refrescar en tu alv (si en tu fcat le marcas el edit a algun campo el standard te añade automaticamente entre otros el boton de refrescar) y cuando veas que los datos que te aparecen en pantalla no te cuadran con lo que deberia salir pulsa el boton de refrescar porque a veces ocurre que lo que vemos en pantalla es como una version antigua de los datos

        Al fin y al cabo lo que estas teniendo son problemas de sincronizacion entre R3 y el GUI, hace tiempo escribi un post donde hablaba un poco de estos temas, aqui te lo dejo para que lo eches un vistazo por si te puede ser de ayuda



        Otro detalle importante es que despues de hacer un refresh_table_display haz tambien una llamada al cl_gui_cfw=>flush( ). para "asegurarte" que se sincronizan los datos

        Comentario

        • Siem
          Member
          • jul
          • 33

          #5
          Lo que pasa es que a mi no me muestra el ALV. SOlo sale el dynpro vacio.
          Es el mismo efecto que si no existiera el objeto contenedor del alv.

          A modo de resumen:

          Cuando lo creo:
          0050 --> 0200 --> 0300 --> ALV OO
          Al hacer el refresh_table_display
          0050 --> 0200 --> 0300 --> ALV OO -----> OK
          0050 --> 0300 --> ALV OO --------------> No se ve el ALV

          Supuestamente el ALV esta asociado al dynpro 0300, pero se ve que debe haber alguna referencia que quede por ahi al crearlo pasando por la dynpro 0200.

          Gracias de nuevo.

          Comentario

          • lehua768
            Junior Member
            • jun
            • 2

            #6
            ya no recuerdo como era el caso exactamente pero yo cambiaba las lineas de mi tabla, hacia un refresh table display y o no me mostraba nada o bien me mostraba datos anterioresLo primero de todo es asegurarte que lo que ves es lo que hay y me explico, añade el boton de refrescar en tu alv (si en tu fcat le marcas el edit a algun campo el standard te añade automaticamente entre otros el boton de refrescar) y cuando veas que los datos que te aparecen en pantalla no te cuadran con lo que deberia salir pulsa el boton de refrescar porque a veces ocurre que lo que vemos en pantalla es como una version antigua de los datosAl fin y al cabo lo que estas teniendo son problemas de sincronizacion entre R3 y el GUI, hace tiempo escribi un post donde hablaba un poco de estos temas, aqui te lo dejo para que lo eches un vistazo por si te puede ser de ayudaEl caso es que lo que tu propones es destruir el ALV y volverlo a crear, pero esa prueba ya la hice y funcionaba, aunque no se por que, los datos no eran los esperados. El caso es que yo quiero dejar el ALV activo y usarlo cuantas veces me haga falta con el metodo refresh_table_display, modificando solo la tabla interna de la que se nutre.
            Replica Handbags
            Replica Watches
            Replica Handbags

            Comentario

            • Siem
              Member
              • jul
              • 33

              #7
              Originalmente publicado por lehua768
              ya no recuerdo como era el caso exactamente pero yo cambiaba las lineas de mi tabla, hacia un refresh table display y o no me mostraba nada o bien me mostraba datos anterioresLo primero de todo es asegurarte que lo que ves es lo que hay y me explico, añade el boton de refrescar en tu alv (si en tu fcat le marcas el edit a algun campo el standard te añade automaticamente entre otros el boton de refrescar) y cuando veas que los datos que te aparecen en pantalla no te cuadran con lo que deberia salir pulsa el boton de refrescar porque a veces ocurre que lo que vemos en pantalla es como una version antigua de los datosAl fin y al cabo lo que estas teniendo son problemas de sincronizacion entre R3 y el GUI, hace tiempo escribi un post donde hablaba un poco de estos temas, aqui te lo dejo para que lo eches un vistazo por si te puede ser de ayudaEl caso es que lo que tu propones es destruir el ALV y volverlo a crear, pero esa prueba ya la hice y funcionaba, aunque no se por que, los datos no eran los esperados. El caso es que yo quiero dejar el ALV activo y usarlo cuantas veces me haga falta con el metodo refresh_table_display, modificando solo la tabla interna de la que se nutre.
              A ver, centrémonos. El problema no es que el alv me muestre datos incorrectos, o que el metodo de refresco no lo haga correctamente. El problema es que no aparece el ALV, ni botones ni nada. Solo una pantalla vacia, cuando se supone que el contenedor y el ALV estan creados, porque yo en ningun momento los destruyo, y ademas, haciendo el debug, los objetos existen:

              IF G_grid_ACT IS INITIAL. " Este es el objeto ALV
              PERFORM CREA_ALV_ACT.
              ELSE. " En el debugg, se mete por aqui, luego existe el objeto.
              CALL METHOD G_GRID_ACT->REFRESH_TABLE_DISPLAY.
              ENDIF.

              Con lo cual, si existe, no se por que no lo muestra. LAs tablas internas tiene los datos correctos, pero al no mostrar el ALV, no muestra los datos.

              Gracias a ti tambien lehua768

              Comentario

              • ballan
                Senior Member
                • oct
                • 671

                #8
                Ok, habia entendido mal el problema, no obstante todo lo que hemos hablado creo que tambien aplica a tu caso, por ejemplo el fragmento de codigo que me has puesto

                IF G_grid_ACT IS INITIAL. " Este es el objeto ALV
                PERFORM CREA_ALV_ACT.
                ELSE. " En el debugg, se mete por aqui, luego existe el objeto.
                CALL METHOD G_GRID_ACT->REFRESH_TABLE_DISPLAY.
                ENDIF.

                No es del todo correcto

                en lugar de preguntar

                IF G_grid_ACT IS INITIAL

                deberias preguntar (no tengo sap delante por lo que quiza lo que pongo debajo no es del todo correcto sintacticamente pero es para que te hagas una idea)

                if g_grid_act->is_alive( ) = g_grid_act->state_alive

                En resumen, lo primero que haria es ver cual es el estado REAL del grid, porque puede ser que NO SEA INICIAL, pero por ejemplo si anteriormente han llamado al metodo FREE, aunque el valor del grid no sea inicial ya no seria "utilizable" por lo tanto no te lo mostraria, para poder ver el status puedes introducir el siguiente codigo

                data: lv_state type i.

                lv_state = g_grid_act->is_alive( ).

                Comentario

                • Siem
                  Member
                  • jul
                  • 33

                  #9
                  Originalmente publicado por ballan

                  data: lv_state type i.

                  lv_state = g_grid_act->is_alive( ).
                  He probado lo que me has dicho, y esta linea, aunque compila correctamente, me devuelve un dump. ???

                  No entiendo por que porque mira que es simple la instruccion


                  El metodo is_alive( ) nofunciona en mi sistema. Que raro.

                  Comentario

                  • ballan
                    Senior Member
                    • oct
                    • 671

                    #10
                    Si te esta dando dump puede ser porque la clase no este instanciada o bien porque no devuelva un valor de tipo i, no tengo sap delante asi que no te lo puedo mirar pero si te fijas en la clase CL_GUI_ALV_GRID en los parametros del metodo IS_ALIVE fijate en cual es el tipo que te devuelve, yo creia que era tipo I pero puede ser que sea alguno diferente

                    El codigo quedaria algo asi

                    data: lv_state type (tipo que hayas visto en la clase CL_GUI_ALV_GRID).

                    if not g_grid_act is initial.
                    lv_state = g_grid_act->is_alive( ).
                    endif.

                    Comentario

                    • Siem
                      Member
                      • jul
                      • 33

                      #11
                      Lo habia mirado ya y es correcto el tipo que habias puesto. Es de tipo i.

                      El simple hecho de llamar al metodo is_alive, me da un dump, y no deberia

                      Comentario

                      • ballan
                        Senior Member
                        • oct
                        • 671

                        #12
                        Pero g_grid_act es inicial o no?

                        Pegame el dump para que veamos que es lo que pasa

                        Comentario

                        • Siem
                          Member
                          • jul
                          • 33

                          #13
                          Originalmente publicado por Siem
                          A modo de resumen:

                          Cuando lo creo:
                          0050 --> 0200 --> 0300 --> ALV OO
                          Al hacer el refresh_table_display
                          0050 --> 0200 --> 0300 --> ALV OO -----> OK
                          0050 --> 0300 --> ALV OO --------------> No se ve el ALV
                          He hecho la prueba al reves y tampoco va.

                          Cuando lo creo:
                          0050 --> 0300 --> ALV OO
                          Al hacer el refresh_table_display
                          0050 --> 0200 --> 0300 --> ALV OO -----> No se ve el ALV
                          0050 --> 0300 --> ALV OO --------------> OK

                          Originalmente publicado por ballan
                          Pero g_grid_act es inicial o no?

                          Pegame el dump para que veamos que es lo que pasa
                          La primera vez que intento acceder a la dynpor 0300, evidentemente es initial, por lo que crea el ALV y lo muestra correctamente. Si vuelvo a acceder por el mismo camino,el refresh_table_display lo muestra correctamente. Pero si ahora accedo por el otro camino (Sin pasar por la dynpro 0200) el refresh_table_display no muestra el alv. En este caso el
                          g_grid_act no es initial.


                          Pego ahora el dump que da el metodo is_alive( )

                          Texto breve
                          Access via 'NULL' object reference not possible.

                          ¿Qué ha sucedido?
                          Error in the ABAP Application Program

                          The current ABAP program "ZRFCTA_DEPOS" had to be terminated because it has come across a statement that unfortunately cannot be executed.

                          Anál.errores
                          An exception occurred that is explained in detail below.
                          The exception, which is assigned to class 'CX_SY_REF_IS_INITIAL', was not caught in procedure "STATUS_0300" "(FORM)", nor was it propagated by a RAISING clause.
                          Since the caller of the procedure could not have anticipated that the exception would occur, the current program is terminated.
                          The reason for the exception is:
                          You attempted to use a 'NULL' object reference (points to 'nothing')
                          access a component (variable: "G_GRID_ACT").
                          An object reference must point to an object (an instance of a class)
                          before it can be used to access components.
                          Either the reference was never set or it was set to 'NULL' using the
                          CLEAR statement.

                          Eso es lo que me dice, simplemente por poner la linea:

                          DATA lv_state type i.

                          >>>>> lv_state = g_grid_act->is_alive( ).


                          De nuevo muchas gracias por tu tiempo, Ballan

                          Comentario

                          • ballan
                            Senior Member
                            • oct
                            • 671

                            #14
                            El dump te esta dando porque g_grid_act es inicial, esta intentando llamar a un metodo de un objeto que no esta instanciado

                            Bien yo creo que aqui se abren dos caminos y tendria que ver el codigo para saber lo que esta pasando exactamente pero te digo las opciones que hay tal y como yo lo veo

                            Opcion 1.- Corregir el algoritmo para la creacion o refresco del ALV

                            Deberia quedar algo mas o menos asi

                            Código:
                            DATA: lv_state TYPE i.
                            
                            IF g_grid_act IS INITIAL.
                            ....CREAR OBJETO GRID
                            ELSE.
                            
                            "Al llamarlo aqui evitaras que de dump porque g_grid_act nunca sera inicial     
                            lv_state = g_grid_act->is_alive( ) 
                            
                            IF lv_state = g_grid_act->state_dead.
                            CREAR OBJETO GRID
                            ELSE.
                            REFRESCAR OBJETO GRID
                            ENDIF.
                            
                            ENDIF.
                            Opcion 2 Tendria que ver el codigo, pero es posible que en algun momento se este llamando al metodo free de g_grid_act o bien que lo hayas creado con lifetime_dynpro y al hacer alguna operacion el objeto se "libera" automaticamente, con esto lo que quiero decir es que por ejemplo puede ser que tu veas que g_Grid_act NO ES INICIAL, es decir que contiene "algo" pero realmente eso es falso porque luego si llamas al metodo IS_ALIVE te devuelve state_dead

                            Si te devuelve state_dead tendras que crearlo aunque no sea inicial porque la unica la razon por la que no es inicial es porque todavia no ha pasado el "garbage collector" (aunque este concepto es mas de otros lenguajes)

                            Para explicar esto pongo un ejemplo, si yo escribiera el siguiente codigo

                            Código:
                            DATA: go_cc TYPE REF TO cl_gui_custom_container,
                            go_grid TYPE REF TO cl_gui_alv_grid.
                            
                            "Voy a obviar los parametros al crear
                            CREATE OBJECT go_cc. 
                            
                            CREATE OBJECT go_grid.
                            
                            go_grid->free( ).
                            
                            Si yo en este punto del programa miro la variable go_grid vere que NO ES INICIAL, esta rellena pero realmente el objeto grid ya no es utilizable porque ya lo mande "morir" asi que tendria que crearlo otra vez
                            Asi que tambien deberias buscar si en algun sitio se esta haciendo un free ya sea del objeto grid o del container sobre el que esta definido y es eso lo que te esta trastocando

                            Comentario

                            • Siem
                              Member
                              • jul
                              • 33

                              #15
                              Yo me inclino mas por la segunda opcion, pero: ¿Que pasa si el parámetro lifetime no esta indicado? ¿Toma algun valor por defecto?.Si se queda con state_dead al cerrar la dynpro donde se creo el ALV, pues entonces estará ahi el problema, aunque si vuelvo a llamar a la dynpro porel mismo camino,el ALV sigue ahí. Si la llamo por otro camino, el ALV no aparece.

                              La aplicacion la he hecho yo al completo, asi que se que no hay ningun free en el codigo.

                              De todos modos, hay una cosa que no entiendo. Y es que como puede dar un dump, el metodo IS_ALIVE si precisamente sirve para ver si existe o no.
                              Editado por última vez por Siem; 05/07/2010, 08:56:03.

                              Comentario

                              Trabajando...