Application Development Discussions
Join the discussions or start your own on all things application development, including tools and APIs, programming models, and keeping your skills sharp.
cancel
Showing results for 
Search instead for 
Did you mean: 

Dynamic fields to be displayed in ALV

Former Member
0 Kudos

Hi All,

I've a requirement like this.

I have table type with 10 fields and I use this to display data in ALV. Now, I need to add few dynamic columns (based on customizing) and show in the same ALV. Since these fields are dynamic and new fields can also be added in the future, I can not enhance the structure I am using at present. So, the solution would be to add dynamic columns to the output table that is sent to ALV display.

Adding fields to field catalogue is not a big ask and I am already done with that. Moreover, I have tried enhancing the current structure with a field of type DATA and populated it.

But, technically, it is a single field and cannot be split into the different new fields at the time of output.

How is this possible? Please provide me with example code also, if you have.

Thanks in advance,

Srinath.

13 REPLIES 13

Former Member
0 Kudos

Hi srinath

You can add dynamic Number of columns in the ALV.

You have to create an internal table where you get populted all the columns u want to display 8,10 or any.

You have to run loop - endloop for the fieldcatalog

Thats it.

Please check the attached code .........

Have a nice day.

Regards,

Kalpesh

ORM fieldcat_init1 .

wa_ls_layout-colwidth_optimize = c_x. "optimise column width

wa_ls_layout-zebra = c_x. "striped pattern

wa_ls_layout-info_fieldname = 'ROWCOLOR'.

REFRESH it_gt_fieldcat.

CLEAR it_fieldcat.

it_fieldcat-fieldname = 'ROW_HEAD'.

it_fieldcat-seltext_m = 'Recruitment Tracker'. "Personnel Subarea.

APPEND it_fieldcat TO it_fieldcatalog.

LOOP AT it_weeks.

CASE it_weeks-srn.

WHEN 1.

CLEAR it_fieldcat.

it_fieldcat-fieldname = 'WEEK1'.

WHEN 2.

CLEAR it_fieldcat.

it_fieldcat-fieldname = 'WEEK2'.

WHEN 3.

CLEAR it_fieldcat.

it_fieldcat-fieldname = 'WEEK3'.

WHEN 4.

CLEAR it_fieldcat.

it_fieldcat-fieldname = 'WEEK4'.

WHEN 5.

CLEAR it_fieldcat.

it_fieldcat-fieldname = 'WEEK5'.

WHEN 6.

CLEAR it_fieldcat.

it_fieldcat-fieldname = 'WEEK6'.

WHEN 7.

CLEAR it_fieldcat.

it_fieldcat-fieldname = 'WEEK7'.

WHEN 8.

CLEAR it_fieldcat.

it_fieldcat-fieldname = 'WEEK8'.

WHEN 9.

CLEAR it_fieldcat.

it_fieldcat-fieldname = 'WEEK9'.

WHEN 10.

CLEAR it_fieldcat.

it_fieldcat-fieldname = 'WEEK10'.

WHEN 11.

CLEAR it_fieldcat.

it_fieldcat-fieldname = 'WEEK11'.

WHEN 12.

CLEAR it_fieldcat.

it_fieldcat-fieldname = 'WEEK12'.

WHEN 13.

CLEAR it_fieldcat.

it_fieldcat-fieldname = 'WEEK13'.

WHEN 14.

CLEAR it_fieldcat.

it_fieldcat-fieldname = 'WEEK14'.

ENDCASE.

it_fieldcat-seltext_m = it_weeks-outputdate. "Heading of the ALV Grid

APPEND it_fieldcat TO it_fieldcatalog.

ENDLOOP.

CLEAR it_fieldcat.

it_fieldcat-fieldname = 'TOTAL'.

it_fieldcat-seltext_m = 'Total'. "Personnel Subarea.

APPEND it_fieldcat TO it_fieldcatalog.

ENDFORM. " fieldcat_init

0 Kudos

Hello,

I am also searching for a special solution.

All answers about the fieldcatalogue go to the direction that it is created manual.

When for example the REUSE_GRID_ALV_DISPLAY is used, the fieldcatalogue can be build with the FM REUSE_ALV_FIELDCATALOG_MERGE and the export parameter "i_internal_tabname". When you pass a table that is declared with begin and occurs instead of "type table of " this works perfect. At least one step more dynamic. But this has two disadvantges:

1. The FM should not be used (says SAP) and

2. In new style "occurs" is bad.

SO MY QUESTION:

How I can create / generate the fieldcat based on the global tableor just a "type"?

I am sure there must be a solution about this ...

Thanks for any answers on that as well.

Best regards,

Volker

0 Kudos

Hi Volker and Srinath,

In order to develop a dynamic ALV, you need to build a dynamic catalog. After that, you can create the dynamic table that you want to display.

Here's a short example.


"Building the dynamic catalog.
  LOOP AT it_zcapacidad1 INTO wa_zcapacidad1.
    CLEAR ls_fcat.

*   Material
    ADD 1 TO w_tabix.
    ls_fcat-col_pos     = w_tabix.
    ls_fcat-fieldname   = wa_zcapacidad1-pmnux.
    ls_fcat-scrtext_l   = wa_zcapacidad1-pmnux.
    ls_fcat-scrtext_m   = wa_zcapacidad1-pmnux.
    ls_fcat-scrtext_s   = wa_zcapacidad1-pmnux.
    ls_fcat-inttype     = 'C'.
    ls_fcat-intlen      = '18'.
    ls_fcat-outputlen = 18.
    APPEND ls_fcat TO it_dyncat.

*   Contador Puesto de Trabajo
    ADD 1 TO w_tabix.
    ls_fcat-col_pos     = w_tabix.
    CONCATENATE 'cont_' wa_zcapacidad1-pmnux INTO ls_fcat-fieldname.
    CONCATENATE 'cont_' wa_zcapacidad1-pmnux INTO ls_fcat-scrtext_l.
    CONCATENATE 'cont_' wa_zcapacidad1-pmnux INTO ls_fcat-scrtext_m.
    CONCATENATE 'cont_' wa_zcapacidad1-pmnux INTO ls_fcat-scrtext_s.
    ls_fcat-inttype     = 'C'.
    ls_fcat-intlen      = '18'.
    ls_fcat-outputlen = 18.
    APPEND ls_fcat TO it_dyncat.
  ENDLOOP.

"Creating the dynamic table
DATA: new_table_dyn           TYPE REF TO data,
      new_line_dyn            TYPE REF TO data.
FIELD-SYMBOLS: <it_itab>           TYPE STANDARD TABLE,
               <wa_line>           TYPE ANY.

CALL METHOD cl_alv_table_create=>create_dynamic_table
    EXPORTING
      it_fieldcatalog = it_dyncat
    IMPORTING
      ep_table        = new_table_dyn.

ASSIGN new_table_dyn->* TO <it_itab>.
  CREATE DATA new_line_dyn LIKE LINE OF <it_itab>.
  ASSIGN new_line_dyn->* TO <wa_line>.

"Now you have to fill the table with the data you wanna display and call the function that shows the ALV.

Regards,

Eric

Pd. Reward points if it was useful

Message was edited by:

Eric Hernandez Pardo

0 Kudos

> [code]

> Building the dynamic catalog.

> LOOP AT it_zcapacidad1 INTO wa_zcapacidad1.

> CLEAR ls_fcat.

> * Material

> ADD 1 TO w_tabix.

> ls_fcat-col_pos = w_tabix.

> ls_fcat-fieldname = wa_zcapacidad1-pmnux.

> ls_fcat-scrtext_l = wa_zcapacidad1-pmnux.

> ls_fcat-scrtext_m = wa_zcapacidad1-pmnux.

> ls_fcat-scrtext_s = wa_zcapacidad1-pmnux.

> ls_fcat-inttype = 'C'.

> ls_fcat-intlen = '18'.

> ls_fcat-outputlen = 18.

> APPEND ls_fcat TO it_dyncat.

>

Hello,

problem here is, that is not dynmiac based on the structured defintion.

I am working with

cl_abap_typedescr=>describe_by_data ( itab )

and I get the field names.

What I do not get here are the types and lengths of the fields. When that is avilable you can read from the DDIC the texts etc. Then we are dynamic !!

BR, Volker

Former Member
0 Kudos

hi,

why dont u use FM

REUSE_ALV_FIELDCATLOG_MERGE

u can give the internal table name and then expect the FCAT to change when ever u chage a global table, plz note that when u are using this FM use only internal table which is created using LIKE..ie use an object not a type..

santhosh

Former Member

Clemenss
Active Contributor
0 Kudos

Hi Srinath,

I for this purpose I use my own solution since a couple of years with success. It was originally developed for ALV functions module. In OO the field catalo has a slightly different structure, nut one can be easily converted into the other using function module (don't remember the name right now).

Recently I created a class with static functional methods for this:


METHOD fieldcat_alv .
  TYPE-POOLS:
    sydes.
  DATA:
    lv_desc                               TYPE sydes_desc,
    ls_alv_fieldcat                       TYPE slis_fieldcat_alv,
    lv_longfield                          TYPE dynfnam.
  FIELD-SYMBOLS:
    <typeinfo>                            TYPE sydes_typeinfo,
    <nameinfo>                            TYPE sydes_nameinfo.
  DESCRIBE FIELD it_table INTO lv_desc.                     "#EC *

  LOOP AT lv_desc-types
      ASSIGNING <typeinfo>
      WHERE NOT idx_name IS INITIAL
        AND table_kind IS INITIAL "no entries for deep table like color
        AND back                          = 2. "top-level-entries only.
    READ TABLE lv_desc-names INDEX <typeinfo>-idx_name
      ASSIGNING <nameinfo>.
    CHECK <nameinfo>-name                 <> 'INCLUDE'.
    ls_alv_fieldcat-fieldname             = <nameinfo>-name.
    WHILE NOT <nameinfo>-continue IS INITIAL.
      ADD 1 TO <typeinfo>-idx_name.
      READ TABLE lv_desc-names INDEX <typeinfo>-idx_name
        ASSIGNING <nameinfo>.
      CONCATENATE
        ls_alv_fieldcat-fieldname
        <nameinfo>-name
        INTO ls_alv_fieldcat-fieldname.
    ENDWHILE." not <nameinfo>-continue IS INITIAL.
    READ TABLE lv_desc-names INDEX <typeinfo>-idx_help_id
      ASSIGNING <nameinfo>.
    IF sy-subrc                           = 0.

* Caution: Help-ID may be Tablename-Fieldname and thus longer
* than 30 Chars; ls_alv_fieldcat-rollname is 30 Chars only
      ls_alv_fieldcat-rollname            = <nameinfo>-name.
      lv_longfield                        = <nameinfo>-name.
      WHILE NOT <nameinfo>-continue IS INITIAL.
        ADD 1 TO <typeinfo>-idx_help_id.
        READ TABLE lv_desc-names INDEX <typeinfo>-idx_help_id
          ASSIGNING <nameinfo>.
        CONCATENATE
          lv_longfield
          <nameinfo>-name
          INTO lv_longfield.
      ENDWHILE." not lv_desc-continue is initial.

* help id may be data element or <table>-<field>
      IF lv_longfield CA '-'.

* get datatype for table field
        CALL METHOD get_rollname_4_tabfield
          EXPORTING
            iv_fieldname    = lv_longfield
          CHANGING
            cs_alv_fieldcat = ls_alv_fieldcat.
      ENDIF." lv_longfield ca '-'.
    ELSE.

* No Help-ID: Use Fieldname as text
      ls_alv_fieldcat-seltext_s           =
      ls_alv_fieldcat-seltext_m           =
      ls_alv_fieldcat-seltext_l           =
      ls_alv_fieldcat-reptext_ddic        =
      <nameinfo>-name.
    ENDIF." sy-subrc                      = 0.

* Starting 4.7: get edit mask
    IF NOT <typeinfo>-idx_edit_mask IS INITIAL.
      READ TABLE lv_desc-names INDEX <typeinfo>-idx_edit_mask
        ASSIGNING <nameinfo>.
      ls_alv_fieldcat-edit_mask           = <nameinfo>-name.
      IF NOT <nameinfo>-continue IS INITIAL.
        ADD 1 TO <typeinfo>-idx_edit_mask.
        READ TABLE lv_desc-names INDEX <typeinfo>-idx_edit_mask
          ASSIGNING <nameinfo>.
        CONCATENATE
          ls_alv_fieldcat-edit_mask
          <nameinfo>-name
          INTO ls_alv_fieldcat-edit_mask.
      ENDIF." not <nameinfo>-continue IS INITIAL.
    ENDIF." not <typeinfo>-IDX_EDIT_MASK is initial.

* assign length, output length and decimals
    ls_alv_fieldcat-intlen                = <typeinfo>-length.
    ls_alv_fieldcat-outputlen             = <typeinfo>-output_length.
    ls_alv_fieldcat-decimals_out          = <typeinfo>-decimals.
    ls_alv_fieldcat-inttype               = <typeinfo>-type.
    APPEND ls_alv_fieldcat TO rt_fieldcat.
    CLEAR:  "prevent anything 2 B  taken for subsequent fields
      ls_alv_fieldcat.
  ENDLOOP." at lv_desc-types where not IDX_NAME is in initial.

ENDMETHOD.

Parameters required

importing

IT_TABLE type STANDARD TABLE

returning

value(RT_FIELDCAT) type SLIS_T_FIELDCAT_ALV .

and


method GET_ROLLNAME_4_TABFIELD .
  FIELD-SYMBOLS:
    <dfies>                               TYPE dfies.
  DATA:
    lv_tabname                            TYPE tabname,
     lt_dfies                             TYPE TABLE OF dfies,
    lv_fieldname                          TYPE fieldname.
  SPLIT iv_fieldname AT '-'
    INTO lv_tabname lv_fieldname.
  CLEAR cs_alv_fieldcat-rollname.
  CALL FUNCTION 'DDIF_FIELDINFO_GET'
    EXPORTING
      tabname                             = lv_tabname
      fieldname                           = lv_fieldname
*   LANGU                                 = SY-LANGU
*   LFIELDNAME                            = ' '
*   ALL_TYPES                             = ' '
* IMPORTING
*   X030L_WA                              =
*   DDOBJTYPE                             =
*   DFIES_WA                              =
*   LINES_DESCR                           =
   TABLES
     dfies_tab                            =  lt_dfies
*   FIXED_VALUES                          =
   EXCEPTIONS
     not_found                            = 1
     internal_error                       = 2
     OTHERS                               = 3
            .
  IF sy-subrc                             <> 0.
    MESSAGE ID sy-msgid                   TYPE sy-msgty NUMBER sy-msgno
            WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
  ELSE.
    READ TABLE   lt_dfies ASSIGNING <dfies> INDEX 1.
    cs_alv_fieldcat-rollname               = <dfies>-rollname.
* Und wenn keinerlei Twexte gepflegt sind?
    IF <dfies>-reptext IS INITIAL AND
       <dfies>-scrtext_s IS INITIAL AND
       <dfies>-scrtext_m IS INITIAL AND
       <dfies>-scrtext_l IS INITIAL.
* No Text: Use Fieldname as text
      cs_alv_fieldcat-seltext_s            =
      cs_alv_fieldcat-seltext_m            =
      cs_alv_fieldcat-seltext_l            =
      cs_alv_fieldcat-reptext_ddic         =
        cs_alv_fieldcat-fieldname.
    ENDIF." <dfies>-reptext IS INITIAL AND
  ENDIF.
endmethod.

parameters required

importing

IV_FIELDNAME type DYNFNAM

changing

value(CS_ALV_FIELDCAT) type SLIS_FIELDCAT_ALV .

Put this into class Z_CL_UTIL using SE80 and generate field catalog dynamically using statement

lt_fieldcat = Z_CL_UTIL=>fieldcat_alv( itab ).

If you have any difficulties with implementation, let me know.

Regards,

Clemens Li

Former Member
0 Kudos

Hello,

for me a very good solution.

I made it more simple as it works as well.

BR, Volker

Clemenss
Active Contributor
0 Kudos

Volker,

it was 3 or 4 years ago I made the first try in that direction - never gave it a complete overhaul. Tell me how I could simplify it!

TIA,

regards,

Clemens

Former Member
0 Kudos

Hello,

I just did not create the class and method for "GET_ROLLNAME_4_TABFIELD" even that makes it more simple for further usage. I will more think a template solution.

And I quiet much left the *-continue parts off so all got more simple.

Best regards,

Volker

Clemenss
Active Contributor
0 Kudos

Volker,

originally the functionality was coded using FORM routines. That was a CRM project where almost everything was class & method where I put both methods in the same class, GET_ROLLNAME_4_TABFIELD may be defined private.

The *-continue parts where introduced later - you need them if the length of field and type names exceed a certain length.

BUT:

I want to check out the solutions provided by Klaus Ziegeler and Uwe Schieferstein - the more contemporary approach. This can wait: SAP made some (of course undocumented) changes to cl_abap_*descr between 4.6 and 4.7/ECC600. As long as I have to work with all releases I need a stable solution.

Regards,

Clemens

Former Member
0 Kudos

Clemmens,

I agree. The solution looks also interesting. I was not far away from that solution but my development needed to get forward and I was not able to access the help_id for the DDIC selection of the text from the class. I did not manage to get the pointer on it. Maybe the solution of Klaus allows it.

I will also think in the next "project" how to improve it and check once more Klaus solution to get it even more dynamic !

BR, Volker

uwe_schieferstein
Active Contributor
0 Kudos

Hello Srinath

The following report shows how to dynamically adjust an ALV list. The report is based on the example given by <b>Klaus Ziegler</b> in

Please note that in your case you have to fill the components itab based on your customizing.

*&---------------------------------------------------------------------*
*& Report  ZUS_SDN_RTTI_CREATE_STRUCTURES
*&
*&---------------------------------------------------------------------*
*&
*&
*&---------------------------------------------------------------------*

REPORT  zus_sdn_rtti_create_structures.


TYPE-POOLS: abap.

DATA:
  go_table         TYPE REF TO cl_salv_table,
  go_sdescr        TYPE REF TO cl_abap_structdescr,
  go_tdescr        TYPE REF TO cl_abap_tabledescr,
  gdo_data         TYPE REF TO data,
  gdo_handle       TYPE REF TO data,
  gs_comp          TYPE abap_componentdescr,
  gt_components    TYPE abap_component_tab.
*
*    name       TYPE string,
*    type       TYPE REF TO cl_abap_datadescr,
*    as_include TYPE abap_bool,
*    suffix     TYPE string,

FIELD-SYMBOLS:
  <gd_fld>      TYPE ANY,
  <gs_struc>    TYPE ANY,
  <gt_itab>     TYPE table.


PARAMETER:
  p_tabnam      TYPE tabname  DEFAULT 'KNB1'.

START-OF-SELECTION.

* Create dynamically structure
  CREATE DATA gdo_data TYPE (p_tabnam).
  ASSIGN gdo_data->* TO <gs_struc>.
  CHECK ( <gs_struc> IS ASSIGNED ).


* Simulate dynamic addition of columns to ALV list
  DO 10 TIMES.
    ASSIGN COMPONENT syst-index OF STRUCTURE <gs_struc> TO <gd_fld>.

    CLEAR: gs_comp.
    gs_comp-type ?= cl_abap_datadescr=>describe_by_data( <gd_fld> ).
    gs_comp-name  = gs_comp-type->get_relative_name( ).
    APPEND gs_comp TO gt_components.

    go_sdescr  = cl_abap_structdescr=>create( gt_components ).
    go_tdescr  = cl_abap_tabledescr=>create( go_sdescr ).
    CREATE DATA gdo_handle TYPE HANDLE go_tdescr.
    ASSIGN gdo_handle->* TO <gt_itab>.

*   Dynamic select
    SELECT        * FROM  (p_tabnam)
      INTO CORRESPONDING FIELDS OF TABLE <gt_itab>
           WHERE  bukrs  = '2000'.

    TRY.
        CALL METHOD cl_salv_table=>factory
          IMPORTING
            r_salv_table = go_table
          CHANGING
            t_table      = <gt_itab>.
        go_table->display( ).
      CATCH cx_salv_msg .
    ENDTRY.

  ENDDO.


END-OF-SELECTION.

Regards

Uwe