2006 Sep 20 2:00 PM
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.
2006 Sep 21 11:25 AM
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
2007 Jan 15 9:45 PM
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
2007 Jan 15 9:58 PM
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
2007 Jan 16 1:06 PM
> [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
2007 Jan 16 1:18 PM
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
2007 Jan 16 2:04 PM
2007 Jan 16 3:34 PM
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
2007 Jan 16 8:20 PM
Hello,
for me a very good solution.
I made it more simple as it works as well.
BR, Volker
2007 Jan 16 8:28 PM
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
2007 Jan 17 5:51 AM
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
2007 Jan 17 7:32 AM
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
2007 Jan 17 7:42 AM
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
2007 Jan 16 10:57 PM
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