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 declarationsDATA: 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 tablelr_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_columnsINTO TABLE lt_dynamic_cols.
* Loop into the dynamic columns and assign them to abap components tabLOOP 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.
* Create the structure typelr_struct ?= cl_abap_structdescr=>create( p_components = lt_comp p_strict = abap_false ).
* Create data with reference to the type objectCREATE 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 ).
METHOD get_table_line_sample.
* Data declarations
DATA: lr_struct TYPE REF TO cl_abap_structdescr,
lr_itab TYPE 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 FSCREATE 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:
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.