Registration

Dear SAP Community Member,
In order to fully benefit from what the SAP Community has to offer, please register at:
http://scn.sap.com
Thank you,
The SAP Community team.
Skip to end of metadata
Go to start of metadata

GENERATION OF CYCLIC LATIN SQUARE USING DYNAMIC INTERNAL TABLES IN ABAP 

Author: Subhashini K
Submitted: 17/11/2009
Related Links:

Description

This tutorial explains how to generate a Ltain square of any size N*N using dynamic interanl tables and field symbols.

Code  

Error rendering macro 'code': Invalid value specified for parameter 'lang'
REPORT zlatin_square_generation.
*Declaration of global variables required for ALV and logic
INCLUDE zlatin_square_declaration.
*Declaration inside the Include
*Data varaibles used in program for processing
DATA:v_i     TYPE i VALUE '1',
     v_value TYPE i,
     v_c     TYPE c.
*Varibales for filling in data
DATA:v_col   TYPE i VALUE '1',    "Row value = 1
     v_row   TYPE i VALUE '1',    "Column value = 1
     v_count TYPE i.              "Count Variable
*Data reference objects
DATA:t_table     TYPE REF TO data,
     wa_workarea TYPE REF TO data.
*Field symbols for holding the data
FIELD-SYMBOLS:<fs_table>    TYPE STANDARD TABLE,
              <fs_workarea>,
              <fs_field>    TYPE c.
*ALV Data for Display
TYPE-POOLS:slis.
*reference varaible for object for ALV GRID
DATA:oref               TYPE REF TO cl_gui_alv_grid,
*Custom Control container Class reference
     g_custom_container TYPE REF TO cl_gui_custom_container,
*Custom Control in screen painter
     g_container TYPE scrfname VALUE 'LATIN_SQUARE1',
     ok_code TYPE sy-ucomm.
*Field catalog structure
DATA:wa_fc TYPE lvc_s_fcat,
     t_fc  TYPE lvc_t_fcat.
*Layout of ALV Grid
DATA: wa_layout TYPE lvc_s_layo.
*Enter the matrix Size
PARAMETERS: p_n TYPE i OBLIGATORY.

START-OF-SELECTION.
*Based on user input define table structure
  PERFORM set_structure_of_table.
*Get contents of data into field symbols during runtime
  PERFORM assign_field_symbols.

END-OF-SELECTION.
*Fill data into the N*N Matrix
  PERFORM fill_data_in_square.
*Call the screen for Display.Create a custom control in screen painter SE51
*and give it a name.Here I gave it LATIN_SQUARE 1.Place an area in screen
*where we can use it.
  CALL SCREEN 9000.
*&---------------------------------------------------------------------*
*&     Form  SET_STRUCTURE_OF_TABLE
*&---------------------------------------------------------------------*
FORM set_structure_of_table .
*Loop through user given size
*and assign field names and number of fields based on
*user given input size
  WHILE v_i LE p_n.
*convert the number to a character
    v_c = v_i.
    CONCATENATE 'COL' v_c INTO wa_fc-fieldname.
    wa_fc-col_pos = v_i.
*assign fieldnames
    wa_fc-coltext = wa_fc-fieldname.
*build fieldcatalog
    APPEND wa_fc TO t_fc.
    v_i = v_i + 1.
    CLEAR:wa_fc,v_c.
  ENDWHILE.
  CLEAR:v_i,v_c.
*Based on the structure created at runtime create a
*dynamic internal table which is a pointer to the runtime table
  CALL METHOD cl_alv_table_create=>create_dynamic_table
    EXPORTING
      it_fieldcatalog = t_fc
    IMPORTING
      ep_table        = t_table.
ENDFORM.                    " SET_STRUCTURE_OF_TABLE
*&---------------------------------------------------------------------*
*&     Form  ASSIGN_FIELD_SYMBOLS
*&---------------------------------------------------------------------*
FORM assign_field_symbols .
*assign the contents of runtime table to fieldsymbol table
  ASSIGN t_table->* TO <fs_table>.
*for that runtime internal table create a runtime workarea reference
  CREATE DATA wa_workarea LIKE LINE OF <fs_table>.
*assign contents of workarea to field symbol
  ASSIGN wa_workarea->* TO <fs_workarea>.
ENDFORM.                    " ASSIGN_FIELD_SYMBOLS
*&---------------------------------------------------------------------*
*&     Form  FILL_DATA_IN_SQUARE
*&---------------------------------------------------------------------*
FORM fill_data_in_square .
*Assign each value to get a unique no to get the Latin Square row wise
  WHILE v_col LE p_n AND v_row LE p_n.
*for each row assign value for every column
    ASSIGN COMPONENT v_col
            OF STRUCTURE <fs_workarea> TO <fs_field>.
*Initialize first row and column with natural sequence
    IF v_row = 1.
      v_value = v_col.
    ELSEIF v_col = 1.
      v_value = v_row.
      v_count = v_row.
    ELSE.
*for other rows and columns cyclically generate numbers and if
*number is greater than input initialize it back to 1 and start
      v_count = v_count + 1.
      IF v_count LE p_n.
        v_value = v_count.
      ELSE.
        v_count = 1.
        v_value = v_count.
      ENDIF.
    ENDIF.
    v_col = v_col + 1.
    <fs_field> = v_value.
    CLEAR:v_value.
*At end of each row add the line to internal table
    IF v_col GT p_n AND v_row LE p_n.
      APPEND <fs_workarea> TO <fs_table>.
      v_col = 1.
      v_row = v_row + 1.
      CLEAR:<fs_workarea>,<fs_field>.
      CLEAR v_count.
    ENDIF.
  ENDWHILE.
ENDFORM.                    " FILL_DATA_IN_SQUARE
*&---------------------------------------------------------------------*
*&     Module  STATUS_9000  OUTPUT
*&---------------------------------------------------------------------*
MODULE status_9000 OUTPUT.
  SET PF-STATUS 'MAIN100'.
*Set the layout before display
  wa_layout-cwidth_opt = 'X'.
  wa_layout-no_toolbar = 'X'.    "no toolbar
  wa_layout-no_hgridln = 'X'.    "no horizontal grid lines
  wa_layout-no_vgridln = 'X'.    "no vertical grid lines
  IF g_custom_container IS INITIAL.
*create a custom control in screen painter
    CREATE OBJECT g_custom_container
      EXPORTING
        container_name = g_container.
*for that custom control screen area create and object
*of ALV GRID
    CREATE OBJECT oref
      EXPORTING
        i_parent = g_custom_container.
*Call the display method for displaying ALV Data
    CALL METHOD oref->set_table_for_first_display
      EXPORTING
        is_layout       = wa_layout    "Layout
      CHANGING
        it_fieldcatalog = t_fc        "Field Catalog
        it_outtab       = <fs_table>.  "Final Table
    IF sy-subrc <> 0.
      MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
              WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
    ENDIF.
  ENDIF.
ENDMODULE.                " STATUS_9000  OUTPUT
*&---------------------------------------------------------------------*
*&     Module  USER_COMMAND_9000  INPUT
*&---------------------------------------------------------------------*
MODULE user_command_9000 INPUT.
*leave screen after user checks output
  CASE ok_code.
    WHEN 'BACK'.
      LEAVE TO SCREEN 0.
    WHEN 'EXIT'.
      LEAVE TO SCREEN 0.
  ENDCASE.
  CLEAR ok_code.
ENDMODULE.                " USER_COMMAND_9000  INPUT

If we want to get another Latin Square with rows changed add the following code in relevant places of the above program.

Error rendering macro 'code': Invalid value specified for parameter 'lang'
DATA:oref1 TYPE REF TO cl_gui_alv_grid,
      g_custom_container1 TYPE REF TO cl_gui_custom_container,
      g_container1 TYPE scrfname VALUE 'LATIN_SQUARE2'.
FIELD-SYMBOLS:<fs_table1> TYPE STANDARD TABLE,
               <fs_workarea1>.
DATA:t_data1 TYPE REF TO data.
ASSIGN t_table->* TO <fs_table1>.
PERFORM fill_get_another_square.
v_row = p_n.

*Create another reference variable for second latin square
CREATE DATA t_data1 LIKE TABLE OF <fs_workarea>.
ASSIGN t_data1->* TO <fs_table1>.
ASSIGN <fs_workarea> TO <fs_workarea1>.
*interchange row order of first latin square to get another latin square
WHILE v_row LE p_n AND v_row > 0.
  READ TABLE <fs_table> ASSIGNING <fs_workarea> INDEX v_row.
  ASSIGN <fs_workarea> TO <fs_workarea1>.
  APPEND <fs_workarea1> TO <fs_table1>.
  v_row = v_row - 1.
ENDWHILE.
*Repeat same procedure for second latin square
CREATE OBJECT g_custom_container1
  EXPORTING
    container_name = g_container1.
CREATE OBJECT oref1
  EXPORTING
    i_parent = g_custom_container1.
CALL METHOD oref1->set_table_for_first_display
  EXPORTING
    is_layout       = wa_layout
  CHANGING
    it_fieldcatalog = t_fc
    it_outtab       = <fs_table1>.

IF sy-subrc <> 0.
  MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
          WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
ENDIF.