
Often, in Layouts in SAP we have requirements where we need to display a paragraph in a fixed space provided. It is difficult to format the text in the layout. Instead we can split text at the required length into a table and display the table directly in the Layout.
GV_SPLIT_LINE and TEXT_LINE are some among the standard FM used to split texts. But they come with few restrictions.
Following is a custom FM which can take in a table of any length with varied length texts and returns a table with uniform length. The required length of the table is a inputting parameter.
Definition of FM
ZPSFM_TABLEDATA_FIXEDLENGTH
*" IMPORTING
*" REFERENCE(TABLELENGTH) TYPE INT4 DEFAULT 132
*" TABLES
*" GT_INPUT
*" GT_OUTPUT
*" EXCEPTIONS
*" NO_DATA_FOUND
Importing Parameters:
TABLELENGTH TYPE INT4:- Optional Input to provide the output table length in characters. If no values are provided it takes the default value – 132.
Tables:
GT_INPUT :- Table with Input text which needs to be formatted
GT_OUTPUT :- Resultant table with formatted data
Both tables are not provided any type. Hence, it can import any input data table of any length and create a resultant table with the table length provided in the importing parameters. If ‘Tablelength’ is not provided, then it creates a resultant table with each line of 132 characters.
We have used mainly String data type to accommodate text of any length. This is because a Text Data type will restrict the use to 132 characters. The basic logic used in the FM is used process each line and split each line at desired length.
Please find code snippet below:
FUNCTION zpsfm_tabledata_fixedlength.
*"----------------------------------------------------------------------
*"*"Local Interface:
*" IMPORTING
*" REFERENCE(TABLELENGTH) TYPE INT4 DEFAULT 132
*" TABLES
*" GT_INPUT
*" GT_OUTPUT
*" EXCEPTIONS
*" NO_DATA_FOUND
*"----------------------------------------------------------------------
DATA: ls_proj_in TYPE string,
ls_proj_out TYPE string,
lv_text TYPE string,
lv_left TYPE string,
lv_right TYPE string,
lv_tabix TYPE sy-tabix,
lv_length TYPE int4,
lv_countcurr TYPE i,
lv_counttext TYPE i,
lv_totlen TYPE i,
lv_lines TYPE i,
lv_start TYPE i,
lv_counttrail TYPE i,
lv_countrem TYPE i,
lv_flag.
CONSTANTS : gc_x TYPE c VALUE 'X'.
*************************************************************************
lv_length = tablelength.
* Raising exception if the input table is empty.
DESCRIBE TABLE gt_input LINES lv_lines.
IF lv_lines < 1.
RAISE no_data_found.
ENDIF.
LOOP AT gt_input INTO ls_proj_in.
lv_length = tablelength.
lv_tabix = sy-tabix.
lv_text = ls_proj_in.
IF lv_tabix = 1. "For first entry
lv_counttext = strlen( lv_text ). "Length of previous entry
lv_countcurr = strlen( lv_text ). "Length of current entry
lv_countrem = lv_length.
ELSE. "For remaining entries.
lv_countcurr = strlen( lv_text ).
IF lv_length >= lv_counttext.
lv_countrem = lv_length - lv_counttext. "Calculating space available for each line.
ELSE.
lv_countrem = lv_length.
ENDIF.
ENDIF.
* When the length is lesser than the maximum length
IF lv_counttext < ( lv_length - 1 ).
* When current line length is lesser than the remaining space avaialable, concatenating previous entry * with the current entry.
IF lv_countcurr < lv_countrem.
IF NOT ls_proj_out IS INITIAL.
CONCATENATE ls_proj_out space lv_text INTO ls_proj_out RESPECTING BLANKS.
ELSE.
MOVE lv_text TO ls_proj_out.
ENDIF.
* When the current line length is more than the remaining space available, current text is split.
* the left hand side of the splitted text is joined with the previous entry,
* right hand side is updated and left for next processing.
ELSE.
CLEAR lv_start.
lv_totlen = strlen( lv_text ).
lv_left = lv_text+lv_start(lv_countrem).
lv_start = lv_start + lv_countrem.
lv_counttrail = lv_totlen - lv_countrem.
lv_right = lv_text+lv_start(lv_counttrail).
IF lv_countrem < lv_totlen.
lv_counttrail = lv_countrem + 1.
IF ( lv_text(lv_counttrail) ) = space.
CONCATENATE space lv_right INTO lv_right RESPECTING BLANKS.
ENDIF.
ENDIF.
IF NOT ls_proj_out IS INITIAL.
CONCATENATE ls_proj_out lv_left INTO ls_proj_out RESPECTING BLANKS.
ELSE.
MOVE lv_left TO ls_proj_out.
ENDIF.
APPEND ls_proj_out TO gt_output.
CLEAR ls_proj_out.
ls_proj_out = lv_right. "For next line processing
lv_text = lv_right. "For next line processing
lv_counttext = strlen( ls_proj_out ). "For next line processing
ENDIF.
* When length is the same
ELSEIF lv_counttext = lv_length.
ls_proj_out = lv_text.
APPEND ls_proj_out TO gt_output.
CLEAR ls_proj_out.
ENDIF.
* When length of currently processed line is more than the space available
* Splitting the text repeatedly into the left and right hand side till the
* right hand side half is lesser than lv_length. The left hand side with
* lv_length is appended to each line and continuing the process with the
* right hand side
WHILE lv_counttext > lv_length.
* Splitting
CLEAR lv_start.
lv_totlen = strlen( lv_text ).
lv_left = lv_text+lv_start(lv_length).
lv_start = lv_start + lv_length.
lv_counttrail = lv_totlen - lv_length.
lv_right = lv_text+lv_start(lv_counttrail).
IF lv_counttrail < lv_totlen.
lv_counttrail = lv_length + 1.
IF ( lv_text(lv_counttrail) ) = space.
CONCATENATE space lv_right INTO lv_right RESPECTING BLANKS.
ENDIF.
ENDIF.
MOVE lv_left TO ls_proj_out.
APPEND ls_proj_out TO gt_output.
CLEAR ls_proj_out.
lv_counttext = strlen ( lv_right ). "For next line processing
lv_text = lv_right. "For next line processing
lv_flag = gc_x. "For processing last right half
ENDWHILE.
IF NOT lv_text IS INITIAL
AND lv_flag = gc_x.
ls_proj_out = lv_text.
ELSE.
lv_counttext = strlen( ls_proj_out ).
ENDIF.
* Processing the last line - Appending the last line to the output table
IF lv_tabix = lv_lines
AND NOT ls_proj_out IS INITIAL.
APPEND ls_proj_out TO gt_output.
CLEAR ls_proj_out.
ENDIF.
CLEAR: lv_text, lv_left, lv_right, lv_countcurr, lv_countrem, lv_flag,
lv_totlen, lv_start, lv_counttrail .
ENDLOOP.
ENDFUNCTION.
Tests:
Example 1:
Input has 4 lines and we need to make a table with each line as 132 characters.
Input Table entry
Output – A single line with maximum 132 characters.
Example 2:
Input table has 2 entries with varied length and we need a table with 40 characters in each line.
Input:
Output:
User | Count |
---|---|
3 | |
2 | |
2 | |
2 | |
1 | |
1 | |
1 | |
1 | |
1 |