Wechselnder Containerinhalt

Die Objektorientierung mit ABAP®: Vererbung, Dynamische Programmierung, GUI Controls (u.a. ALV im OO).
4 Beiträge • Seite 1 von 1
4 Beiträge Seite 1 von 1

Wechselnder Containerinhalt

Beitrag von creative235 (ForumUser / 4 / 2 / 0 ) »
Hallo zusammen,

ich entwickle gerade einen Report und arbeite dort mit CL_GUI_SPLITTER_CONTAINER. Einen dieser gesplitteten Container wird / soll bei gewissen Aktionen unterschiedliche Dinge anzeigen (SALV-Liste oder CL_DD_DOCUMENT). Hierfür habe ich Steuerungsvariablen genutzt, welche bestimmen welcher Inhalt gerade angezeigt wird und auf welchen Inhalt umgesteuert wird.

Zum "resetten" der Container nutze ich die Methode "REMOVE_CONTROL()" der Klasse CL_GUI_SPLITTER_CONTAINER. Nach dem dritten Switch des Inhaltes erhalte ich immer einen Dump (Egal von wo, nach wo ich springe). Die Meldung sagt folgendes aus: "Ausnahmebedingung "INDEX_EXCEEDS_LINES_ERROR" ausgelöst"

Ausgelöst wird der Dump in der Methode GET_CHILD(). Meine Logik sieht folgendermaßen aus:

Form zum befüllen des Containers:

Code: Alles auswählen.

    IF iv_init_call = abap_false.
      IF use_notes = abap_true AND ( jmp_lief = abap_true OR jmp_best = abap_true ).
        gr_sc_0100_right->remove_control( EXPORTING  row               = 2
                                                     column            = 1
                                          EXCEPTIONS cntl_error        = 1
                                                     cntl_system_error = 2
                                              OTHERS                   = 99 ).
      ENDIF.

      IF use_lief = abap_true AND ( jmp_notes = abap_true OR jmp_best = abap_true ).
        gr_sc_0100_right->remove_control( EXPORTING  row               = 2
                                             column            = 1
                                  EXCEPTIONS cntl_error        = 1
                                             cntl_system_error = 2
                                      OTHERS                   = 99 ).
      ENDIF.

      IF jmp_lief = abap_true.
        PERFORM show_lief USING p_auftrag p_posnr.
        jmp_lief = abap_false.
      ENDIF.

      IF jmp_notes = abap_true.
        PERFORM show_notes USING p_auftrag.
        jmp_notes = abap_false.
      ENDIF.

    ENDIF.
Die entsprechenden Methoden sind folgendermaßen aufgebaut:

SHOW_NOTES:

Code: Alles auswählen.

    DATA iv_text            TYPE sdydo_text_element.
    DATA lr_form            TYPE REF TO cl_dd_form_area.
    DATA iv_value           TYPE sdydo_value.
    DATA iv_buttont         TYPE string.
    DATA iv_button          TYPE REF TO cl_dd_button_element.
    DATA lr_co_0100_center  TYPE REF TO cl_gui_container.

    lr_co_0100_center = gr_sc_0100_right->get_container( row    = 2
                                                         column = 1 ).

    IF gr_dd_0100_center IS INITIAL.
      CREATE OBJECT gr_dd_0100_center.
    ELSE.
      gr_dd_0100_center->initialize_document( ).
    ENDIF.

    gr_dd_0100_center->add_form( IMPORTING formarea = lr_form ).
    CONCATENATE 'Notiz für Auftrag' p_auftrag INTO iv_text SEPARATED BY space.

    lr_form->add_text_as_heading(
      EXPORTING
        text          = iv_text
        heading_level = 3
    ).
    lr_form->underline( ).
    lr_form->new_line( ).

    SELECT SINGLE * FROM zsd_objektauf WHERE vbeln = @p_auftrag INTO @DATA(iv_notiz). "#EC CI_ALL_FIELDS_NEEDED
    IF sy-subrc IS INITIAL.
      iv_value = iv_notiz-text.
    ENDIF.

    IF iv_value IS INITIAL.
      iv_text = 'Keine Notiz vorhanden'.
    ELSE.
      CONCATENATE 'Notiz:' iv_value INTO iv_text SEPARATED BY space.
      lr_form->add_icon(
        EXPORTING
          sap_icon         = 'ICON_MESSAGE_INFORMATION'
      ).
    ENDIF.

    lr_form->add_text(
          EXPORTING
            text          = iv_text            " Einzeltext, bis zu 255 Zeichen lang
            sap_style     = cl_dd_area=>emphasis                 " Empfohlene Stilarten
        ).

    lr_form->new_line( ).
    lr_form->new_line( ).

    lr_form->add_input_element(
       EXPORTING
         value         = iv_value
         name          = 'Input'                 " Name (kann frei vergeben werden)
         size          = 87                 " Breite des Eingabefeldes
         maxlength     = 200                 " maximal erlaubte Länge der Texteingabe
       IMPORTING
         input_element = iv_input                 " Eingabe-Element
    ).

    lr_form->new_line( ).
    lr_form->new_line( ).

    IF iv_value IS INITIAL.
      iv_buttont = 'Anlegen'.
    ELSE.
      iv_buttont = 'Ändern'.
    ENDIF.

    lr_form->add_button(
       EXPORTING
         label    = iv_buttont
         sap_icon = 'ICON_SYSTEM_SAVE'                 " Name der SAP Ikone aus Tabelle ICON (ICON_TREE, ICON_...)
         name     = 'savebutton'                  " Name (kann frei vergeben werden)
       IMPORTING
         button   = iv_button                 " Button Element
    ).

    SET HANDLER lcl_events=>on_button_clicked FOR iv_button .

    gr_dd_0100_center->merge_document( ).
    gr_dd_0100_center->display_document(
      EXPORTING
        reuse_control      = abap_true                 " HTML_Control wird wiederverwendet
        parent             = lr_co_0100_center                 " Container-Objekt (ist schon vorhanden)
      EXCEPTIONS
        html_display_error = 1                " Fehler beim Anzeigen des Dokuments im HTML Control
        OTHERS             = 2
    ).

    use_notes = abap_true.
    use_best = abap_false.
    use_lief = abap_false.
SHOW_LIEF

Code: Alles auswählen.

    DATA: iv_refresh    TYPE abap_bool,
          lr_layout     TYPE REF TO cl_salv_layout,
          lr_columns    TYPE REF TO cl_salv_columns_table,
          lr_column     TYPE REF TO cl_salv_column,
          lr_selections TYPE REF TO cl_salv_selections,
          lr_functions  TYPE REF TO cl_salv_functions.

    lr_co_0100_center = gr_sc_0100_right->get_container( row    = 2
                                                         column = 1 ).

*   Lieferungen-Tabelle wurde bereits zu einem frühren Zeitpunkt aufgerufen
*   -> Refresh
    IF gr_salvtab_lief IS BOUND.
      iv_refresh = abap_true.
    ENDIF.

    PERFORM select_lieferscheine USING p_auftrag p_posnr.

    LOOP AT it_lief ASSIGNING FIELD-SYMBOL(<fs_lieferung>).

      CASE <fs_lieferung>-wbstk.
        WHEN 'A'.
          <fs_lieferung>-wbs_t = 'Nicht bearbeitet'.
          <fs_lieferung>-icons = icon_led_red.
        WHEN 'B'.
          <fs_lieferung>-wbs_t = 'Teilweise bearbeitet'.
          <fs_lieferung>-icons = icon_led_yellow.
        WHEN 'C'.
          <fs_lieferung>-wbs_t = 'Vollständig bearbeitet'.
          <fs_lieferung>-icons = icon_led_green.
      ENDCASE.

    ENDLOOP.

    IF iv_refresh = abap_true.
      iv_refresh = abap_false.
      gr_salvtab_lief->refresh( ).
    ENDIF.

    IF gr_salvtab_lief IS INITIAL.
      TRY.
          CALL METHOD cl_salv_table=>factory
            EXPORTING
              list_display = space
              r_container  = lr_co_0100_center
            IMPORTING
              r_salv_table = gr_salvtab_lief
            CHANGING
              t_table      = it_lief.
        CATCH cx_salv_msg.
          MESSAGE e999(zbc) WITH 'Fehler bei Listanzeige'.
      ENDTRY.

      lr_columns = gr_salvtab_lief->get_columns( ).
      lr_columns->set_optimize( abap_true ).

      TRY.
          DATA(o_col) = CAST cl_salv_column_table( lr_columns->get_column( 'ICONS' ) ).
          o_col->set_alignment(
              value = if_salv_c_alignment=>centered
          ).
        CATCH cx_root INTO DATA(lv_error).
      ENDTRY.

      TRY.
          o_col = CAST cl_salv_column_table( lr_columns->get_column( 'WBSTK' ) ).
          o_col->set_alignment(
              value = if_salv_c_alignment=>centered
          ).
        CATCH cx_root INTO lv_error.
      ENDTRY.

      TRY.
          r_column ?= lr_columns->get_column( 'VBELV' ).
          r_column->set_medium_text( 'Verkaufsb.' ).
          r_column->set_long_text( 'Verkaufsbeleg' ).
          r_column->set_short_text( 'VBELN' ).
        CATCH cx_salv_not_found.
          MESSAGE e000(zwm)
               WITH 'Fehler beim Setzen der Spaltentexte.'.
      ENDTRY.

      TRY.
          r_column ?= lr_columns->get_column( 'WBS_T' ).
          r_column->set_medium_text( 'Warenbewegs.' ).
          r_column->set_long_text( 'Warenbewegstatus' ).
          r_column->set_short_text( 'WBSTK' ).
        CATCH cx_salv_not_found.
          MESSAGE e000(zwm)
               WITH 'Fehler beim Setzen der Spaltentexte.'.
      ENDTRY.

      TRY.
          r_column ?= lr_columns->get_column( 'ICONS' ).
          r_column->set_medium_text( 'Status' ).
          r_column->set_long_text( 'Status' ).
          r_column->set_short_text( 'Status' ).
        CATCH cx_salv_not_found.
          MESSAGE e000(zwm)
               WITH 'Fehler beim Setzen der Spaltentexte.'.
      ENDTRY.

*     Drucktasten aktivieren
      lr_functions = gr_salvtab_lief->get_functions( ).
      lr_functions->set_all( abap_true ).

      lr_layout = gr_salvtab_lief->get_layout( ).
      IF p_lay3 IS NOT INITIAL.
        lr_layout->set_initial_layout( p_lay3 ).
      ENDIF.
      ls_key-report =  sy-cprog.
      lr_layout->set_key( ls_key ).

      lr_layout->set_save_restriction( if_salv_c_layout=>restrict_none ).

      lr_selections = gr_salvtab_lief->get_selections( ).
      lr_selections->set_selection_mode( if_salv_c_selection_mode=>none ).

      lr_event_tab = gr_salvtab_lief->get_event( ).
      SET HANDLER lcl_events2=>on_double_click FOR gr_salvtab_lief->get_event( ).

      gr_salvtab_lief->display( ).
    ENDIF.

    use_notes = abap_false.
    use_best = abap_false.
    use_lief = abap_true.
Die dritte Methode (Weshalb es die Steuerungsvariablen USE_BEST und JMP_BEST exsitieren) habe ich noch nicht implementiert, da ich zuerst diesen sehr ärgerlichen Fehler beheben möchte.

Hat jemand eine Idee?

Viele Grüße,
Dennis


Re: Wechselnder Containerinhalt

Beitrag von a-dead-trousers (Top Expert / 3757 / 142 / 983 ) »
Das mit dem Entfernen und wieder Hinzufügen ist im CFW immer etwas hakelig. Die bessere Lösung wäre meines Erachtens, alle Controlvarianten im Splitter abzubilden und dann mittels "Ausblenden" (Zeile auf Höhe 0 setzen) jene Teile wegzuschalten die aktuell nicht gebraucht werden.

Zur Info:
Nicht das REMOVE_CONTROL bzw. ADD_CONTROL machen hier die meisten Probleme, sondern die Registrierung der Events. Diese beruhen nähmlich auf den ParentIDs der Container und nicht auf denen der eigentlichen Controls. Deswegen hab ich früher mal eine solche Aufgabenstellung nur lösen können, indem ich die Controls die ich ein-/ausblenden wollte in einen eigenen Splitter-Container gepackt habe und dann diese Splitter-Container in meinem Hauptsplitter-Container mit ADD_CONTROL bzw. REMOVE_CONTROL verwaltet habe.
Bis ich dann eben auf die Möglichkeit mit dem Setzen der Höhe auf 0 gestoßen bin (im Standard z.B. in CL_GUI_CONTAINER_BAR in Verwendung), was weitaus besser funktioniert und viel weniger Probleme verursacht.

Folgende Benutzer bedankten sich beim Autor a-dead-trousers für den Beitrag (Insgesamt 3):
fr-gcreative235Thomas R.

Theory is when you know something, but it doesn't work.
Practice is when something works, but you don't know why.
Programmers combine theory and practice: Nothing works and they don't know why.

ECC: 6.07
Basis: 7.40

Re: Wechselnder Containerinhalt

Beitrag von black_adept (Top Expert / 3617 / 77 / 740 ) »
Wenn es darum geht genau eins von 2 unterschiedlichen Controls im selben Container anzuzeigen kann man den Container auch überladen (beide Controls geben den selben Container als "Parent" an ). Normalerweise wird nur das zuerst angelegte Control angezeigt - das andere dümpelt unsichtbar dahinter rum. Ist ein beliebter Fehler auf den sich hier im Forum diverse Threads beziehen weil das normalerweise unabsichtlich passiert .
Aber man kann diesen Effekt dazu verwenden um, wie in deinem Fall, zwischen den beiden Controls zu wechseln, indem man das vorne liegende Control via "set_visible" ein- oder ausblendet.

Folgende Benutzer bedankten sich beim Autor black_adept für den Beitrag (Insgesamt 3):
creative235a-dead-trousersThomas R.

live long and prosper
Stefan Schmöcker

email: stefan@schmoecker.de

Re: Wechselnder Containerinhalt

Beitrag von creative235 (ForumUser / 4 / 2 / 0 ) »
Hallo zusammen,

danke für eure Hilfen. Hat prima funktioniert :-) Ich steuere mit den Steuerungsvariablen jetzt die Größe der drei einzelnen Container und das funktioniert wunderbar!!!

Das macht die ganze Programmierung auch deutlich einfacher, da mir jetzt egal sein kann, welcher Container zuvor angezeigt wurde.

Vielen, vielen Dank!!! :)

Seite 1 von 1