Archive for August 16, 2011

ALV Grid in Background (CL_GUI_ALV_GRID)

At times it may be required to run ALV using class CL_GUI_ALV_GRID in the background mode. ALV grid object reference developed using CL_GUI_ALV_GRID needs a custom screen and custom container as “Parent Object”.

If ALV is scheduled as a background job either from SM36 or from program menu then it generates a short dump.

As a workaround, use below logic while initializing the ALV Grid and Container Object in PBO of custom screen.

1. Necessary data declaration for object reference

CONSTANTS:
      c_ccontainer       TYPE scrfname VALUE 'CCONTAINER'.
DATA: g_ccontainer       TYPE REF TO cl_gui_custom_container,
      g_grid             TYPE REF TO cl_gui_alv_grid.

2. Code in PBO for Initialization of Object

Check whether user is working in Offline mode using static method CL_GUI_ALV_GRID=>Offline(). If yes then do not initialize container object. If No then initialize both container and ALV grid instance for GUI.

 IF g_ccontainer IS INITIAL.
     IF cl_gui_alv_grid=>offline( ) IS INITIAL.
       CREATE OBJECT g_ccontainer
         EXPORTING
           container_name              = c_ccontainer
           repid                       = sy-repid
           dynnr                       = sy-dynnr
         EXCEPTIONS
           cntl_error                  = 1
           cntl_system_error           = 2
           create_error                = 3
           lifetime_error              = 4
           lifetime_dynpro_dynpro_link = 5
           OTHERS                      = 6.
       IF sy-subrc <> 0.
         MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
                    WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
       ENDIF.

       CREATE OBJECT g_grid
         EXPORTING
           i_parent          = g_ccontainer
         EXCEPTIONS
           error_cntl_create = 1
           error_cntl_init   = 2
           error_cntl_link   = 3
           error_dp_create   = 4
           OTHERS            = 5.
       IF sy-subrc <> 0.
         MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
                    WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
       ENDIF.
     ELSE.
       CREATE OBJECT g_grid
         EXPORTING
           i_parent          = g_ccontainer
         EXCEPTIONS
           error_cntl_create = 1
           error_cntl_init   = 2
           error_cntl_link   = 3
           error_dp_create   = 4
           OTHERS            = 5.
       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.
 ELSE.
  CALL METHOD g_grid->refresh_table_display
   EXPORTING
    i_soft_refresh = c_true.
 ENDIF.

Once the above changes would be done then the ALV grid would be displayed as ALV List (not as grid) in background mode.

DZoneDeliciousLinkedInRedditTechnorati FavoritesStumbleUponShare

Rejection in Purchase Requisition

Purchase requisition can be rejected using transaction ME54N which updates processing state of requisition (EBAN-BANPR) to value 08. There is no BAPI available which can be used to update processing state of purchase requisition.

To handle the rejection programmatically, function module ME_UPDATE_REQUISITION can be used to update the same.

Usage for the same is given below.

DATA: wl_xeban  TYPE ueban,
      wl_yeban  TYPE ueban,
      wl_eban   TYPE eban,
      li_xeban  TYPE STANDARD TABLE OF ueban,
      li_xebkn  TYPE STANDARD TABLE OF uebkn,
      li_yeban  TYPE STANDARD TABLE OF ueban,
      li_yebkn  TYPE STANDARD TABLE OF uebkn,
      li_eban   TYPE STANDARD TABLE OF eban.

SELECT * FROM eban INTO TABLE li_eban
     WHERE banfn EQ im_requisition.
   IF sy-subrc IS INITIAL.
     CLEAR wl_eban.
     LOOP AT li_eban INTO wl_eban
         WHERE loekz IS INITIAL.
       wl_yeban          = wl_eban.
       APPEND wl_yeban TO li_yeban.

       wl_xeban          = wl_eban.
       wl_xeban-banpr = c_state_rej.
       wl_xeban-kz      = c_ind_upd.
       APPEND wl_xeban TO li_xeban.
       CLEAR: wl_eban, wl_xeban, wl_yeban.
     ENDLOOP.
     IF li_xeban[] IS NOT INITIAL AND
        li_yeban[] IS NOT INITIAL.
       CALL FUNCTION 'ME_UPDATE_REQUISITION'
         TABLES
           xeban = li_xeban
           xebkn = li_xebkn
           yeban = li_yeban
           yebkn = li_yebkn.
    ENDIF.
 ENDIF.
DZoneDeliciousLinkedInRedditTechnorati FavoritesStumbleUponShare

Hotspot in ALV Grid (Object Oriented ALV)

1. Declaration of necessary objects

Declare Objects for Receiver Class and ALV Grid (CL_GUI_ALV_GRID) in the top include of the ALV report. Implementation for receiver has to be deferred because receiver class definition is not available before top include (considering top include as first include for program).

CLASS gcl_event_receiver DEFINITION DEFERRED.

DATA: g_grid             TYPE REF TO cl_gui_alv_grid,
      g_receiver         TYPE REF TO gcl_event_receiver.

2. Activate Hotspot in field catalog

Hotspot property is to be set in the field catalog for the ALV Grid (CL_GUI_ALV_GRID). After this once ALV grid is displayed then the field with hotspot would have an underline beneath just similar to a hyperlink.

DATA: ls_fieldcat       TYPE lvc_s_fcat.
CLEAR ls_fieldcat.
   ls_fieldcat-row_pos   = 1.
   ls_fieldcat-col_pos   = 2.
   ls_fieldcat-fieldname = 'BANFN'.
   ls_fieldcat-tooltip   = c_true.
   ls_fieldcat-col_opt   = c_true.
   ls_fieldcat-hotspot   = c_true.
   ls_fieldcat-scrtext_m = 'Requisition'(006).
   APPEND ls_fieldcat TO i_fieldcat.

3. Define Event Handler Class

Define handler class for event hotspot_click of class CL_GUI_ALV_GRID. Instance of the handler class would be registered with the instance of ALV grid class later.

Row ID, Column ID and Row number are passed as event parameters when the hotspot click event is triggered to identify on which row hotspot event is fired. Once the row number is obtained the necessary action can be taken.

*--------------------------------------------------------------------*
 *       CLASS LCL_EVENT_RECEIVER DEFINITION
 *-------------------------------------------------------------------*
 *       Class for Event Handler                                     *
 *-------------------------------------------------------------------*
CLASS gcl_event_receiver DEFINITION.
   PUBLIC SECTION.

   METHODS handle_hotspot_click
         FOR EVENT hotspot_click OF cl_gui_alv_grid
             IMPORTING e_row_id
                       e_column_id
                       es_row_no.
 ENDCLASS.                    "gcl_event_receiver DEFINITION

4. Implement Event Handler Method

Handler class defined the handler method which would be executed once the event is fired by user command. The action to be performed inside handler method is to be decided. Usually this is call to some SAP transaction.

*-------------------------------------------------------------------*
*       CLASS gcl_event_receiver IMPLEMENTATION
*-------------------------------------------------------------------*
*       Class for Event Receiver                                    *
*-------------------------------------------------------------------*
 CLASS gcl_event_receiver IMPLEMENTATION.

   METHOD handle_hotspot_click.
     PERFORM f_event_hotspot_click  USING e_row_id
                                          e_column_id
                                          es_row_no.
   ENDMETHOD.                    "hotspot_click
 ENDCLASS.                    "gcl_event_receiver IMPLEMENTATION

 *&-----------------------------------------------------------------*
 *&      Form  F_EVENT_HOTSPOT_CLICK
 *&-----------------------------------------------------------------*
 *       Handle Hot-spot Click
 *------------------------------------------------------------------*
 *      -->FP_ROW     Row ID
 *      -->FP_COLUMN  Column ID
 *------------------------------------------------------------------*
 FORM f_event_hotspot_click  USING fp_row_id     TYPE lvc_s_row
                                   fp_column_id  TYPE lvc_s_col
                                   fp_row_no     TYPE lvc_s_roid.
   DATA: wl_output  TYPE ty_output.
   CLEAR wl_output.
   READ TABLE i_output INTO wl_output
                       INDEX fp_row_no-row_id.
   IF sy-subrc IS INITIAL.
     CASE fp_column_id.
       WHEN 'BANFN'.
         SET PARAMETER ID 'BAN' FIELD wl_output-banfn.
         CALL TRANSACTION 'ME53N' AND SKIP FIRST SCREEN.
       WHEN OTHERS.
     ENDCASE.
   ENDIF.
 ENDFORM.                    " EVENT_HOTSPOT_CLICK

5. Register Hotspot Event handler with the instance of ALV Grid

Register hotspot_click event with the instance of ALV grid. This is to be done in the PBO of the screen having ALV Grid. All the registered events are usually monitored. Once this is done the calls are routed to the handler method incase of an event.

 SET HANDLER g_receiver->handle_hotspot_click
   FOR g_grid.

The above ALV Snippets makes use of Object oriented ALV. Only relevant details have been added to increase clarity about the HotSpot_Click event of CL_GUI_ALV_GRID class. Once ALV is displayed hotspot would be available on field and after click navigation would be possible to requisition display transaction ME53N.

DZoneDeliciousLinkedInRedditTechnorati FavoritesStumbleUponShare

Remove 5000 Entries Restriction from F4IF_INT_TABLE_VALUE_REQUEST

When using function module F4IF_INT_TABLE_VALUE_REQUEST to generate F4 search help from internal table, by default there is restriction of 5000 entries in the output.

To remove the restriction, below actions are to be taken to remove such restriction.

1. Pass callback program name and callback routine name during the function call.

<br />
CALL FUNCTION 'F4IF_INT_TABLE_VALUE_REQUEST'<br />
         EXPORTING<br />
           retfield         = 'ICNUM'<br />
           dynpprog         = sy-repid<br />
           dynpnr           = sy-dynnr<br />
           dynprofield      = 'WG_CTRLITAB-PRIAPPCNUM'<br />
           stepl            = g_stepl<br />
           value_org        = 'S'<br />
           callback_program = sy-repid            &quot; Callback Program<br />
           callback_form    = 'F_F4CALLBACK'      &quot; Callback Routine<br />
         TABLES<br />
           value_tab        = i_lookupcnum<br />
           return_tab       = i_returntab<br />
         EXCEPTIONS<br />
           parameter_error  = 1<br />
           no_values_found  = 2<br />
           OTHERS           = 3.<br />

2. Write code in the callback subroutine to pass the parameters to remove fields count restriction. It would be legible to pass a Dialog screen for Filtering Records before hand similar to Dialog Option in Global Search help.

<br />
*&amp;--------------------------------------------------------------------*<br />
*&amp;      Form  f4callback<br />
*&amp;--------------------------------------------------------------------*<br />
*       Call Back routine<br />
*---------------------------------------------------------------------*<br />
*      --&gt;RECORD_TAB   Record Type<br />
*      --&gt;SHLP         Search Help<br />
*      --&gt;CALLCONTROL  Call Control<br />
*---------------------------------------------------------------------*<br />
FORM f_f4callback<br />
 TABLES   record_tab  STRUCTURE seahlpres<br />
 CHANGING shlp        TYPE      shlp_descr<br />
 callcontrol          LIKE      ddshf4ctrl.</p>
<p>shlp-intdescr-dialogtype = C'. &quot; This would filter dialog<br />
callcontrol-no_maxdisp   = ''. &quot; Remove upper limit</p>
<p>ENDFORM.           &quot;f4callback<br />
DZoneDeliciousLinkedInRedditTechnorati FavoritesStumbleUponShare

Terminating events for Asynchronous Task in Workflow

Terminating events for Asynchronous Task in Workflow

Terminating events are the ones which have the ability to complete a task. SAP recommends that each asynchronous task should have atleast one terminating event. Synchronous task however may or may not have terminating events.

Asynchronous Task can be terminated if

1. The Registered terminating event occurs

2. Recipient executes the work item/ task.

Terminating events can be maintained for a task on the Terminating events tab page.

Important Points before using terminating events:

1. Terminating events are always refers to an object for which event should occur. If the object is not linked properly at runtime then event, even if triggered, would not be able to find any legible receiver.

This makes sense because if the binding of object reference, for which terminating event is registered, is not done properly then it would not be possible for runtime to find which task instance is to be terminated out of thousands of similar type during runtime.

2. Task Container Element _WI_Object_ID is should contain the reference of the object for which terminating event should be raised/ handled.

3. Event Instance linkage is established at runtime by SAP in this case.

4. When terminating event is not able to work in your development then you can have a workaround of using wait steps for terminating events in parallel branches of a fork along with asynchronous task. If the wait branch completes in fork because of event then the asynchronous task would be rendered logically deleted.

What does Instance linkage look for at runtime?

As a thumb rule, instance linkages look for below information before linking event instance and receiver instance.

1. Event Type -> Receiver would define which event types it is looking for.

- Receiver could be a workflow or a task or a wait step inside workflow

- Receiver could trigger or terminate or complete its state with event.

2. Object Type -> Receiver has to define what is the object type to which event belongs

3. Object Key -> This is the runtime object key or the object instance key for which event instance would be listened at runtime.

If the above points are ensured during development then instance linkage would work.

DZoneDeliciousLinkedInRedditTechnorati FavoritesStumbleUponShare