Quantcast
Channel: SCN : Document List - ABAP Development
Viewing all 935 articles
Browse latest View live

Some code tips in using READ statement

$
0
0

Hi All

I have prepared this document to be able to help ABAPers to find some easy fixed while they are using READ statement during coding ..

I myself faced some issues and saw a lot of open posts for the same hence thought a ready document might come handy .

Read statement and some Limitations 

 

***************************************************************************************

Limitation 1 : Read table does not make use of SY-SUBRC NE 0 condition .

Here we are trying to read a table LT_PO_ITEM which does not have matching entries in IT_ITEM ..

 

Example

Case 1 : READ TABLE LT_PO_ITEMS INTO LS_FINAL WITH KEY GUID NE IT_ITEM-GUID . " This is wrong

Case 2 : READ TABLE LT_PO_ITEMS INTO LS_FINAL WITH KEY GUID EQ IT_ITEM-GUID . "This is right

 

Explanation :Lets look as to why case 1 is wrong .IN using Read statement SAP does not allow NE to be used . I don't know what's the purpose of doing that is .. probably because there will be a lot of entries which are NE and hence you cannot pass it into the structure.. LS_FINAL ..

 

Workaround/ Solution  for Case 1

LOOP AT LT_PO_ITEMS INTO LT_FINAL .                                        " I am still comparing LT_PO_ITEM but by each case now

READ TABLE IT_ITEM INTO WA_ITEM WITH KEY GUID = LT_FINAL " Checking LT_PO_ITEM with IT_ITEM

IF SY-SUBRC EQ 0 . " If it matches the entry

DELETE LT_PO_ITEMS Index Lv_index .                                            " DELETE

  1. ENDIF.
  2. ELSE.

MOVE CORRESPONDING LT_PO_ITEMS INTO LT_FINAL2               . "If  does not matches add to table LT_FINAL2

 

Now in LT_FINAL2 you can have all the data which is NOT matching (EXCLUSIVE of entry in ) the initial Table  in LT_PO_ITEMS. Hence we achieved it ..

 

***************************************************************************************

Limitation 2 READ ENTRIES OF ONE Internal TABLE INTO ANOTHER internal table NOT POSSIBLE ..

Example

READ TABLE LT_CRMJEST INTO LT_CRMJEST1  WITH KEY OBJNR = ls_requirments-parent

" If LT_FINAL Is a Table this is not a correct statement . Why ? It will give you the below error.

 

 

 

Explanation : From an internal table you cannot select into an internal table ONLY INTO a structure is allowed .. So how do we select multiple entries from an internal table based on some condition which is not a primary key so obviously it will have multiple entries .

 

SOLUTION

LOOP AT lt_crmjest1 INTO LS_crmjest1 WHERE objnr = ls_requirements-item.

   IF sy-subrc = 0 .

   APPEND ls_crmjest1 TO LT_crmjest2.

   ENDIF.

  1. ENDLOOP.

 

Now from 1 internal table lt_crmjest1 your entries have moved to the 2nd internal table lt_crmjest2.

Now put your logic on conditions.

 

 

READ TABLE  Lt_CRMJEST2 INTO LS_crmjest2  with key STAT = 'I1113' INACT = ABAP_FALSE . 


" We put condition on LT_CRMJEST2 now since it will have the desired entries ..Note here we can use read statement as its from an internal table to a structure .

 

 

Hope this helps a bit

 

Regards

Vinita


Handling BOL/Genil in HCM portal applications

$
0
0

The business object layer (BOL) model is a programming concept that allows for uniform application development, decoupled from interface changes in the underlying business-object-specific application programming interfaces The BOL layer provides a consistent interface to access the business objects APIs or the underlying data fetching APIs using the GENIL framework. The BOL object uses the object oriented approach to access the model and also acts as the buffer for the UI. GENIL is the generic interaction layer which provides you access to the business logic which is present in the Business object. As compared to BOL, GENIL can also be used for scenarios other than the Web UI.

Even though BOL layer is built by SAP specifically for SAP CRM Web UI, it is widely used in HCM portal applications. Instead of going deep into the conceptual level, in this document I have tried to provide a quick code reference for developers who are dealing with the HCM portal developments. Most of the time you will be able to find BOL related examples based on the CRM only. Here we are using an HCM scenario of reading/updating the dependent data for Health plans in Benefits.

The Benefits Participation Overview application uses the Model for ESS Benefits (HRBENF) BOL model.

GENIL_MODEL_BROWSER - This transaction is used to check the BOL Objects and their underlying structures. The BOL objects are related together in order to make it easier to access the related data.

They can be categorized as one of the various kinds on Objects.


Root Objects

Access Objects

Dependent Objects

Abstract Objects

Query Objects

Query Result Objects

View Objects

Dynamic Query Objects


BOL_Browser.jpg


In our example we are using the relation HEALTH_DEP_REL, as you can see it lies in the third level. In our coding we need to drill down to that level to read/update the data existing there.


As per my requirement, I have used the below code as an enhancement in CL_HRESS_BEN_DEPENDENTS->PROCESS_EVENT. This will be triggered on clicking OK button in the plan option popup. You can add your code anywhere based on your requirement.



*----- Data declarations

DATA lo_bol_core             TYPE REF TO cl_crm_bol_core,
       lo_hress               
TYPE REF TO cx_hress,
       ls_object_spec         
TYPE crmt_genil_obj_instance,
       lo_iterator            
TYPE REF TO if_bol_entity_col_iterator,
       lo_entity              
TYPE REF TO cl_crm_bol_entity,
       lo2_iterator           
TYPE REF TO if_bol_entity_col_iterator,
       lo_entity              
TYPE REF TO cl_crm_bol_entity,
       lv_object_id           
TYPE crmt_genil_object_id,
       lt_object_specs        
TYPE crmt_genil_obj_instance_tab,

              lo_collection_in        TYPE REF TO if_bol_entity_col,
       lo_collection_out      
TYPE REF TO if_bol_entity_col,
       lo2_collection_out     
TYPE REF TO if_bol_entity_col,
       lo_access              
TYPE REF TO if_bol_bo_property_access,

              lo_bol_filter           TYPE REF TO cl_crm_bol_filter,
       lv_tech_exception_text 
TYPE string,
       ls_pernr_struc         
TYPE hrpernr,
       lv_rel_name            
TYPE crmt_relation_name,
       lv_string              
TYPE string.

*----- Data declaration for objects which stores the change that has to be updated in BOL.

  DATA : lt_dep_sel   TYPE ztthbn_deplife_dep_sel,
       lx_dep_sel  
TYPE zshbn_deplife_dep_sel,
       lx_dep_sel_n
TYPE zshbn_deplife_dep_sel.

 
IF io_event->mv_event_id EQ cl_fpm_event=>gc_event_close_dialog_box AND mo_collection IS BOUND.


io_event
->mo_event_data->get_value( EXPORTING iv_key = if_fpm_constants=>gc_dialog_box-dialog_buton_key

                                   IMPORTING ev_value = lv_button ).


IF lv_button = if_fpm_constants=>gc_dialog_action_id-ok.

lo_bol_core
= cl_crm_bol_core=>get_instance( ).


lo_bol_core
->start_up( iv_appl_name = 'EMPTY'
                        iv_display_mode_support
= space ).


lo_bol_core
->load_component( 'HRBENF' ).

*----- Get object
TRY.
ls_pernr_struc
-pernr = cl_hress_employee_services=>get_instance( )->get_pernr( ).
CATCH cx_hress INTO lo_hress.
lv_tech_exception_text
= cl_hress_fpm_msg_services=>return_tech_exception( lo_hress ).


cl_fpm_factory
=>get_instance( )->display_error_pagecl_fpm_error_factory=>create_from_object(
io_exception_obj
= lo_hress iv_technical_exception = lv_tech_exception_text iv_additional_info = 'HRESS_EXCEPTION' ) ).
RETURN.
ENDTRY.


lv_object_id
= cl_crm_genil_container_tools=>build_object_id( ls_pernr_struc-pernr ).


CLEAR ls_object_spec .
ls_object_spec
-object_name = 'PERNR_BEN'.
ls_object_spec
-object_id = lv_object_id.
APPEND ls_object_spec TO lt_object_specs.

ls_object_spec
-object_name = 'HEALTH_PLANS'.
ls_object_spec
-object_id = lv_object_id.
APPEND ls_object_spec TO lt_object_specs.

ls_object_spec
-object_name = 'DEPENDENTS'.
ls_object_spec
-object_id = lv_object_id.
APPEND ls_object_spec TO lt_object_specs.

lo_collection_in
= lo_collection_out = lo_bol_core->get_root_entities( it_instances = lt_object_specs ).
lo_iterator     
= lo_collection_out->get_iterator( ).
lo_entity 
= lo_iterator->get_first( ).


IF lo_entity  IS BOUND.

lo_entity
->lock( ). "Lock the root entity
lo_entity
->reread( ). "Refresh / re-read the contents

IF lo_collection_out IS BOUND.
lo_entity 
= lo_collection_out->get_first( ).
IF  lo_entity IS BOUND.
lo_entity
->reread( ). "*          "Refresh / re-read the contents


*--Filtering the relevant Plan type and Benefit plan from the Health Plans. We are building a filter for that.

lv_rel_name = 'HEALTH_PLANS_REL'.
lo_bol_filter
cl_crm_bol_relation_filter=>get_instance( lv_rel_name ).

CALL METHOD lo_bol_filter ->if_bol_bo_property_access~set_property
EXPORTING
iv_attr_name
= 'ENDDA'
iv_value    
= '99991231'.

CALL METHOD lo_bol_filter ->if_bol_bo_property_access~set_property
EXPORTING
iv_attr_name
= 'BEGDA'
iv_value    
= sy-datum.

CALL METHOD lo_bol_filter ->if_bol_bo_property_access~set_property
EXPORTING
iv_attr_name
= 'PLAN_TYPE'
iv_value    
= 'DPLF'.

CALL METHOD lo_bol_filter->if_bol_bo_property_access~set_property
EXPORTING
iv_attr_name
= 'BPLAN'
iv_value    
= 'DPL1'.

CALL METHOD lo_bol_filter->if_bol_bo_property_access~set_property
EXPORTING
iv_attr_name
= 'EVENT'
iv_value    
= 'ANYT'.


*--Reading the Plan Data from BOL with the filter
lo_collection_out
= lo_entity ->get_related_entities_by_filter( iv_relation_name lv_rel_name                                                                                     iv_filter lo_bol_filter ).

lo_entity
->lock( ).

lo_entity
->reread( ).

IF lo_collection_out IS BOUND.

lo_iterator
= lo_collection_out->get_iterator( ).
lo_entity 
= lo_iterator->get_first( ).

CLEAR lv_string.

WHILE lo_entity  IS BOUND. "Looping of Benefit plans


CALL METHOD lo_entity->get_property_as_value
EXPORTING
iv_attr_name
= 'BOPTI'
IMPORTING
ev_result   
= lv_string.


*--We have added a condition here, as per requirement. If only the plan option is either ‘1OPT’ or ‘2OPT’, we need to read the dependent data.

  IF lv_string EQ '1OPT' OR lv_string EQ '2OPT'.

*-Reading the health plan dependents data from BOL


lv_rel_name
= 'HEALTH_DEP_REL'.
lo_collection_out
= lo_entity->get_related_entities(
iv_relation_name  
= lv_rel_name ).
lo_entity
->lock( ).
lo2_iterator
= lo_collection_out->get_iterator( ).
lo_entity
= lo2_iterator->get_first( ).

WHILE lo_entity  IS BOUND. "Looping of dependents record


*-Reading the values of attributes such as BPLAN, DEP_TYPE, etc. This is to read the relevant data from itab LT_DEP_SEL, which contains the      *- data to be updated. The code for populating the itab LT_DEP_SEL is not mentioned here. You can use data based on your requirement.


CALL METHOD lo_entity->get_property_as_value
EXPORTING
iv_attr_name
= 'BPLAN'
IMPORTING
ev_result   
= lv_string.

lx_dep_sel
-bplan = lv_string.
CLEAR lv_string.

CALL METHOD lo_entity->get_property_as_value
EXPORTING
iv_attr_name
= 'DEP_TYPE'
IMPORTING
ev_result   
= lv_string.

lx_dep_sel
-dep_type = lv_string.
CLEAR lv_string.

CALL METHOD lo_entity->get_property_as_value
EXPORTING
iv_attr_name
= 'DEP_ID'
IMPORTING
ev_result   
= lv_string.

lx_dep_sel
-dep_id = lv_string.
CLEAR lv_string.

CALL METHOD lo_entity->get_property_as_value
EXPORTING
iv_attr_name
= 'PERID'
IMPORTING
ev_result   
= lv_string.

lx_dep_sel
-perid = lv_string.
CLEAR lv_string.


lo_entity
->switch_to_change_mode( ).
IF lo_entity ->is_changeable( ) = abap_true.
IF lo_entity ->alive( ) = abap_true.
lo_access
= lo_entity .


*-Reading the dependent details from already populated itab
READ TABLE lt_dep_sel INTO lx_dep_sel_n WITH KEY bplan = lx_dep_sel-bplan
                                                 dep_type
= lx_dep_sel-dep_type
                                                 dep_id
= lx_dep_sel-dep_id
                                                 perid
= lx_dep_sel-perid.
IF sy-subrc EQ 0.
lv_string
= lx_dep_sel_n-selected. This value has to set to the respective BOL attribute.
CLEAR: lx_dep_sel,
lx_dep_sel_n
.
ENDIF.

TRY.

  *-Updating the BOL data
lo2_access
->set_property_as_string(
iv_attr_name
= 'SELECTED'
iv_value    
= lv_string ).
lo_entity
->activate_sending( ).


CATCH cx_crm_cic_parameter_error.
ENDTRY.
ENDIF.
ENDIF.

lo_entity ?= lo2_iterator
->get_next(  ). "Dependent loop

ENDWHILE.
ENDIF.
lo_entity  ?= lo_iterator
->get_next(  ). "Health Plan loop
ENDWHILE.

ENDIF.
ENDIF.
ENDIF.
ENDIF.
ENDIF.
ENDIF.

Thank you

ALV list output exception column

$
0
0

Hi Experts,

 

i was working on an report and i had to use the Exception function of the ALV list output. After reasearching i didn't find an proper document that summarizes the Exception groups and the exception funktion of ALV list ouputs. So i created one that i want to share with you.

 

 

 

Exception Column in ALV Lists

 

Exception Groups

In the context of the ALV list output there are several cell graphics that can be displayed by using the so called Exceptions. These Exceptions are sorted into several groups. For an output of an Exception column you have to define an output column of the type CHAR. This columns normally holds a single value. In the following tables you can see which value has to be set for the several exception groups for each row/node of the output. Also you have to set the exception column on the ALV object by calling the method SET_EXCEPTION that needs the column name of the output structure and the exception group..

groupsoverview.jpg


Exc. group 1: LIGHTS

grup1.jpg

 

Exc. group 2: LED

group2.jpg


Exc. group 3: STATUS

group3.jpg


Exc. group 4: TREND

group4.jpg

 

Exc. group 5: MESSAGE

group5.jpg


Exc. group 6: ALERT/ WARNING/ HINT

group6.jpg


Exc. group 7: FAILURE/ INCOMPLETE/ CHECKED

group7.jpg

Notes

Affected are the following column classes:CL_SALV_COLUMNS_LIST

 

Example

 

REPORT ZERO_ZUCKER.

 

TYPES: BEGIN OF TY_TEST.

         INCLUDE TYPE MARA.

TYPES: EXCEPTION TYPE C,

END OF TY_TEST.

 

DATA: LT_MARA   TYPE STANDARD TABLE OF TY_TEST,

       LS_MARA   TYPE TY_TEST,

       LV_STRING TYPE LVC_VALUE.

 

DATA: LR_SALV_TREE TYPE REF TO CL_SALV_TREE,

       LR_COLUMNS   TYPE REF TO CL_SALV_COLUMNS_TREE,

       LR_NODES     TYPE REF TO CL_SALV_NODES,

       LR_NODE      TYPE REF TO CL_SALV_NODE,

       LV_KEY       TYPE SALV_DE_NODE_KEY.

 

START-OF-SELECTION.

 

   TRY.

       CALL METHOD CL_SALV_TREE=>FACTORY

         IMPORTING

           R_SALV_TREE = LR_SALV_TREE

         CHANGING

           T_TABLE     = LT_MARA.

     CATCH CX_SALV_ERROR .

   ENDTRY.

 

   SELECT * UP TO 10 ROWS INTO CORRESPONDING FIELDS OF TABLE LT_MARA FROM MARA.

 

   LR_NODES = LR_SALV_TREE->GET_NODES( ).

   LOOP AT LT_MARA INTO LS_MARA.

     CASE LS_MARA-MSTAE.

       WHEN 4. "normales Material

         LS_MARA-EXCEPTION = 3.

       WHEN 5. "Sondermaterial

         LS_MARA-EXCEPTION = 2.

       WHEN 7. "Auslaufendes Material

         LS_MARA-EXCEPTION = 1.

     ENDCASE.

     move LS_MARA-MATNR TO LV_STRING.

     LR_NODE = LR_NODES->ADD_NODE( RELATED_NODE   = LV_KEY

                                   RELATIONSHIP   = CL_GUI_COLUMN_TREE=>RELAT_FIRST_CHILD

                                   TEXT           = LV_STRING ).

     LR_NODE->SET_DATA_ROW( ls_mara ).

 

   ENDLOOP.

 

   TRY.

       LR_COLUMNS = LR_SALV_TREE->GET_COLUMNS( ).

       LR_COLUMNS->SET_EXCEPTION_COLUMN( VALUE = 'EXCEPTIONS' GROUP = 1 ).

     CATCH CX_SALV_NOT_FOUND.

   ENDTRY.

 

   LR_SALV_TREE->DISPLAY( ).

 

Futher Informations:

A Dirty Little Trick to use Check-boxes to Simulate Radio-buttons

$
0
0

The Problem:

 

How many times has this happened to you: you’re sitting at your desk, quietly banging away at the keyboard, pumping out simple, elegant ABAP code, when you user sends you an e-mail saying “and oh, by the way, those two radio-buttons on the new screen – both should be de-selected.” The request, although unusual, is reasonable. Users must be forced to make decision about which option to choose. There should be no default button selected.

 

Never? Well, OK, it doesn’t happen very often, but I got a request like this a while ago, and it turned out not to be so simple.

 

INITIALizing both of them to blank didn’t work. The first radio-button was still selected.

 

I tried using three radio-buttons, selecting and hiding the first one. Still no luck – the first one was still selected.

 

Finally, I searched SCN, and found a few discussions about this, suggesting the same things that I had tried but found that didn’t work.

 

What to do?

 

The Solution:

 

This is the code that I came up with:

 

REPORT ztest.

DATAold_no,
      old_yes
.

SELECTION-SCREEN BEGIN OF LINE.

SELECTION-SCREEN POSITION 1.
SELECTION-SCREEN COMMENT 1(21) text-001.           “ Pick one

SELECTION-SCREEN POSITION 23.
PARAMETERS: p_no AS CHECKBOX USER-COMMAND ucom1.
SELECTION-SCREEN COMMENT 25(2) text-002.           “ Yes

SELECTION-SCREEN POSITION 30.
PARAMETERS  p_yes AS CHECKBOX USER-COMMAND ucom2.
SELECTION-SCREEN COMMENT 32(3) text-003.           “ No

SELECTION-SCREEN END   OF LINE.

AT SELECTION-SCREEN.

     
IF sy-ucomm = 'UCOM1'.
          
IF p_no IS INITIAL.
               
IF old_no IS INITIAL.
                     p_yes  
= 'X'.
                     old_yes
= 'X'.
                     old_no 
= ' '.
               
ELSE.
                     p_no 
= 'X'.
                     p_yes
= ' '.
               
ENDIF.
          
ELSE.
                p_yes  
= ' '.
                old_yes
= ' '.
                old_no 
= 'X'.
          
ENDIF.
     
ELSEIF sy-ucomm = 'UCOM2'.
          
IF p_yes IS INITIAL.
               
IF old_yes IS INITIAL.
                     p_no   
= 'X'.
                     old_no 
= 'X'.
                     old_yes
= ' '.
               
ELSE.
                     p_yes
= 'X'.
                     p_no 
= ' '.
               
ENDIF.
          
ELSE.
               p_no   
= ' '.
               old_no 
= ' '.
               old_yes
= 'X'.
          
ENDIF.
     
ENDIF
.

 

A couple of caveats:

 

The code was developed for a module pool screen; this is a report.

 

This code can be modified to handle multiple check-boxes.

iXML Cheat Sheet

$
0
0

One of my maiden attempts at creating an excel output in SAP, was using the iXML method.

 

I found plenty of resources across SCN and other sites which explained how to create an excel.

But what I had trouble with was finding the right attributes to suit my requirements.

 

Below, I have noted down the attributes that I had used in my developments from my experience.

 

This is an attempt to add and accumulate all the attributes developers to add to / correct the below attributes.

 

 

Sr. No

ElementAttributeValuesUseChild of

 

Things to Note

1BorderPositionBottom
Left
Top
Right
Bottom Border Position
Left Border Position
Top Border Position
Right Border Position
Borders
2LineStyleContinuous
Dotted
Continuous Border
Dotted Border
3Weight< Any Numeric Value >Weight of the border line
4DataTypeString
Number
Cell contains string data
Cell contains numeric data. (Needed to perform numeric calculations)
Cell
5CellStyleID< Name of style >Apply style to cellRow
6Index< Any Numeric Value >Numeric position of cell
7MergeAcross< Any Numeric Value >Merge cells horizontallyIt is mandatory to specify indexes if you are using MergeAcross
8MergeDown< Any Numeric Value >Merge cells verticallyIf you do a MergeDown, it is not required to create a row explicitly for the subsequent row, but it is required to specify atleast one cell in the following row using an index
9FontFontName< Required font installed in system>Apply a font to a styleStyle
10Bold1
< space >
Bold font
Normal font
11UnderlineSingle
Double
Single Underline
Double Underline
12Color< Any color name or hex value >Apply color to font
13Size< Any Numeric Value >Change font size
14AlignmentHorizontalLeft
Right
Center
Align text left horizontally
Align text right horizontally
Align text center horizontally
15VerticalTop
Bottom
Center
Align text top vertically
Align text bottom vertically
Align text center vertically
16Workbookxmlns< xml name space to be used >Part of open office specification.Document
17StyleID< Any Name >Assign name to your styleStyles
18NumberFormatFormat< example '0.00' >
<example '0,000.00'>
Set the number format in the cellStyleShould be preceeded with a format attribute with value '@'
If you do not specify the number of decimals, no decimals will be displayed
19WorksheetName< any name >Name to be assigned to the worksheetRoot
20TableFullColumns1 or 0Display and use all columnsWorksheet
21FullRows1 or 0Display and use all rows
22ColumnWidth< Any Numeric Value >Set column widthTable

BOM alv report / change number solution

$
0
0

In this document ;  Bill of material list report developed with alv concept to run all of materials which are listed by users. The most important trick is a solution of dublicate records in BOM tables so change number records.

 

For example : In belowed printscreen that you can see STPO table.

 

If you read STPO table without a restriction , you will get 2 rows for PY200005 Bom item material.

 

1.JPG

 

If you do not benefit change number functionality , you can join tables like belowed and it can be used to list BOMs.

 

2.JPG

 

But , change number functionality cause additional records in STPO and other related PP tables.

 

To solve this problem , you can benefit belowed alv report.

 

This report provides last record of changing component with change number.

 

Go to SE38 , add this code and list results.

 



*&---------------------------------------------------------------------*
*& Report  ZPP_BILL_OF_MATERIAL
*&
*&---------------------------------------------------------------------*
*& M.Ozgur Unal ------ 04.11.2014
*& Ürün ağaçları listeleme raporudur.
*& özgü :)
*&---------------------------------------------------------------------*

REPORT  ZPP_BILL_OF_MATERIAL.

TYPE-POOLS : slis.
CONSTANTS : c_tcode(4)TYPE c VALUE'CS03'.
TABLES : mast , stko , stpo , stas , makt , mara .

*************************
* DATA TYPES DEFINITIONS*
*************************

DATA: BEGINOF it_mast OCCURS0,
          matnr  LIKE mast-matnr,
          werks  LIKE mast-werks,
          stlan  LIKE mast-stlan,
          stlnr  LIKE mast-stlnr,
          stlal  LIKE mast-stlal,
          maktx  LIKE makt-maktx,
          matkl  LIKE mara-matkl,
       ENDOF it_mast.

DATA : BEGINOF it_stko OCCURS 0,
          stlnr LIKE stko-stlnr,
          stlal LIKE stko-stlal,
          datuv LIKE stko-datuv,
          bmein LIKE stko-bmein,
          bmeng LIKE stko-bmeng,
          stlst LIKE stko-stlst,
        ENDOF it_stko.

DATA : BEGINOF it_stpo OCCURS 0,
          stlnr LIKE stpo-stlnr,
          stlkn LIKE stpo-stlkn,
          datuv LIKE stpo-datuv,
          idnrk LIKE stpo-idnrk,
          meins LIKE stpo-meins,
          menge LIKE stpo-menge,
          aennr LIKE stpo-aennr,
          andat LIKE stpo-andat,
          annam LIKE stpo-annam,
          aenam LIKE stpo-aenam,
          posnr LIKE stpo-posnr,
          maktx LIKE makt-maktx,
          vgknt LIKE stpo-vgknt,
          stvkn LIKE stpo-stvkn,
          stpoz LIKE stpo-stpoz,
          vgpzl LIKE stpo-vgpzl,
          matkl LIKE mara-matkl,
        ENDOF it_stpo.

DATA : BEGINOF it_stas OCCURS 0,
          stlnr LIKE stas-stlnr,
          stlal LIKE stas-stlal,
          stlkn LIKE stas-stlkn,
          aennr LIKE stas-aennr,
          lkenz LIKE stas-lkenz,
          stvkn LIKE stas-stvkn,
        ENDOF it_stas.

DATA : BEGINOF it_final OCCURS 0,
          matnr LIKE mast-matnr,
          werks LIKE mast-werks,
          stlan LIKE mast-stlan,
          stlnr LIKE mast-stlnr,
          stlal LIKE mast-stlal,
          datuv LIKE stko-datuv,
          bmein LIKE stko-bmein,
          bmeng LIKE stko-bmeng,
          idnrk LIKE stpo-idnrk,
          posnr LIKE stpo-posnr,
          meins LIKE stpo-meins,
          menge LIKE stpo-menge,
          maktx LIKE makt-maktx,
          aennr LIKE stpo-aennr,
          andat LIKE stpo-andat,
          annam LIKE stpo-annam,
          aenam LIKE stpo-aenam,
          matkl LIKE mara-matkl,
          stlst LIKE stko-stlst,
          lkenz LIKE stas-lkenz,
         maktx2 LIKE makt-maktx,
          stvkn LIKE stas-stvkn,
          vgknt LIKE stpo-vgknt,
          stlkn LIKE stpo-stlkn,
         stvkn2 LIKE stpo-stvkn,
          stpoz LIKE stpo-stpoz,
          vgpzl LIKE stpo-vgpzl,
         matkl2 LIKE mara-matkl,
  ENDOF it_final.


DATA : wa_mast LIKELINEOF it_mast.
DATA : wa_stko LIKELINEOF it_stko.
DATA : wa_stpo LIKELINEOF it_stpo,
       wa_stas LIKELINEOF it_stas,
       gw_final LIKELINEOF it_final,
       gw_final2 LIKELINEOF it_final,
       gt_fcat  TYPE slis_t_fieldcat_alv,
       gw_fcat  TYPE slis_fieldcat_alv.


******************
*SELECTION SCREEN*
******************

SELECTION-SCREENBEGINOFBLOCK blk WITHFRAMETITLE text-001.

SELECT-OPTIONS: s_matnr FOR  mast-matnr,
                s_matkl FOR  mara-matkl.
PARAMETERS p_werks TYPE mast-werks OBLIGATORYDEFAULT1006.

SELECTION-SCREENENDOFBLOCK blk.

*******************************
*GET DATA & INSERT TO GT_FINAL*
*******************************

PERFORM get_data.

PERFORM loop_data.


IF it_final[] ISNOTINITIAL.

  PERFORM f_fill_fcat .
  PERFORM f_display_alv .

ELSE.
  MESSAGE'Veri bulunamadı'TYPE'I'.
ENDIF.

PERFORM plant_validation.

*&---------------------------------------------------------------------*
*&      Form  FETCH_DATA_RETREIVE
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*  -->  p1        text
*  <--  p2        text
*----------------------------------------------------------------------*
FORM get_data .

" break ounal.

  SELECT mast~matnr mast~werks mast~stlan mast~stlnr mast~stlal
         makt~maktx mara~matkl

           INTOCORRESPONDINGFIELDSOFTABLE it_mast
           FROM mast
           INNERJOIN makt
           ON mast~matnr = makt~matnr
           INNERJOIN mara
           ON makt~matnr = mara~matnr
           WHERE  mast~matnr IN s_matnr
                AND mast~werks = p_werks
                AND mast~stlan ='1'
                AND mara~matkl IN s_matkl.

  IFLINES( it_mast )GT0.
    SELECT stlnr stlal datuv bmein bmeng
           aennr andat annam  aenam stlst
           FROM stko
           INTOCORRESPONDINGFIELDSOFTABLE it_stko
           FORALLENTRIESIN it_mast
           WHERE stlnr = it_mast-stlnr AND
                 stlal = it_mast-stlal.

    SORT it_stko BY datuv DESCENDING.

    SELECT stlnr stlal stlkn lkenz aennr stvkn
           FROM stas INTOCORRESPONDINGFIELDSOFTABLE it_stas
           FORALLENTRIESIN it_mast
           WHERE stlnr = it_mast-stlnr AND
                 stlal = it_mast-stlal.

    SORT it_stas BY lkenz DESCENDING.

  ENDIF.

*20.11.2014 - M.Ozgur Unal
*Üretim tarafından bileşenlerin mal grubu eklenmesi talebi ile
*revize edildi.

IFLINES( it_stko )GT0.
    SELECT stpo~stlnr stpo~stlkn stpo~datuv stpo~idnrk
           stpo~posnr stpo~meins stpo~menge stpo~aennr
           stpo~andat stpo~annam stpo~aenam stpo~posnr
           makt~maktx stpo~vgknt stpo~stvkn stpo~stpoz
           stpo~vgpzl mara~matkl
           FROM stpo
           INNERJOIN makt
           ON stpo~idnrk = makt~matnr
           INNERJOIN mara
           ON makt~matnr = mara~matnr
           INTOCORRESPONDINGFIELDSOFTABLE it_stpo
           FORALLENTRIESIN it_mast
           WHERE stlnr = it_mast-stlnr.

  ENDIF.

ENDFORM.                    " FETCH_DATA_RETREIVE



*&---------------------------------------------------------------------*
*&      Form  LOOP_DATA
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*  -->  p1        text
*  <--  p2        text
*----------------------------------------------------------------------*
FORM loop_data .

  REFRESH it_final.

  LOOPAT it_mast INTO wa_mast.

    LOOPAT it_stpo INTO wa_stpo WHERE stlnr = wa_mast-stlnr.

       IF sy-subrc =0.
        MOVE: wa_mast-matnr TO gw_final-matnr,
              wa_mast-stlnr TO gw_final-stlnr,
              wa_mast-werks TO gw_final-werks,
              wa_mast-stlal TO gw_final-stlal,
              wa_mast-stlan TO gw_final-stlan,
              wa_mast-matkl TO gw_final-matkl,
              wa_mast-maktx TO gw_final-maktx2,
              wa_stpo-matkl TO gw_final-matkl2,
              wa_stpo-idnrk TO gw_final-idnrk,
              wa_stpo-menge TO gw_final-menge,
              wa_stpo-aennr TO gw_final-aennr,
              wa_stpo-andat TO gw_final-andat,
              wa_stpo-annam TO gw_final-annam,
              wa_stpo-aenam TO gw_final-aenam,
              wa_stpo-posnr TO gw_final-posnr,
              wa_stpo-meins TO gw_final-meins,
              wa_stpo-maktx TO gw_final-maktx,
              wa_stpo-datuv TO gw_final-datuv,
              wa_stpo-stlkn TO gw_final-stlkn,
              wa_stpo-vgknt TO gw_final-vgknt,
              wa_stpo-stvkn TO gw_final-stvkn2,
              wa_stpo-stpoz TO gw_final-stpoz,
              wa_stpo-vgpzl TO gw_final-vgpzl.

      READTABLE it_stko INTO wa_stko WITHKEY stlnr = wa_mast-stlnr
                                               stlal = wa_mast-stlal.


      IF sy-subrc =0.
        MOVE: wa_stko-stlst TO gw_final-stlst,
              wa_stko-bmein TO gw_final-bmein,
              wa_stko-bmeng TO gw_final-bmeng.

     ENDIF.
    ENDIF.

      READTABLE it_stas INTO wa_stas WITHKEY stlnr = wa_stpo-stlnr
                                              " stlkn = wa_stpo-stlkn
                                               stvkn = wa_stpo-stvkn.

      MOVE: wa_stas-stvkn  TO gw_final-stvkn,
            wa_stas-lkenz  TO gw_final-lkenz.

   APPEND gw_final TO it_final.
   CLEAR gw_final.

     ENDLOOP.
   ENDLOOP.

*add by ounal.
*Silinip yerine değişiklik no ile atama yapılan kalemlerin ürün
*ağaçlarında standart dışında eski düğüm ve eski sayaç no yu
*kullanarak atama yapıyoruz.

FIELD-SYMBOLS: <fs_it_final>LIKELINEOF it_final,
               <fs_it_final2>LIKELINEOF it_final.

SORT it_final BY stlnr stlkn ASCENDING.
  IFLINES( it_final )NE0.
   LOOPAT it_final ASSIGNING<fs_it_final>.
     LOOPAT it_final ASSIGNING<fs_it_final2>.
    IF<fs_it_final>ISASSIGNED.
     IF<fs_it_final2>ISASSIGNED.
      IF<fs_it_final>-stlnr =<fs_it_final2>-stlnr AND
         <fs_it_final>-stlkn =<fs_it_final2>-vgknt AND
         <fs_it_final>-stpoz =<fs_it_final2>-vgpzl.

         <fs_it_final>-idnrk =<fs_it_final2>-idnrk.
         <fs_it_final>-menge =<fs_it_final2>-menge.
         <fs_it_final>-aennr =<fs_it_final2>-aennr.
         <fs_it_final>-matkl2 =<fs_it_final2>-matkl2.
         <fs_it_final>-lkenz =''.

      ENDIF.
     ENDIF.
     ENDIF.
    ENDLOOP.
   ENDLOOP.
  ENDIF.

ENDFORM.                    " LOOP_DATA

*&---------------------------------------------------------------------*
*&      Form  f_fill_fcat
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
FORM f_fill_fcat .

  gw_fcat-col_pos =1.
  gw_fcat-fieldname ='WERKS'.
  gw_fcat-tabname ='IT_FINAL'.
  gw_fcat-seltext_m ='Üretim yeri'.
  APPEND gw_fcat TO gt_fcat.
  CLEAR gw_fcat.


  gw_fcat-col_pos =2.
  gw_fcat-fieldname ='STLNR'.
  gw_fcat-tabname ='IT_FINAL'.
  gw_fcat-seltext_m ='Ürün ağacı no.'.
  APPEND gw_fcat TO gt_fcat.
  CLEAR gw_fcat.

  gw_fcat-col_pos =3.
  gw_fcat-fieldname ='STLAL'.
  gw_fcat-tabname ='IT_FINAL'.
  gw_fcat-seltext_m ='Alternatif bom'.
*   gw_fcat-do_sum = 'X'.
  APPEND gw_fcat TO gt_fcat.
  CLEAR gw_fcat.

  gw_fcat-col_pos =4.
  gw_fcat-fieldname ='MATNR'.
  gw_fcat-tabname ='IT_FINAL'.
  gw_fcat-seltext_m ='Malzeme No.'.
  APPEND gw_fcat TO gt_fcat.
  CLEAR gw_fcat.


  gw_fcat-col_pos =5.
  gw_fcat-fieldname ='MAKTX2'.
  gw_fcat-tabname ='IT_FINAL'.
  gw_fcat-seltext_m ='Kısa metin'.
  APPEND gw_fcat TO gt_fcat.
  CLEAR gw_fcat.

  gw_fcat-col_pos =6.
  gw_fcat-fieldname ='IDNRK'.
  gw_fcat-tabname ='IT_FINAL'.
  gw_fcat-seltext_m ='Bileşen'.
  gw_fcat-outputlen  =10.
*  gw_fcat-emphasize   = 'X'.
*  gw_fcat-key         = 'X'.
  APPEND gw_fcat TO gt_fcat.
  CLEAR gw_fcat.

  gw_fcat-col_pos =7.
  gw_fcat-fieldname ='POSNR'.
  gw_fcat-tabname ='IT_FINAL'.
  gw_fcat-seltext_m ='Kalem no'.
  APPEND gw_fcat TO gt_fcat.
  CLEAR gw_fcat.

  gw_fcat-col_pos =8.
  gw_fcat-fieldname ='BMENG'.
  gw_fcat-tabname ='IT_FINAL'.
  gw_fcat-seltext_m ='Temel miktar'.
  APPEND gw_fcat TO gt_fcat.
  CLEAR gw_fcat.

  gw_fcat-col_pos =9.
  gw_fcat-fieldname ='MENGE'.
  gw_fcat-tabname ='IT_FINAL'.
  gw_fcat-seltext_m ='Bileşen miktarı'.
  APPEND gw_fcat TO gt_fcat.
  CLEAR gw_fcat.

  gw_fcat-col_pos =10.
  gw_fcat-fieldname ='AENAM'.
  gw_fcat-tabname ='IT_FINAL'.
  gw_fcat-seltext_m ='Değiştiren'.
  APPEND gw_fcat TO gt_fcat.
  CLEAR gw_fcat.

  gw_fcat-col_pos =11.
  gw_fcat-fieldname ='MATKL'.
  gw_fcat-tabname ='IT_FINAL'.
  gw_fcat-seltext_m ='Mal grubu'.
  APPEND gw_fcat TO gt_fcat.
  CLEAR gw_fcat.

  gw_fcat-col_pos =12.
  gw_fcat-fieldname ='AENNR'.
  gw_fcat-tabname ='IT_FINAL'.
  gw_fcat-seltext_m ='Değişiklik no'.
  APPEND gw_fcat TO gt_fcat.
  CLEAR gw_fcat.

  gw_fcat-col_pos =13.
  gw_fcat-fieldname ='ANDAT'.
  gw_fcat-tabname ='IT_FINAL'.
  gw_fcat-seltext_m ='Kayıt tarihi'.
  APPEND gw_fcat TO gt_fcat.
  CLEAR gw_fcat.

  gw_fcat-col_pos =14.
  gw_fcat-fieldname ='ANNAM'.
  gw_fcat-tabname ='IT_FINAL'.
  gw_fcat-seltext_m ='Kaydeden'.
  APPEND gw_fcat TO gt_fcat.
  CLEAR gw_fcat.

  gw_fcat-col_pos =15.
  gw_fcat-fieldname ='DATUV'.
  gw_fcat-tabname ='IT_FINAL'.
  gw_fcat-seltext_m ='Geçerlilik başı'.
  APPEND gw_fcat TO gt_fcat.
  CLEAR gw_fcat.

  gw_fcat-col_pos =16.
  gw_fcat-fieldname ='STLST'.
  gw_fcat-tabname ='IT_FINAL'.
  gw_fcat-seltext_m ='Statü'.
  APPEND gw_fcat TO gt_fcat.
  CLEAR gw_fcat.

  gw_fcat-col_pos =17.
  gw_fcat-fieldname ='BMEIN'.
  gw_fcat-tabname ='IT_FINAL'.
  gw_fcat-seltext_m ='Temel ölçü'.
  APPEND gw_fcat TO gt_fcat.
  CLEAR gw_fcat.

  gw_fcat-col_pos =18.
  gw_fcat-fieldname ='MEINS'.
  gw_fcat-tabname ='IT_FINAL'.
  gw_fcat-seltext_m ='Bileşen ölçü'.
  APPEND gw_fcat TO gt_fcat.
  CLEAR gw_fcat.

  gw_fcat-col_pos =19.
  gw_fcat-fieldname ='MAKTX'.
  gw_fcat-tabname ='IT_FINAL'.
  gw_fcat-seltext_m ='Bileşen metni'.
  APPEND gw_fcat TO gt_fcat.
  CLEAR gw_fcat.

  gw_fcat-col_pos =20.
  gw_fcat-fieldname ='LKENZ'.
  gw_fcat-tabname ='IT_FINAL'.
  gw_fcat-seltext_m ='Silme'.
  APPEND gw_fcat TO gt_fcat.
  CLEAR gw_fcat.

  gw_fcat-col_pos =21.
  gw_fcat-fieldname ='STVKN'.
  gw_fcat-tabname ='IT_FINAL'.
  gw_fcat-seltext_m ='Düğüm as'.
  APPEND gw_fcat TO gt_fcat.
  CLEAR gw_fcat.

  gw_fcat-col_pos =22.
  gw_fcat-fieldname ='VGKNT'.
  gw_fcat-tabname ='IT_FINAL'.
  gw_fcat-seltext_m ='Önceki düğüm'.
  APPEND gw_fcat TO gt_fcat.
  CLEAR gw_fcat.

  gw_fcat-col_pos =23.
  gw_fcat-fieldname ='STVKN2'.
  gw_fcat-tabname ='IT_FINAL'.
  gw_fcat-seltext_m ='Düğüm po'.
  APPEND gw_fcat TO gt_fcat.
  CLEAR gw_fcat.

  gw_fcat-col_pos =24.
  gw_fcat-fieldname ='STLKN'.
  gw_fcat-tabname ='IT_FINAL'.
  gw_fcat-seltext_m ='Düğüm'.
  APPEND gw_fcat TO gt_fcat.
  CLEAR gw_fcat.

  gw_fcat-col_pos =25.
  gw_fcat-fieldname ='STPOZ'.
  gw_fcat-tabname ='IT_FINAL'.
  gw_fcat-seltext_m ='Dahili sayaç'.
  APPEND gw_fcat TO gt_fcat.
  CLEAR gw_fcat.

  gw_fcat-col_pos =26.
  gw_fcat-fieldname ='VGPZL'.
  gw_fcat-tabname ='IT_FINAL'.
  gw_fcat-seltext_m ='Eski sayaç'.
  APPEND gw_fcat TO gt_fcat.
  CLEAR gw_fcat.

  gw_fcat-col_pos =27.
  gw_fcat-fieldname ='MATKL2'.
  gw_fcat-tabname ='IT_FINAL'.
  gw_fcat-seltext_m ='Bileşen mal grubu'.
  APPEND gw_fcat TO gt_fcat.
  CLEAR gw_fcat.

ENDFORM.                    "f_fill_fcat

*&---------------------------------------------------------------------*
*&      Form  f_display_alv
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
FORM f_display_alv .
  DATA:lv_repid TYPE sy-repid.
  lv_repid = sy-cprog.

  DATA: w_layout TYPE slis_layout_alv.
  w_layout-colwidth_optimize ='X'.
  w_layout-zebra ='X'.


  CALLFUNCTION'REUSE_ALV_GRID_DISPLAY'
     EXPORTING

       i_callback_program     = sy-cprog
       is_layout              = w_layout
       i_callback_user_command ='USER_COMMAND'
       it_fieldcat            = gt_fcat[]
       i_default              ='X'
       i_save                 ='A'
     TABLES
       t_outtab               = it_final
     EXCEPTIONS
       program_error          =1
       OTHERS                 =2.
  IF sy-subrc <>0.
* MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO
*         WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.
  ENDIF.

ENDFORM.                    "f_display_alv
*&---------------------------------------------------------------------*
*&      Form  PLANT_VALIDATION
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*  -->  p1        text
*  <--  p2        text
*----------------------------------------------------------------------*
FORM plant_validation .
  DATA : lv_plant TYPE mast-werks.
  SELECTSINGLE werks
         FROM mast
        INTO  lv_plant
    WHERE werks = p_werks.

  IF sy-subrc NE0.
    MESSAGE'Üretim yerini kontrol ediniz'TYPE'I'.
    RETURN.
  ENDIF.
ENDFORM.                    "PLANT_VALIDATION



*&---------------------------------------------------------------------*
*&      Form  user_command
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*      -->R_UCOMM      text
*      -->RS_SELFIELD  text
*----------------------------------------------------------------------*
FORM user_command USING r_ucomm LIKE sy-ucomm rs_selfield TYPE
slis_selfield.

  IF r_ucomm ='&IC1'.

    READTABLE it_final INTO gw_final INDEX rs_selfield-tabindex.

    rs_selfield-value = gw_final-matnr.

    SETPARAMETERID'MAT'FIELD rs_selfield-value.
    CALLTRANSACTION'CS03'ANDSKIPFIRSTSCREEN.

  ENDIF.

ENDFORM.                    "user_command

 

 

 

   Finally , you can get this list.

 

3.JPG

 

   Regards.

 

   M.Ozgur Unal

Purchasing history report

$
0
0

This document explains how can we create a purchasing history report with query. In standart MM Module , there are a lot of reports like ME80FN , ME2* , MB5S etc. They are used to get your requirements. But , customers need to get a lot of details and different variances report formats.However , you can not find a solution for SAP will not display POs in ME80FN that are deleted. For this reasons, we can develop a report to respond all requirements. In generally , this report has to contain PO/SA/Contract --> GR --> IR chain. If customers get this information in report , they would create a lot of report in excel.

 

In this document , a report will be designed to meet the needs with SAP Query.


Related Tcodes : SQ01 , SQ02 , SQ03 , SQ10 , SU24 , SE93

Related Tables : EKBE , EKKO , EKPO , LFA1 , EKKN , RBKP,RSEG

 

Helpful documents in SCN :

 

Making of Boxed Reports for BOMs (using LDBs in Infoset Query)

GOS : Value Addition to your Infoset Query

Query Report Tips Part 2 - Mandatory Selection Field And Authorization Check

Calling Reports from an Infoset Query

Some tips on ABAP query (SQ01) Part 2

How to create Report by using SQVI

 

Firstly , i create a Infoset to get data.


---> Go to SQ02 tcode create a infoset named ZEKBE or what you want.


Also , there are some extras. For example , reversal of GR or IR can be report also , customers can want to eliminate reversal docoment and its real document. In belowed , ZTK field is added to get a key for reversal documents relations.


1.JPG

 

---> To respond reversal documents key requirement , we can write a code block so we have to read another tables.


Note : Be careful careful , because BELNR --> Document Number of an Invoice Document is repeat again every year.

 


data : i_mblnr like mseg-mblnr.
tables: rbkp.
data : beginof fat_tab occurs 0,
      menge like ekbe-menge,
      shkzg like ekbe-shkzg,
      xblnr like ekbe-xblnr,
      endof fat_tab.
data s_menge like ekbe-menge.
break ounal.
clear zztk.
clear fat_tab.refresh fat_tab.

if ekbe-bewtp ='E'and ekbe-bwart ='102'and
  ekbe-belnr ne ekbe-lfbnr.
  zztk ='X'.
elseif ekbe-bewtp ='E'and ekbe-bwart ='101'.
  selectsingle mblnr from mseg into i_mblnr
    where smbln = ekbe-belnr and
    smblp = ekbe-buzei and sjahr = ekbe-gjahr.
  if sy-subrc isinitial.
    zztk ='X'.
  else.
endif.

* Modified by M.Ozgur Unal - 14.01.2015

elseif ekbe-bewtp ='Q'.
  select * from rbkp where belnr = ekbe-belnr
                     and blart ='TK'.
  endselect.
  if sy-subrc isinitial.
    zztk ='X'.
  else.
    select * from rbkp where stblg = ekbe-belnr
                         and gjahr = ekbe-gjahr.
    endselect.
    if sy-subrc isinitial.
      zztk ='X'.
    endif.
  endif.
endif.

   2.JPG


--->Also , there are another adding fields like 'Amount of quantity delivery note X unit price ' --> ZZDMBTR type P



data: out like ekbe-lsmng.
*if ekpo-bprme ne ekbe-lsmeh.
callfunction'ZMM_UNIT_CONV'
  exporting
    i_matnr                 = ekbe-matnr
    i_source_value          = ekbe-lsmng
    i_source_unit           = ekbe-lsmeh
    i_target_unit           = ekpo-bprme
  importing
    e_target_value          = out
*     E_MATNR_SUBRC            =
*   EXCEPTIONS
*     MATNR_INVALID            = 1
*     SOURCE_UOM_INVALID       = 2
*     TARGET_UOM_INVALID       = 3
*     OTHERS                   = 4
          .
if sy-subrc <>0.
* MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO
*         WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.
endif.
zzdmbtr = out * ekpo-netpr / ekpo-peinh.
*ENDIF.

 

For ABAPer , Transaction/event type, purchase order history has to known to design report.

 

1Goods Receipt
2Invoice Receipt
3Subseq. Debit/Credit
4Down Payment
5Payment
6Goods Issue for Stock Transfer
7Consumption (Subcontracting)
8Delivery (Stock Transfer)
9Service Entry Sheet
   ADown Payment Request
  CDown Payment Clearing
  QComparison for Internally Posted Material (Only IS-OIL)
  RReturn Delivery via Delivery Note
  PInvoice Parking
  VDown Payment Request Clearing


a

s---

Join logic can be designed like belowed.

 

3.JPG

 

---> Secondly , Go to SQ01 and create your query.

 

4.JPG

 

---> Select fiedls of 'display and fields appearing on the selection screen'.

 

5.JPG

 

---> Finally , you can get all details for PO-->GR-->IR chain.

 

6.JPG

 

---> Also , you can authorize end users.

---> Assign infoset to role

 

7.JPG

 

---> Go to SU24 , this has to be defined for tcode and authorization objects.

 

8.JPG

 

---> Execute (F8)

 

9.JPG

 

9.JPG

 

---> Go to SE93 , define your tcode and link program name to tcode.

 

10.JPG

 

   Regards.

 

   M.Ozgur Unal

 



<

SAP ABAP Scanner

$
0
0

Hi,

 

It's been long time working in SAP as technical consultant and I think everyday something new comes at the front of my eyes, which is new to me. Which I have already tried.

 

Few months ago, I got an issue, where someone has written a validation based on Order creation process, VA01.

 

And put some hard coded message. And user wants to remove that validation from the system.

 

Though, it was a hard code message, I have spent few hours, did some debugging on standard codes and finally got the respective enhancement place.

 

Now come to main point, SAP system already provided where used search help with respect to tables, programs, class, DD objects, message.

 

But other objects, like

  1. System Call commands,
  2. Hard Coded Messages
  3. Pseudo codes
  4. And depends on your requirement, what else you want to search in SAP system.


Here is a program which is provided by SAP to search a string in SAP system.

 

Few days ago, I have post a question in SCN, like how many types are Pseudo codes are exist in SAP system, I didn't received any perfect ans.

But, through this Program, now I am able to gather all Pseudo code which is used by SAP in SAP system.

 

Program Name      :               AFX_CODE_SCANNER

T-Code                 :               CODE_SCANNER

 

tet.jpg

 

I have executed this report to search Pseudo code in System for all *ABAP* packages..

 

Output :

 

tet.jpg

 

In SAP system contains huge no standard and customized programs. So we can search our search string based on package. (Which is mandatory field in program)

 

Like that, we can search based on other criteria like

  • Ø Program,
  • Ø Function Groups
  • Ø Class.

 

Double click on any of output records; system will open the same respective program in same line.

 

Still lots of programs, t-code, procedures are there to learn.

 

Happy learning.

Praveer.


How to find the source code where the message is raised

$
0
0

Many a times we get some message in the bottom left of our screen while executing some custom program or TCode. This document will show you how to find the exact line of code which raises this message. I hope it will be useful to all of us.


 

1. I am using customized program in this example. When I execute this program I get the following message ‘No records found’. Now I want to find the source code from where this message is raised.

Picture 1.png

 

2. Go to TCode SE30/SAT. Enter your program name in ‘In Dialog’ box and select Program radio button. In this case I am using ‘ZFRO_CI_PAYMENT_INFO’ program. Then click on Execute.

Picture 2.png

 

3. System will take you to the same program. Enter your data so that same message pops up. Then press Exit button so that you come back to SAT TCode screen. Click on Evaluate tab. You will see Existing ABAP Runtime Measurements.

Picture 3.1.pngPicture 3.2.png


4. Click on Trace File column.

Picture 4.png

 

5. Search for message number in the trace file.

Picture 5.1.png     Picture 5.2.png 

6. Double click on this line will directly take you to the source code.Picture 6.png

Fetching Linked DMS Documents of Materials

$
0
0

BACKGROUND IN BRIEF

 

 

Documents can be assigned to a particular Material in Material Master and as well as in BOM.


1) MM03– To View Documents in Material Master

MM03.png

 


2) CS03  – To View Documents in BOM

CS03.png




REQUIREMENT


Suppose in a report we need to display all these documents against a particular Material.

 

We need two separate logic for this which are listed below.

 

1) Fetching the documents assigned in Material Master (MM01/MM02)

2) Fetching the documents assigned in BOM (CS01/CS02)




PROCEDURE


We will get the document list in DRAD table where we will get details like Document Type, Document Number, Document Version, etc.


1) Documents assigned in Material Master (MM01/MM02)


Pass 'MARA' in DOKOB field and material number in OBJKY field.

Material Master.png

We may face a problem here.

The data type of MATNR is 18 character but this OBJKY field is 50 character.

The easiest solution is...

We can keep another column of type DRAD-OBJKY in the same internal table where we have the list of all the materials.

Run a loop and convert the material number from 18 character  to 50 character.

After this use SELECT Query to fetch data from DRAD table using FOR ALL ENTRIES with the new prepared column having material number of length 50 characters.



2) Documents assigned in BOM (CS01/CS02)

 

Step A: Fetch the the BOM Number(STLNR) form MAST Table by passing Material Number(MATNR) and Plant(WERKS).
MAST.png

 

Step B: Then we will fetch the Guid(GUIDX) of the that BOM Material from STKOtable by passing BOM category(STLTY) as 'M' and the BOM Number(STLNR) we got in Step A into BOM(STLNR) of STKO Table. We pass 'M' into BOM category(STLTY) because here we are concerned only about Material BOM.

STKO.png


Step C: Now, we need to fetch the documents from DRAD table by passing the Guid(GUIDX) we got in Step B into the Object key(OBJKY) field in DRAD table.

 

Now while programming we may face a problem. The data type of GUIDX field in STKO table is RAW(length = 16) and the data type of OBJKY in DRAD table isCHAR(Length = 50). We won't be able to apply FOR ALL ENTRIES in the select query directly.

 

A normal assignment statement won't do your job here. So, we should use this function module to do it.

This function module will convert the data from RAW type to CHAR type.

 

CALL FUNCTION'GUID_CONVERT'

          EXPORTING

            iv_guid_x16             = guid_inp

         IMPORTING

            ev_guid_c32            = guid_out

          EXCEPTIONS

            no_unicode_support_yet = 1

            parameters_error              = 2

            OTHERS                               = 3.

 

Store the new converted GUIDX which is character type in a separate table and apply FOR ALL ENTRIES with that separate table when fetching data from DRAD table.

drad2.png

We will get our desired results in this way.

WDA: Call WebDynpro application from ABAP code with parameter table type

$
0
0

In the main window of WD component define importing parameter (for example SYSTEM_ROLES with type IHTTPVAL (predefined type - string)

   Handle method.jpg

Add the parameter to the WD application

application.jpg

 

In the ABAP code (the place where the WD application is called) define table – type TIHTTPNVP, line type IHTTPNVP.

  app parameter.jpg

 

In this example information which is needed to run the WD application form ABAP is in the table IT_SYSTEM_ROLES – type ZSYSTEM_ROLES_TT, line type ZSYSTEM_ROLES

roles table.jpg

Use the following code to move the content of table ZSYSTEM_ROLES_TT to TIHTTPNVP.

table to string.jpg

 

Note: Use different separators to divide the values of the fields in one row and the content of the rows in the table. In this example for fields is used space and for rows is used comma.

Now call the application using FM WDY_EXECUTE_IN_PLACE

  FM WDY.jpg

 

In the WD component, either in WDDOINIT method of the VIEW or in WDDOINIT method of the COMPONENTCONTROLLER, you can get the application parameters using the following code:

get parameters.jpg

 

 

 

And in the end, move back the parameters to the table ZSYSTEM_ROLES_TT

 

  split.jpg

ABAP - Host Command

$
0
0

Run Host Command from ABAP code.

 

REPORT hostcommand.

 

SELECTION-SCREEN : BEGIN OF BLOCK b1 WITH FRAME TITLE text-001.

SELECTION-SCREEN PUSHBUTTON /10(10) bt_calc USER-COMMAND calc.

SELECTION-SCREEN PUSHBUTTON /10(10) bt_word USER-COMMAND word.

SELECTION-SCREEN END OF BLOCK b1.

 

INITIALIZATION.

   MOVE 'Calculator' TO bt_calc.

   MOVE 'MS Word' TO  bt_word.

 

START-OF-SELECTION.

 

END-OF-SELECTION.

 

AT SELECTION-SCREEN.

   CASE sy-ucomm.

      " Calculator

     WHEN 'CALC'.

       CALL FUNCTION 'GUI_RUN'

         EXPORTING

           command = 'CALC.EXE'.

 

       " MS Word

     WHEN 'WORD'.

       CALL FUNCTION 'GUI_RUN'

         EXPORTING

           command = 'winword.EXE'.

 

   ENDCASE.


W1.jpg

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

W2.jpg

Authorization Checks

$
0
0

Hello all,

 

   Here is the document to create authorization objects. It's all about how to customize and how to use the authorization objects at programming level.

 

Creating Authorization Fields: Go to SU20

 

a1.jpg

 

a1.jpg

 

Now, go to SU21 & select Authorization Object as shown

 

a1.jpg

 

Create Authorization Fields,

a1.jpg

 

You can check the same being added,

 

a1.jpg

 

Now, Create the Role in PFCG as shown below,

 

a1.jpg

 

a1.jpg

 

a1.jpg

 

Maintain the authorizations,

 

a1.jpg

 

Programming the authorization checks(SE38) or anywhere you want to check for the authorizations,

a1.jpg

 

Make sure of adding the roles to mind thru SU01 (done by Basis Team ),

 

a1.jpg

 

Thanks!!!

Create Label for Purchase Order Using AdobeForms

$
0
0

Requirement

Print PO label with only PO Number as a bar-code on the label. This would be used for plant to plant to stock transfer.

Create AdobeForm

 

Step 1 : Create Interface in Tcode: SFP.

 

Add parameters to the form interface import parameters.

Parameter NameTYPEType nameOptionalPassValue
/1BCDWB/DOCPARAMSTYPESFPDOCPARAMSXX
HEADERTYPEMMPUR_PRINT_EKKOXX

 

These parameters will be export parameters of the calling function module.

Activate Interface.

Interface.png

Step 2 : Create Form in Tcode : SFP.

Provide the interface name you just created above.

FormCreate.png

 

Step 3. Drag and drop your fields from Import to Context Area.

Drag Fields.png

Step 4: Go to Layout and choose the page size based on label stationery.

Currently we are using Height = 4in, Width = 6in and Orientation = Landscape.

layout.png

 

Step 5 : From the Object Library take the object you want to print on label, our requirement is to print PO number as a bar-code.

Do the binding with variable added in the context area.

Activate Form.

 

  binding.png

 

 

Configure output type

Tcode: NACE

Now we are ready to trigger the label from PO. Let’s make sure we have correct output type setup.

MM functional person can help us with this requirement.

We are using standard SAP print program to print PO.

Program : SAPFM06P

FORM routine : ADOBE_ENTRY_NEU

Output type.png

 

Configure Printer

Device Type and Printer Setup – TCode: SPAD

Label Printer should be available in SAP, with PDF device type so that we can print PDF forms.

Basis team can help us with this one.


SPAD.png

Trigger Output

In TCode : ME21N/ ME22N/ ME23N.

Create Output.

trigger output2.png

Hiding Keys in URL Parameters with ABAP

$
0
0

Hy everyone,

 

i'm waiting for a transport request to get into the test system. so i thought i'll quickly write a document about hiding key informations in urls with abap. let's assume you have a web application, where you want to display some invoice information.

 

Very often you see constructs as the following:

http(s)://domain.com/someapp/index.html?invoiceid=<BUKRS><BELNR><GJAHR>

 

With this information a user that knows a little bit about sap & sap objects sees that the key is a concatination of key fields from a table. with such kind of parameters it's pritty simple to get other content as propably previewed by the application developer, just by increasing for example <BELNR> in the key. With such kind of parameters it's pretty clear, that the user can manipulate application results.

 

as it is a good practice to mask such kind of keys, i would like to describe two pretty simple solutions to avoid such kind of parameters.

 

Option 1 - My prefered approach - are GUIID's

Usually i create a mapping table with the following structure. All fields are set as key's in se11.

mandt - guiid - <BUKRS> - <BELNR> - <GJAHR>

 

Afterwards, an this is for both options the same, i implement a little abap class with following functions:

get_guiid() - This method takes care of the generation of a guuid (solved with SAP standard classes within) - just don't try to generate own guiids by a custom alghorithm or other approaches.

get_business_key(exporting iv_guuid) - This method returns the "real" db key to a given iv_guiid. iv_guiid could be the parameter invoiceid of the url on top of this document.

get_guuid_from_key(exporting is_business_key) - This method returns the "masked" db key to use it e.g. as url parameter.

 

With this simple approach, it's quite impossible for the user to manipulate url parameters.

 

Option 2 - MD5Hash

It's pretty much the absolute same approach as option 1, but it works with MD5Hash as equivalent to the guuid in option 1. It has one advantage for me. With a given set of information e.g (<BUKRS><BELNR><GJAHR>) i always get the same MD5Hash. With this, some kind of validation would be possible. There are function modules available in SAP Systems to generate MD5Hash values (SE84 to search with *MD5* as search string - pick a fitting function module).

 

I often use Option 2 with MD5Hash values, when i develop a programm, that could have pretty heavy business impact, if it's executed without the necessary care at the selection screen where parameters and ranges are set. The programms are e.g. reports, that correct a certain information on a table entry. i haven't wrote much of these programms so far, but it happend. I kind of implement a passwort prompt in the report to avoid unwanted execution of a certain program (e.g. a correction report). In the report, there is only the MD5Hash set as constant to wich i compare the "passwort" prompt MD5Hash value. For me, this is kind of a extended check to the sap auhority & role concept, as there is sometimes that one person, who has the right to execute any programm.

 

Think about the user bapi to assign user roles (tip: always read user roles into itab, append/remove roles to assign depending on your business logic, and only after that assign user roles by bapi -> as standard behaviour is: remove all roles, assign roles -> if you forgot to read the roles in advance, existing user role assignment is lost - happend & led to a system restore . An i'm sure there are some developers using that bapi, and after some testruns there no more developers from system perspective) A similar constellation is possible, if a program is executed without the necessary care at selection screen.

 

i wish you a nice day & hope this little document inspires ABAPers to think about hiding key values in the url.

 

Regards,

Michael


Check if component exists in structure and return value (Dynamic)

$
0
0

Hello,

 

 

i would like to give a simple example how to use Runtime Type Services (RTTS) for components of a flat structure and assign the components of the structure to field symbols. This is often required if you get a structure into a method by a parameter that its type is data though you don't know the runtime type and therfore you have to work with field symbols.

 

Let us start with a simple example without looping over all structure components.

 

 

This is the sample code of a simple test report to get the concept:

* Data Declaration
DATA: go_obj       TYPE REF TO zcl_test_am01,       gv_value     TYPE string,       lv_comp_name TYPE string,       ls_bseg      TYPE bseg.
* Create Object
CREATE OBJECT go_obj.
* Check if Object is available
IF NOT go_obj IS BOUND.   WRITE 'No Instance created'.
ENDIF.
* Assign a Text to the BSEG Structure Field SGTEXT
ls_bseg-sgtxt = 'This is the value we would like to get'.
* Define the Component Name we would like to get Data from
lv_comp_name = 'SGTXT'.
* Call get_component_value
gv_value = go_obj->get_component_value(     is_struc      = ls_bseg     iv_comp_name  = lv_comp_name       ).
* Display component value on screen
write: 'Val1: ', gv_value.

Basicly all this report does is the following:

1) Create Instance of Class zcl_test_am01

2) Assign a text to the ls_bseg structure

3) Set lv_comp_name with 'SGTXT' => The component name we would like to get the value from.

4) Call of get_component_value of the class zcl_test_am01.

5) Write gv_value

 

So the interesting part is now, what does the method get_component_value:

 

Method Interface:

IS_STRUC TYPE DATA Structure Reference

IV_COMP_NAME TYPE STRING Component Name

value( EV_COMP_VALUE ) TYPE STRING Component Value

 

 

METHOD get_component_value.
* Field Symbol Definition     FIELD-SYMBOLS <fs_struc_component> TYPE any.
* Assignment of Component Name of imported structure to fieldsymbol      ASSIGN COMPONENT iv_comp_name OF STRUCTURE is_struc TO <fs_struc_component>.
* Check if field symbol is assigned ! Important - If you don't check with if is assigned you might get a 
GWA_NOT_ASSIGNED Shortdump     IF <fs_struc_component> IS ASSIGNED.
* Set ev_comp_value             ev_comp_value = <fs_struc_component>.     ELSE.
* Exception Handling      
* eg. raise exception     ENDIF.
ENDMETHOD.

This method also does not very much:

1) Declaration of Field Symbol <fs_struc_component> - Not type of bseg-sgtxt!

2) Assign Componentn (Dynamic Component Name) of Structure is_struc (type data) to fieldsymbol

3) Check if fieldsymbol is assigned if it is assigned ev_comp_value gets the value of <fs_struc_component>

 

This short example basicly shows how to get a structure component in a dynamic way. As we now, that we passed ls_bseg in the method and that the component SGTXT exists, there was no need to check if  structure component.

 

Now let's have a look at this:

We assume, that we do not now, what structure is passed into our method. Therfore we first check what components are present on the structure and check if the imported component name is present. For this, we can use the abap runtime type services. A good document for this can be found here - if its moved google with this: "Runtime Type Services (RTTS) ABAP". We would have to check the typekind of the structure (flat = typekind u = TYPEKIND_STRUCT1).

 

So lets check see the extende test report code:

* Data Declaration
DATA: go_obj       TYPE REF TO zcl_test_am01,       gv_value     TYPE string,       lv_comp_name TYPE string,       ls_bseg      TYPE bseg.
* Create Object
CREATE OBJECT go_obj.
* Check if Object is available
IF NOT go_obj IS BOUND.   WRITE 'No Instance created'.
ENDIF.
* Assign a Text to the BSEG Structure Field SGTEXT
ls_bseg-sgtxt = 'This is the value we would like to get'.
* Define the Component Name we would like to get Data from
lv_comp_name = 'SGTXT'.
* Call get_component_value
gv_value = go_obj->get_component_value(     is_struc      = ls_bseg     iv_comp_name  = lv_comp_name       ).
* Display component value on screen
write: 'Val1: ', gv_value.
* Part 2
clear gv_value.
gv_value = go_obj->get_component_value_gen(   EXPORTING     is_struc     = ls_bseg     iv_comp_name = lv_comp_name            ).
write: /'Val2:', gv_value.

Only *Part 2 is relevant

Again ls_bseg and lv_comp_name are given into the method get_component_value_gen. The code in the method has a few changes:

 

METHOD get_component_value_gen.
* Field Symbol Definition     FIELD-SYMBOLS <fs_struc_component> TYPE any.
* Data Declarations     DATA: lo_struc_type_desc TYPE REF TO cl_abap_structdescr,           ls_component       TYPE abap_compdescr.     lo_struc_type_desc ?= cl_abap_structdescr=>describe_by_data( p_data = is_struc ).     IF lo_struc_type_desc->type_kind NE lo_struc_type_desc->typekind_struct1.       WRITE: /'IS_STRUC Parameter is not a flat structure ', lo_struc_type_desc->absolute_name.     ENDIF.
* Components are present in the following instance attribute     READ TABLE lo_struc_type_desc->components INTO ls_component WITH KEY name = iv_comp_name.     IF sy-subrc <> 0.       WRITE: /'Component ', iv_comp_name, ' not present in structure ', lo_struc_type_desc->absolute_name.     ENDIF.     ASSIGN COMPONENT ls_component-name OF STRUCTURE is_struc TO <fs_struc_component>.
* Check if field symbol is assigned ! Important - If you don't check with if is assigned you might get a 
GWA_NOT_ASSIGNED Shortdump     IF <fs_struc_component> IS ASSIGNED.
* Set ev_comp_value       rv_value = <fs_struc_component>.     ELSE.
* Exception Handling
* eg. raise exception       WRITE 'Error due to <fs> assign statment'.     ENDIF.
ENDMETHOD.

The following changed:

lo_struc_type_desc ?= cl_abap_structdescr=>describe_by_data( p_data = is_struc ).

With this statement we use the RTTS to get a description of our structure. With this we are checking, that the structure is flat (if you want e.g a more generic approach you would need to call your method in a recursive way again if eg. it was a deep structure).

 

IF lo_struc_type_desc->type_kind NE lo_struc_type_desc->typekind_struct1.       WRITE: /'IS_STRUC Parameter is not a flat structure ', lo_struc_type_desc->absolute_name.
ENDIF.

The rest of the method stays the same.

With this approach it will be quite simple to implement methods that eg. loop over all components of a structure and to check some conditions and so on. Futher you can reuse such a generic method to use it broadly in your developments like kind of a service/utility class.

 

I hope you liked this document & that there are some tipps for you within it. Thanks for bookmarking or rating the document. I aprreciate all feedback & comments of you.

 

I wish you a nice day.

 

Regards,

Michael

An Alphabetic Counter

$
0
0

Introduction

 

An alphabetic counter is a counter that increments from A to B to C etc. through all letters of the alphabet. After Z the counter increases its length by one and increments from AA to AB to AC, etc. By applying this pattern recursively, an alphabetic counter may have an infinite number of values just like a numeric counter. An example with which you may be familiar is Microsoft Excel which uses an alphabetic counter to uniquely name columns.

 

Incrementing the Counter

 

An odometer is a useful model for incrementing an alphabetic counter. From right to left, each position increments from A to Z just as each position of an odometer increments from 0 to 9 (though each alphabetic position actually has blank as its starting value). When the final value is reached (Z or 9) the position rolls back to its starting value (A or 0) and the left-adjacent position is incremented. This algorithm can be applied recursively at each position along the alphabetic string.

 

Example 1

N...321
A
increments to →
N...321
B

Example 2

N...321
Z
increments to →
N...321
AA

Example 3

N...321
AZ
increments to →
N...321
BA

 

Translating this Algorithm to ABAP

The routine to implement this algorithm is recursive. It increments an alphabetic string at a specific position then, if that position has reached final character Z, increments the left-adjacent position by way of a recursive call to itself. In this demonstration, the algorithm is implemented as a method of a class, but it may also be implemented as a function module, form subroutine or other routine.


Create method increment_alpha with the following signature.


Parameter Declaration TypeParameter NameParameter Typing
Importingvalue( position )type i
Changingalphatype csequence
Exceptionnon_alpha

 

method increment_alpha.    data offset type i.    data character_tab type standard table of char1.    field-symbols <char> type char1.
*  Split changing parameter alpha into a table of single characters to facilitate substring handling    call function 'SWA_STRING_TO_TABLE'        exporting            character_string = alpha            line_size            = 1        importing            character_table  = character_tab        exceptions            others                = 0.    if position is initial.        add 1 to position.    endif.    read table character_tab assigning <char> index position.    check <char> is assigned.
*  An initial character is incremented to 'A'    if <char> is initial.        <char> = sy-abcde(1). " A
*      Reconstitute changing parameter alpha from the character table        call function 'SWA_STRING_FROM_TABLE'            exporting                character_table  = character_tab            importing                character_string = alpha            exceptions                others                = 0.        exit. " we're done    elseif <char> cn sy-abcde.        raise non_alpha.    endif. " <char>
*  Increment the alphabetic counter string    case <char>.        when sy-abcde+25(1). " Z
*      Roll Z back to A at the current position        <char> = sy-abcde(1). " A
*      Reconstitute changing parameter alpha from the character table        call function 'SWA_STRING_FROM_TABLE'            exporting                character_table  = character_tab            importing                character_string = alpha            exceptions                others                = 0.
*      Increment the left-adjacent position by recursively calling this method        increment_alpha(            exporting                position = ( position - 1 )            changing                alpha    = alpha        ).      when others. " A-Y
*        Increment the current alphabetic character          find <char> in sy-abcde ignoring case match offset offset.          add 1 to offset.          <char> = sy-abcde+offset(1).
*        Reconstitute changing parameter alpha from the character table          call function 'SWA_STRING_FROM_TABLE'              exporting                  character_table  = character_tab              importing                  character_string = alpha              exceptions                  others                = 0.    endcase. " <char>
endmethod.


The initial call to increment_alpha method passes in the whole alphabetic counter string using its complete length as position. The method then recursively increments the alphabetic counter string one character at a time along the length of the string.


data alpha_counter type string value 'ABC'. " for example
* Increment the alpha counter and assign equipment name. We extend the
* length of the alpha string by 1 place to accommodate a potential additional
* character, e.g., Z > AA.
shift alpha_counter right.
increment_alpha(    exporting        position  = numofchar( alpha_counter )    changing        alpha    = alpha_counter
).


Sorting Counter Values


To correctly sort alphabetic counter values like A, Z, AB, BA, we cannot rely on a simple character sort because AA would come before Z which is not true in the odometer model. An algorithm which calculates the sum of each alphabetic character's ASCII numeric value multiplied by its odometer position provides a reliable sort value for alphabetic counter values.

 

Example 1

N...321
A
to ASCII →
N...321
65
result →
65 x 1 = 65

Example 2

N...321
Z
to ASCII →
N...321
90
result →
90 x 1 = 90

Example 3

N...321
AB
to ASCII →
N...321
6566
result →
65 x 2 + 66 x 1 = 196

Example 4

N...321
BA
to ASCII →
N...321
6665
result →
66 x 2 + 65 x 1 = 197

 

Translating this Algorithm to ABAP


data alpha_counter type string value 'ABC'. " for example
data offset type i.
data character_at_this_position type char1.
data sort_value type i.
do strlen( alpha_counter ) times.    offset = strlen( alpha_counter ) - sy-index.    character_at_this_position = alpha_counter+offset(1).    sort_value = sort_value + ( cl_abap_conv_out_ce=>uccpi( character_at_this_position ) * sy-index ).
enddo.


When applied to a table of alphabetic counter values, each record's sort value may be used to correctly sort the table according to the odometer model.

Leading Zero disappeared on some fields in Query.

$
0
0

Reproducing the Issue

  • One query created with table EKPO.
  • Set EKPO-MATNR(Material) & EKPO-EBELP(item) as 'Output List'.
  • Example: the data in table EKPO is MATNR=000111, EBELP=001.
  • Execute query with 'SAP List Viewer' output type.
  • In output list, you can find that the data in MATNR field displayed as 111,
    but the data in field EBELP field still displayed as 001.

 

Cause

 

Field 'MATNR' uses Convers. Routine MATN1, the conv.exit MATN1 removes the
leading zeros. 'EBELP' field does not use any conversion routine.

 

You can check the corresponding field in SE11 as below:

 

1.PNG

 

2.PNG

3.PNG

 

Resolution

 

 

Define an additional field in the infoset or a local field in the query
without any conv.exit and copy the data to this field. The result will be shown
without any conversion in this field.

 

Reference Document:

SAP KBANote: 2171140 Leading Zero disappeared on some fields in Query.

Custom TAB in ML81N (Entry Sheet) Header

$
0
0

Creation of Additional Tab in ML81N Header

Step 1: Use CMOD  and create a Project .


Step 2: Click on “Enhancement Assignment” and add SRVEUSCR


Step 3: Click on “Components”


Step 4: Double Click on Table CI_ESSRDB and add your custom fields


Step 5: Double click on “Screen Exit”  0399, open its “Layout” and add the custom fields.


Step 6: Use Function Exit “EXIT_SAPLMLSR_020”  to process PBO part.

Write the code in INCLUDE ZXMLUU27


Step 7: Use Function Exit “EXIT_SAPLMLSR_021”  to process PAI part.

Write the code in INCLUDE ZXMLUU28

 

Step 8: Open ML81N and check your output.


 

Thanks

D.Satpathy

Create Custom TAB in ML81N (Entry Sheet) Line

$
0
0

Creation of Additional Tab in ML81N Line Item


Step 1: Use CMOD and create a Project .


Step 2: Click on “Enhancement Assignment” and add SRVDET


Step 3: Click on “Components”


Step 4: Double Click on Table CI_ESLLDB and add your custom fields

 

Step 5: Double click on “Screen Exit” 0299, open its “Layout” and add the custom fields.


Step 6: Use Function Exit “EXIT_SAPLMLSP_040” to process PBO part. Write the code in INCLUDE ZXMLUU23

TABLES: esll.

CLEAR: esll-zlory,esll-zexn1.

 

MOVE i_esll-zlory TO esll-zlory. MOVE i_esll-zexn1 TO esll-zexn1.

 

 

Step 7: Use Function Exit “EXIT_SAPLMLSP_041” to process PAI part. Write the code in INCLUDE ZXMLUU26

MOVE esll-zlory TO e_eslldb-zlory. MOVE esll-zexn1 TO e_eslldb-zexn1.


Step 8: Open ML81N and click on Line no 10 to check your output.

 

Thanks

D.Satpathy

Viewing all 935 articles
Browse latest View live


<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>