Application Development Blog Posts
Learn and share on deeper, cross technology development topics such as integration and connectivity, automation, cloud extensibility, developing at scale, and security.
cancel
Showing results for 
Search instead for 
Did you mean: 
2,895

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:

Labels in this area