CRM and CX Blogs by Members
Find insights on SAP customer relationship management and customer experience products in blog posts from community members. Post your own perspective today!
cancel
Showing results for 
Search instead for 
Did you mean: 
former_member192716
Contributor

Hello everyone! The purpose of this blog is to provide a solution to add columns in a table view at runtime. So far, tableviews the most extensively used html element has to be defined in the view configuration directly or use an iterator to introduce images in individual cells. It was hankering in my mind to come up with a solution to define columns dynamically at runtime and bend the functionality of tableview as we wish and finally i was able to figure a solution.

The idea is to create dynamic structures & workarea using runtime type services. Let me elaborate it with an example.

In the below picture, the table has 9 columns in total, out of which 4 are static columns that is the attribuutes are defined at the time of creating the view and the remaining five columns are created at runtime.

For instance, lets define the dynamic columns in a custom table "ZDYN_COLUMNS". The table stores the columns name, its data type and its technical name.

To start with, create a view with a value node, lets call it "DYNTV" and add the static attributes to it. This is the basic structure of our table view,

Now, the dynamic columns must be added to the table structure and also to the value node "DYNTV". To add columns to our value node we must redefine the method "IF_BSP_MODEL~INIT" of our context node class. Create an internal table of type abap_components_tab and add our static fields to it. Pass the field name and elementary data type using runtime type services.


METHOD if_bsp_model~init.

* Structure with static columns

TYPES: BEGIN OF ltype_attr_struct,
     position        TYPE crmt_number_int,
     productid     
TYPE comt_product_id,
     configurable 
TYPE comt_product_configurable,
     quantity      
TYPE crmt_schedlin_quan,
END OF ltype_attr_struct.


* Data declarations 

DATA: lt_comp             TYPE abap_component_tab,
         
ls_comp             TYPE abap_componentdescr,
          lt_dynamic_cols 
TYPE TABLE OF zdyn_columns,
          ls_dynamic_cols
TYPE zdyn_columns,
          ls_struct            
TYPE ltype_attr_struct.


* Add the static columns to internal table

lr_element ?= cl_abap_elemdescr=>describe_by_data( ls_struct-position ).
ls_comp-name = 'Position'.
ls_comp-type = lr_element.
INSERT ls_comp INTO TABLE lt_comp.

lr_element ?= cl_abap_elemdescr=>describe_by_data( ls_struct-productid ).
ls_comp-name =
'Description'.
ls_comp-type = lr_element.
INSERT ls_comp INTO TABLE lt_comp.

lr_element ?= cl_abap_elemdescr=>describe_by_data( ls_struct-configurable ).
ls_comp-name =
'Configurable'.
ls_comp-type = lr_element.
INSERT ls_comp INTO TABLE lt_comp.

lr_element ?= cl_abap_elemdescr=>describe_by_data( ls_struct-quantity ).
ls_comp-name =
'Quantity'.
ls_comp-type = lr_element.
INSERT ls_comp INTO TABLE lt_comp.

Get the dynamic columns form the custom table and pass them to the abap component descriptor. 

SELECT * FROM zdyn_columns

                INTO TABLE lt_dynamic_cols.


* Loop into the dynamic columns and assign them to abap components tab

LOOP AT lt_dynamic_cols INTO ls_dynamic_cols.
     lr_element        ?= cl_abap_elemdescr=>describe_by_data( ls_dynamic_cols-field_type ).
     ls_comp-name    = ls_dynamic_cols-technical_name.
     ls_comp-type      = lr_element.
     INSERT ls_comp INTO TABLE lt_comp.
ENDLOOP
.

* Declare a global internal table and assign itab lt_comp
* The global table wil be used in method GET_TABLE_LINE_SAMPLE and tableview iterator
gt_comp = lt_comp.

Now, create a structure and craete a value node and add it to the collection wrapper.
* Create the structure type

lr_struct ?= cl_abap_structdescr=>create( p_components = lt_comp p_strict = abap_false ).
* Create data with reference to the type object

CREATE DATA dref TYPEHANDLE lr_struct.
super->if_bsp_model~init(
id = id
                                   owner = owner ).
* Create a value node
CREATE OBJECT lr_value_node
                    EXPORTING iv_data_ref = dref.
* Create a BO collection
CREATE OBJECT lv_bo_coll TYPE cl_crm_bol_bo_col.
* Add the value node to the BO collection
lv_bo_coll->add( lr_value_node ).
* Set the collection wrapper
set_collection( lv_bo_coll ).

The second part is to add the dynamic columns to the table structure by redefining the method GET_TABLE_LINE_SAMPLE and using the global internal table gt_comp.

METHOD get_table_line_sample.

* Data declarations

DATA: lr_struct     TYPE REF TO  cl_abap_structdescr,
           lr_itab        T
YPE REF TO cl_abap_tabledescr,
           lr_line       
TYPE REF TO data,
           dref          
TYPE REF TO data.

FIELD-SYMBOLS : <lt_outtab> TYPE ANY TABLE,
                             <ls_outtab>
TYPE ANY.

IF gt_comp IS NOT INITIAL.
* Create a structure type using the global internal table gt_comp
     lr_struct ?= cl_abap_structdescr=>create( p_components = gt_comp  p_strict = abap_false ).
* Create a new table type
     lr_itab    ?= cl_abap_tabledescr=>create( lr_struct ).
* Create a data with reference to type object
     CREATE DATA dref TYPE HANDLE lr_itab.
     ASSIGN dref->* TO <lt_outtab>.
* Create dynamic work area and assign to FS

     CREATE DATA lr_line LIKE LINE OF <lt_outtab>.
     rv_sample = lr_line.

ENDIF.
ENDMETHOD.

  Create a table view iterator to define the column name and its properties. This is necessary since we do not use the configuration tab to define column properties. Redefine the method "GET_COLUMN_DEFINITIONS" and fill in the column properties,


ls_col_def-columnname           = ls_comp-name.
ls_col_def-title                         = ls_dynamic_cols-field_name. 
  

ls_col_def-wrapping                 = abap_false.
ls_col_def-width                      = '100px'.
ls_col_def-horizontalalignment  =
'LEFT'.  

APPEND

ls_col_def TO p_column_definitions.

Define the layout page and pass the iterator,

<%@page language="abap" %>

<%@extension name="thtmlb" prefix="thtmlb" %>

<%@extension name="chtmlb" prefix="chtmlb" %>

<%@extension name="bsp" prefix="bsp" %>

<%

  Data: lr_iterator TYPE REF TO ZDYN_COLUMN_ITERATOR.

  CREATE OBJECT lr_ITERATOR EXPORTING ir_context_node = dyntv.

%>

<thtmlb:cellerator editMode                  = "ALL"

                          id                             = "TableView"

                          actionsMaxInRow      = "6"

                          onRowSelection        = "select"

                          headerText               = "Dynamic Columns-Example"

                          personalizable          = "TRUE"

                          table                        = "//dyntv/Table"

                          usage                      = "EDITLIST"

                          iterator                     = "<%= lr_ITERATOR %>" />

Output:

 

Regards,
Arun
ArunKumar Balakrishnan.

8 Comments