Skip to end of metadata
Go to start of metadata

Author: Steffen Fröhlich
Submitted: August 10th, 2008 (20080810)
Related Links:

Developed on (but should run fine on older platforms too):

-ERP 2005 (a.k.a. ERP 6.0)
-SAP Basis 7.00 SP12
-SAPGUI 7.10 patchlevel 8

Possible improvements:

Which program is perfect? Sure, even this program could be improved, let's see what is possible in my mind. Feel free to improve it and write your changes back into this wiki page! Thanks
-better help for possible values in selection screen
-editable longtext fields for the ALV-Grid
-better selection to the transparent tables...

Motivation: 

The problem while selecting longtext is that the content for the longtexts are saved in binary code. See this in table STXL (Text lines):

So we cannot directly select the right content into a internal table and show it via ALV. We have to select more than we would put out, to search in the first selection and determine the right records out.

Solution:

Selection for STXL table and use the function module READ_TEXT to "open" the lines and see the content in clear text. Long text consists about many lines which are limited to 132 chars. So now we can search in every line for the pattern. If a pattern was found, we save the long text into a dynamic table. This is necessary, coz the maximal length for the selected records is not fix! In that case if you put it out to an ALV Grid, you didn't see which record line is filled just with spacers (null). So the null-values were set to '<<no-values>>' for better identify.

Selection screen:


As you can see (when running the report) the "F4-value help" works fine for Text-ID, Language and Textobject. If you typed the select-options fields directly to the STXL table it wouldn't work. Thats why it is typed for the BAPI_MLTX structure (see it in the coding).

Other values for TEXT-ID are possible:

  • Basic data text: GRUN
  • Inspection text: PRUE
  • Internal comment: IVER

The search pattern is limited to 20 chars, but you can edit this if you need longer patterns.

Output via ALV Grid:


 

Objects you have to add, which doesn't come with the coding below:

-Transaction for the programm (optional)
-Gui status and texts
-create Dynpro '100': insert a CustomControl an name it 'LIST_AREA' for the ALV output
-documentation (optional, but recommended)

*&---------------------------------------------------------------------*
*& Report  ZMAT_LONGTEXTS                                              *
*&---------------------------------------------------------------------*

REPORT  ZMAT_LONGTEXTS                                        .

TABLES: stxh,        "Longtext header table
        stxl,        "Longtext text lines
        bapi_mltx.   "BAPI structure for longtext

TYPE-POOLS: slis.

DATA: container01    TYPE REF TO cl_gui_docking_container,
      alv_list1      TYPE REF TO cl_gui_alv_grid,
      g_repid        TYPE sy-repid,
      g_find(20)     TYPE c,
      g_okcode       TYPE sy-ucomm.

DATA: gt_stxl TYPE TABLE OF stxl,
      wa_stxl TYPE          stxl,

      gt_text     TYPE TABLE OF tline,
      wa_text     TYPE tline,

      g_tdlines_max_loc   TYPE i,
      g_tdlines_max_all   TYPE i,
      g_found_matnr(16)   TYPE n,

      gs_fcat_tdlines TYPE lvc_s_fcat,
      gt_fcat_tdlines TYPE lvc_t_fcat,

      gt_dyn_tdlines TYPE REF TO data,
      wa_dyn_table   TYPE REF TO data,

      wa_f4_return    TYPE ddshretval,
      gt_f4_return    TYPE TABLE OF ddshretval.


FIELD-SYMBOLS: <fs_stxl>     TYPE stxl,
               <fs_dyn_tdlines> TYPE REF TO data,
               <fs_dyn_table>   TYPE TABLE,
               <fs_dyn_newline>,
               <fs_dynnewline_field>.

DATA: word(20) TYPE c.

*+++++++++++++> +++++++++++++> ++++++++++++>
* Selektionsbilder
*+++++++++++++> +++++++++++++> ++++++++++++>
SELECTION-SCREEN: BEGIN OF BLOCK blka WITH FRAME TITLE text-050.
  SELECT-OPTIONS:  so_find FOR word NO INTERVALS NO-EXTENSION.
  SELECT-OPTIONS:  so_tdid FOR bapi_mltx-text_id DEFAULT 'GRUN' NO INTERVALS NO-EXTENSION OBLIGATORY.
  SELECT-OPTIONS:  so_tdsp FOR bapi_mltx-langu   DEFAULT 'DE' NO INTERVALS NO-EXTENSION OBLIGATORY.
  SELECT-OPTIONS:  so_tdob FOR bapi_mltx-applobject DEFAULT 'MATERIAL' NO INTERVALS NO-EXTENSION OBLIGATORY.
  SELECT-OPTIONS:  so_tdna FOR bapi_mltx-text_name.
SELECTION-SCREEN: END OF BLOCK blka.




START-OF-SELECTION.

  SET TITLEBAR 'TITLE_100'.
  SET PF-STATUS 'STATUS_100'.

  CALL SCREEN 0100.

END-OF-SELECTION.

*"----------------------------------------------------------
*" read long text
*"----------------------------------------------------------
FORM read_long_text.

DATA:  l_gttext_string TYPE string
      ,l_name    TYPE string
      ,l_nr(4)   TYPE n
      ,l_pos_nr(4) TYPE n
      ,l_tabix_component(5) TYPE n
      ,l_dynnewline_field TYPE string
      .

*put search string into G_FIND variable
g_find = so_find-low.
CLEAR: g_tdlines_max_all.
*Langtext für alle GT_STXL_EXT lesen und
*nach Suchtext suchen
LOOP AT gt_stxl ASSIGNING <fs_stxl>.


  CALL FUNCTION 'READ_TEXT'
  EXPORTING
    client           = sy-mandt
    id               = <fs_stxl>-tdid
    language         = <fs_stxl>-tdspras
    name             = <fs_stxl>-tdname
    object           = <fs_stxl>-tdobject
  TABLES    lines    = gt_text.

* a long text was found for the selection-entries
  IF sy-subrc = 0.

    CLEAR: l_gttext_string, g_tdlines_max_loc.



    LOOP AT gt_text INTO wa_text.
      CONCATENATE l_gttext_string wa_text-tdline INTO l_gttext_string.
    ENDLOOP.

    FIND g_find IN l_gttext_string IGNORING CASE.

    IF sy-subrc <> 0.
      wa_stxl = <fs_stxl>.
      DELETE TABLE gt_stxl FROM wa_stxl.

    ELSE.

      g_tdlines_max_loc = lines( gt_text ).
      "if current lines for this long text is higher then the lines before
      " --> set the new max lines which should display in the ALV later
      IF g_tdlines_max_loc > g_tdlines_max_all.
        g_tdlines_max_all = g_tdlines_max_loc.
      ENDIF.
    ENDIF.
  ENDIF.

ENDLOOP.

*create fieldcatalog for dynamic table
CLEAR gs_fcat_tdlines.
gs_fcat_tdlines-fieldname = 'MANDT'.
gs_fcat_tdlines-col_pos   = '1'.
gs_fcat_tdlines-inttype   = 'C'.
gs_fcat_tdlines-outputlen = '3'.
APPEND gs_fcat_tdlines to gt_fcat_tdlines.

CLEAR gs_fcat_tdlines.
gs_fcat_tdlines-fieldname = 'RELID'.
gs_fcat_tdlines-col_pos   = '2'.
gs_fcat_tdlines-inttype   = 'C'.
gs_fcat_tdlines-outputlen = '2'.
APPEND gs_fcat_tdlines to gt_fcat_tdlines.

CLEAR gs_fcat_tdlines.
gs_fcat_tdlines-fieldname = 'TDOBJECT'.
gs_fcat_tdlines-col_pos   = '3'.
gs_fcat_tdlines-inttype   = 'C'.
gs_fcat_tdlines-outputlen = '10'.
APPEND gs_fcat_tdlines to gt_fcat_tdlines.

CLEAR gs_fcat_tdlines.
gs_fcat_tdlines-fieldname = 'TDNAME'.
gs_fcat_tdlines-col_pos   = '4'.
gs_fcat_tdlines-inttype   = 'C'.
gs_fcat_tdlines-outputlen = '70'.
APPEND gs_fcat_tdlines to gt_fcat_tdlines.

CLEAR gs_fcat_tdlines.
gs_fcat_tdlines-fieldname = 'TDID'.
gs_fcat_tdlines-col_pos   = '5'.
gs_fcat_tdlines-inttype   = 'C'.
gs_fcat_tdlines-outputlen = '4'.
APPEND gs_fcat_tdlines to gt_fcat_tdlines.

CLEAR gs_fcat_tdlines.
gs_fcat_tdlines-fieldname = 'TDSPRAS'.
gs_fcat_tdlines-col_pos   = '6'.
gs_fcat_tdlines-inttype   = 'C'.
gs_fcat_tdlines-outputlen = '1'.
APPEND gs_fcat_tdlines to gt_fcat_tdlines.


DO g_tdlines_max_all TIMES.
    "create ascending variable for fieldcatalog
    l_name = 'TDLINE'.
    l_nr   = sy-index.
    l_pos_nr = 6 + l_nr.
    SHIFT l_nr LEFT DELETING LEADING '0'.
    CONCATENATE l_name l_nr INTO l_name.

    "expand the max lines for all founded long text into the fieldcatalog
    CLEAR gs_fcat_tdlines.
    gs_fcat_tdlines-fieldname = l_name.
    gs_fcat_tdlines-col_pos   = l_pos_nr.
    gs_fcat_tdlines-inttype   = 'C'.
    gs_fcat_tdlines-outputlen = '127'.
    APPEND gs_fcat_tdlines to gt_fcat_tdlines.
ENDDO.



  "create dynamic table with the fieldcatalog above
  ASSIGN gt_dyn_tdlines TO <fs_dyn_tdlines>.
  CALL METHOD cl_alv_table_create=>create_dynamic_table
    EXPORTING it_fieldcatalog  = gt_fcat_tdlines
    IMPORTING ep_table         = <fs_dyn_tdlines>
    .

IF sy-subrc <> 0.
      MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO
              WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.
ENDIF.

*dereference the fieldsymbol
ASSIGN <fs_dyn_tdlines>->* TO <fs_dyn_table>.
   *Datenstruktur WA_DYN_TABLE erstellen mit Format von FS_DYN_TABLE

*save founded long texts into the dynamic table
LOOP AT gt_stxl ASSIGNING <fs_stxl>.

  CALL FUNCTION 'READ_TEXT'
  EXPORTING
    client           = sy-mandt
    id               = <fs_stxl>-tdid
    language         = <fs_stxl>-tdspras
    name             = <fs_stxl>-tdname
    object           = <fs_stxl>-tdobject
  TABLES    lines    = gt_text.

* wenn zum gefundenen Material ein Langtext existiert:
  IF sy-subrc = 0.
    CLEAR: l_gttext_string, g_tdlines_max_loc.
    UNASSIGN <fs_dyn_newline>.
*    CLEAR wa_dyn_table.
    CREATE DATA wa_dyn_table LIKE LINE OF <fs_dyn_table>.
    ASSIGN wa_dyn_table->* TO <fs_dyn_newline>.

    MOVE-CORRESPONDING <fs_stxl> TO <fs_dyn_newline>.


    LOOP AT gt_text INTO wa_text.

      l_dynnewline_field = 'TDLINE'.
      l_tabix_component = sy-tabix.
      SHIFT l_tabix_component LEFT DELETING LEADING '0'.
      CONCATENATE l_dynnewline_field l_tabix_component INTO l_dynnewline_field.

      ASSIGN COMPONENT l_dynnewline_field OF STRUCTURE <fs_dyn_newline> TO <fs_dynnewline_field>.
      IF wa_text-tdline IS INITIAL.
        <fs_dynnewline_field> = '<<no-values>>'.
      ELSE.
        <fs_dynnewline_field> = wa_text-tdline.
      ENDIF.

    ENDLOOP.
*   Zeile an dynamische Tabelle anhängen
    APPEND <fs_dyn_newline> TO <fs_dyn_table>.

  ENDIF.
ENDLOOP.

ENDFORM.

*----------------------------------------------------------*
*Form    : free_container01
*----------------------------------------------------------*
FORM free_container01.

  IF container01 IS NOT INITIAL.
    " ALV container zerstören
    CALL METHOD container01->free
      EXCEPTIONS cntl_system_error = 1
                 cntl_error        = 2.
  ENDIF.

  FREE: alv_list1, container01.

ENDFORM. " free_container01
*----------------------------------------------------------*


*&---------------------------------------------------------------------*
*&      Module  pbo_0100  OUTPUT
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
module pbo_0100 output.

  DATA:  ls_layout    TYPE lvc_s_layo
        ,l_alv_titel TYPE string
        ,ls_fcat     TYPE lvc_s_fcat
        ,lt_fieldcatalog TYPE lvc_t_fcat
        ,l_name      TYPE string
        ,l_nr(4)     TYPE n
        ,l_pos_nr(4) TYPE n
        .

  "set title and status function for dynpro
  SET TITLEBAR 'TITLE_100'.
  SET PF-STATUS 'STATUS_100'.

  "select all long texts with the entries from selection screen
  SELECT tdid tdspras tdname tdobject
  FROM stxl
  INTO CORRESPONDING FIELDS OF TABLE gt_stxl
  WHERE tdobject IN so_tdob
  AND   tdspras  IN so_tdsp
  AND   tdid     IN so_tdid
  AND   tdname   IN so_tdna
  .

  "search pattern in long texts (GT_STXL)
  PERFORM read_long_text.



  "create ALV container
  g_repid = sy-repid.
  IF container01 IS INITIAL.

    CREATE OBJECT container01
      EXPORTING
        parent     = cl_gui_container=>screen0
        side       = cl_gui_docking_container=>dock_at_left
        ratio      = 90
      EXCEPTIONS
        cntl_error                  = 1
        cntl_system_error           = 2
        create_error                = 3
        lifetime_error              = 4
        lifetime_dynpro_dynpro_link = 5
        OTHERS                      = 6.
    IF sy-subrc <> 0.
        CALL FUNCTION 'POPUP_TO_INFORM'
           EXPORTING
                titel = g_repid
                txt2  = sy-subrc
                txt1  = 'The control could not be created'.
    ENDIF.

*   Set very high extension, which should not be overruled by screen resizing
    CALL METHOD container01->set_extension
      EXPORTING   extension  = 99999
      EXCEPTIONS  CNTL_ERROR = 1
                  others     = 2.
    IF sy-subrc <> 0.
      CALL FUNCTION 'POPUP_TO_INFORM'
           EXPORTING
                titel = g_repid
                txt2  = sy-subrc
                txt1  = 'The extension of container_dock could not be set.'.
    ENDIF.


    CREATE OBJECT alv_list1  EXPORTING i_parent = container01.

  ENDIF.

  "get max. entries for the generated table to show up in the ALV title
  g_found_matnr = lines( <fs_dyn_table> ).
  SHIFT g_found_matnr LEFT DELETING LEADING '0'.
  "set ALV title
  CONCATENATE g_found_matnr 'Langtexte mit "' g_find '" gefunden.' INTO l_alv_titel SEPARATED BY SPACE.

  ls_layout-NO_ROWMARK = ' '.
  ls_layout-SEL_MODE   = 'A'.  "Zeilen lassen sich selektieren
  ls_layout-CWIDTH_OPT = 'X'.  "optimierte Breite der Spalten
  ls_layout-ZEBRA      = 'X'.  "Zebrastreifen in ALV
  ls_layout-GRID_TITLE = l_alv_titel.


  "create fieldcatalog by merge function for STXL table
  CALL FUNCTION 'LVC_FIELDCATALOG_MERGE'
    EXPORTING i_structure_name = 'STXL'
    CHANGING  ct_fieldcat      = lt_fieldcatalog[]
    .
"delete not used fields wich comes from the STXL table
LOOP AT lt_fieldcatalog INTO ls_fcat.
  CASE ls_fcat-fieldname.
    WHEN 'RELID'.  DELETE TABLE lt_fieldcatalog FROM ls_fcat.
    WHEN 'SRTF2'.  DELETE TABLE lt_fieldcatalog FROM ls_fcat.
    WHEN 'CLUSTR'. DELETE TABLE lt_fieldcatalog FROM ls_fcat.
    WHEN 'CLUSTD'. DELETE TABLE lt_fieldcatalog FROM ls_fcat.
  ENDCASE.
ENDLOOP.

DO g_tdlines_max_all TIMES.
  "create ascending variable for fieldcatalog
  l_name = 'TDLINE'.
  l_nr   = sy-index.
  l_pos_nr = 6 + l_nr.
  SHIFT l_nr LEFT DELETING LEADING '0'.
  CONCATENATE l_name l_nr INTO l_name.

  "expand the max lines for all founded long text into the fieldcatalog
  CLEAR ls_fcat.
  ls_fcat-fieldname = l_name.
  ls_fcat-coltext   = l_name.
  ls_fcat-col_pos   = l_pos_nr.
  ls_fcat-inttype   = 'C'.
  ls_fcat-outputlen = '127'.
  ls_fcat-tabname   = 'GT_STXL'.
  APPEND ls_fcat to lt_fieldcatalog.
ENDDO.


    "move the content, layout and fieldcatalog to the ALV-list
    CALL METHOD alv_list1->set_table_for_first_display
        EXPORTING is_layout        = ls_layout
        CHANGING  it_outtab        = <fs_dyn_table>
                  it_fieldcatalog  = lt_fieldcatalog
        .

  "show ALV-list
  CALL METHOD alv_list1->set_toolbar_interactive.
  CALL METHOD cl_gui_control=>set_focus EXPORTING control = alv_list1.

endmodule.                 " pbo_0100  OUTPUT
*&---------------------------------------------------------------------*
*&      Module  pai_0100  INPUT
*&---------------------------------------------------------------------*
module pai_0100 input.

* button actions
  CASE g_okcode.
      WHEN 'BACK'.   PERFORM free_container01. LEAVE TO SCREEN 0.
      WHEN 'EXIT'.   PERFORM free_container01. LEAVE TO SCREEN 0.
      WHEN 'CANCEL'. PERFORM free_container01. LEAVE PROGRAM.
  ENDCASE.

endmodule.                 " pai_0100  INPUT
*----------------------------------------------------------*