Homelab, Linux, JS & ABAP (~˘▾˘)~
 

[ABAP] Display CL_BAL_LOGOBJ output as ALV in a splitcontainer

When developing a report that should also write logs (SLG1), I normaly use the class CL_BAL_LOGOBJ as described here. When using method lo_log->display( ) it displays the result in a popup. If you want to display the log as ALV some more logic is neede.

DATA ls_display_profile TYPE bal_s_prof.

TRY.
    DATA(lo_log) = NEW cl_bal_logobj(
      i_log_object        = 'Z_MY_LOG'
      i_default_subobject = 'GENERAL' ).

    lo_log->add_statustext( i_statustext = 'Processing started' ).

    lo_log->add_errortext( i_errortext = 'An error occurred during processing' ).

    CALL FUNCTION 'BAL_DSP_PROFILE_NO_TREE_GET'
      IMPORTING
        e_s_display_profile = ls_display_profile.

    ls_display_profile-use_grid = abap_true.

    lo_log->display( i_disp_profile = ls_display_profile ).

  CATCH cx_bal_exception INTO DATA(lx_bal).
    MESSAGE lx_bal->get_text( ) TYPE 'I'.
ENDTRY.

In my case, I wanted to display the log next to the actual output of a report, so that I have my data result on the left side, and the application log on right side.

*--------------------------------------------------------------------*
* Create Split Container
*--------------------------------------------------------------------*

    " Create a splitter on default_screen
    DATA(o_splitter_main) = NEW cl_gui_splitter_container( parent                  = cl_gui_container=>default_screen
                                                           no_autodef_progid_dynnr = abap_true
                                                           rows                    = 1
                                                           columns                 = 2 ).

    " Width of left splitter in %
    o_splitter_main->set_column_width( id = 1 width = 75 ).

    " Get the ref from the left and right split containers
    DATA(o_container_1) = o_splitter_main->get_container( row = 1 column = 1 ).
    DATA(o_container_2) = o_splitter_main->get_container( row = 1 column = 2 ).

*--------------------------------------------------------------------*
* 1 ALV Output
*--------------------------------------------------------------------*

    TRY.
        cl_salv_table=>factory( EXPORTING r_container  = o_container_1
                                IMPORTING r_salv_table = DATA(o_salv)
                                CHANGING  t_table      = lt_sflight).
        o_salv->display( ).

      CATCH cx_salv_msg.
      CATCH cx_salv_not_found.
    ENDTRY.

*--------------------------------------------------------------------*
* 2 BAL Log
*--------------------------------------------------------------------*

    DATA ls_display_profile TYPE bal_s_prof.
    DATA lv_control_handle  TYPE balcnthndl.

    DATA(lt_log_handles) = VALUE bal_t_logh( ( mo_log->if_bal_logger~mv_loghandle ) ).

    CALL FUNCTION 'BAL_DSP_PROFILE_NO_TREE_GET'
      IMPORTING
        e_s_display_profile = ls_display_profile.

    ls_display_profile-use_grid = abap_true.

    " Increase the width of the message text column
    LOOP AT ls_display_profile-mess_fcat ASSIGNING FIELD-SYMBOL(<ls_fcat>)
         WHERE ref_table = 'BAL_S_SHOW'
           AND ref_field = 'T_MSG'.
      <ls_fcat>-outputlen = 200.
    ENDLOOP.

    CALL FUNCTION 'BAL_CNTL_CREATE'
      EXPORTING
        i_container          = o_container_2
        i_s_display_profile  = ls_display_profile
        i_t_log_handle       = lt_log_handles
      IMPORTING
        e_control_handle     = lv_control_handle
      EXCEPTIONS
        profile_inconsistent = 1
        internal_error       = 2
        OTHERS               = 3.

  ENDMETHOD.

*--------------------------------------------------------------------*
*  Force output
*--------------------------------------------------------------------*
    WRITE: space.

I really like the result

[ABAP] ALV – Enable Excel Export

The “Excel export” functionality can easily be enabled using get_functions( )->set_all( abap_true )

SELECT * FROM sflight INTO TABLE @DATA(flights) UP TO 100 ROWS.

TRY.
    cl_salv_table=>factory( IMPORTING r_salv_table = DATA(lo_salv)
                            CHANGING  t_table      = flights ).

    lo_salv->get_functions( )->set_all( abap_true ).
    lo_salv->get_columns( )->set_optimize( abap_true ).
    lo_salv->get_display_settings( )->set_list_header( 'Flights' ).
    lo_salv->get_display_settings( )->set_striped_pattern( abap_true ).
    lo_salv->get_selections( )->set_selection_mode( if_salv_c_selection_mode=>row_column ).

    lo_salv->display( ).

  CATCH cx_root INTO DATA(e_txt).
    WRITE: / e_txt->get_text( ).
ENDTRY.

[ABAP] Debugging as other user

Imagine the following situation:

USER_A: Allowed to run a specific report, but not allowed to debug
USER_B: Is allowed to debug

In such a case, you can do the following:

  • USER_B: Sets external breakpoint for USER_A
  • USER_A: Enters the following in the command field: /hext user=USER_B
  • USER_A: Starts his report
  • USER_B: Debugger will be opened

If you check SY-UNAME in the debugger, it will have the value USER_A

[ABAP] ALV icon

Demo program: SALV_DEMO_TABLE_COLUMNS

TYPES: BEGIN OF ty_log,
         icon TYPE icon-id,
       END OF ty_log.

DATA lt_log TYPE TABLE OF ty_log.

lt_log = VALUE #( ( icon = icon_okay    )
                  ( icon = icon_cancel  ) ).

TRY.
    cl_salv_table=>factory( IMPORTING r_salv_table = DATA(alv_table)
                            CHANGING  t_table      = lt_log ).

    alv_table->display( ).

  CATCH cx_salv_msg.
ENDTRY.

[ABAP] Get MOLGA for PERNR

" Option 1
TRY.
    cl_hrpa_masterdata_factory=>get_read_molga( IMPORTING read_molga = DATA(lr_molga) ).
    DATA(molga) = lr_molga->read_molga_by_pernr( pernr ).
  CATCH cx_hrpa_violated_assertion.
ENDTRY.

" Option 2
TRY.
    DATA(employee_api) = cl_hcmfab_employee_api=>get_instance( ).
    DATA(molga)        = employee_api->get_molga( pernr ).
  CATCH cx_hcmfab_common.
ENDTRY.

[ABAP] xstring to binary (RAW)

* Option 1
  DATA lt_data TYPE STANDARD TABLE OF x255.
  CALL FUNCTION 'SCMS_XSTRING_TO_BINARY'
    EXPORTING
      buffer     = lv_xstring
    TABLES
      binary_tab = lt_data.

* Option 2
  cl_scp_change_db=>xstr_to_xtab( EXPORTING im_xstring = lv_xstring
                                  IMPORTING ex_xtab    = DATA(lt_data) ).

* Option 3
  DATA(lt_data) = cl_bcs_convert=>xstring_to_solix( lv_xstring ).

[ABAP] Read E-Mail-Template

Addition to https://nocin.eu/abap-e-mail-templates-in-s-4hana/

I had to create an E-Mail template where I did not need a CDS view or any variable at all. I simply needed the defined mail template without any rendering of class cl_smtg_email_api.
Solution: Reading the plain mail template can be achieved using class cl_smtg_email_template and method get_tmpl_cont:

DATA(ls_mail_content) = cl_smtg_email_template=>get( p_mailtx )->get_tmpl_cont( iv_langu = 'D' ).

Full sample:

 PARAMETERS: p_mailtx TYPE smtg_tmpl_id OBLIGATORY.
   
 TRY.
        " get mail template
        DATA(ls_mail_content) = cl_smtg_email_template=>get( p_mailtx )->get_tmpl_cont( iv_langu = 'D' ).

        " optional: dynamic manipulation of html email body

        " create mail document
        DATA(lo_mail_document) = cl_document_bcs=>create_document( i_type    = 'HTM'
                                                                   i_subject = conv #( ls_mail_content-subject )
                                                                   i_text    = cl_bcs_convert=>string_to_soli( ls_mail_content-body_html ) ).

        " create Sender & Receiver
        DATA(lo_sender)    = cl_cam_address_bcs=>create_internet_address( i_address_string = 'noreply@example.com'
                                                                          i_address_name   = 'Test' ).

        DATA(lo_recipient) = cl_cam_address_bcs=>create_internet_address( i_address_string = 'max.mustermann@example.com').

        " create Business Communication Service
        DATA(lo_bcs) = cl_bcs=>create_persistent( ).
        lo_bcs->set_document( lo_mail_document ).
        lo_bcs->set_sender( lo_sender ).
        lo_bcs->add_recipient( lo_recipient ).
        lo_bcs->send( ).
        COMMIT WORK.

      CATCH cx_smtg_email_common INTO DATA(ls_cx).
        DATA(lv_message) = ls_cx->get_text( ).
        MESSAGE e899(id) WITH 'Unable to send message:'(004) lv_message.
    ENDTRY.