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

Introduction

Activating multiple Core Data Services (CDS) at once within HANA Studio can be challenging, especially when changes contain dependencies. This blog post introduces a program that solves this issue.

The Problem

HANA Studio often(always) fails to activate multiple CDS simultaneously when dependencies exist,
even though successful activation should resolve all issues.
A common example is renaming a field used across several CDS and needing to activate all objects at once.

The Solution

I created a program that forces the system to activate multiple DDLs simultaneously, despite dependencies:

  1. Automatic Retrieval: The program automatically retrieves all inactivate objects in your system, allowing easy selection. If needed, you can manually add DDLs in the selection screen.
  2. Efficient Activation: You can call the program directly from HANA Studio.

    Use the program responsibility.

*&------------------------------------------------------------------------------------------------------------------------------------------*
*& Report ZCDS_FORCE_ACTIVATION
*&------------------------------------------------------------------------------------------------------------------------------------------*
*&
*&                                                    DDL Activation Program
*&
*&      The program is designed to activate multiple DDLs simultaneously, even if there are dependencies between them.
*&      If you have made changes to several DDLs that rely on each other,
*&      The program will automatically retrieve all the inactive objects in the system and allow you to select from them.
*&      If for some reason, the DDLs do not appear, you can also add them manually in the selection screen.
*&
*&      In the next step,
*&      a screen will appear where you can choose all the DDLs you want to activate.
*&      Click on the 'V' button, and they will all be activated.
*&
*&------------------------------------------------------------------------------------------------------------------------------------------*
REPORT zcds_force_activation.

DATA : gv_ddlname  TYPE ddlname,
       gt_fieldcat TYPE  TABLE OF slis_fieldcat_alv..

TYPES: BEGIN OF ty_object,
         object   TYPE  trobjtype,
         obj_name TYPE  trobj_name,
         checkbox TYPE c,
       END OF ty_object.


gt_fieldcat = VALUE #( (  fieldname = 'OBJECT'    outputlen = 4   col_pos  = 0 seltext_m = 'Obj.' )
                       (  fieldname = 'OBJ_NAME' outputlen = 120 col_pos = 1 seltext_m = 'Object Name'  ) ).

SELECT-OPTIONS:
p_ddl_n FOR gv_ddlname.


START-OF-SELECTION.

  DATA:
    l_subrc             TYPE sy-subrc,
    lt_actrc            TYPE STANDARD TABLE OF ddmsactrc,
    lt_inactive_objects TYPE TABLE OF ty_object,
    lt_worklist         TYPE TABLE OF  e071,
    lv_logname          TYPE  text256,
    lt_ddl_names        TYPE if_dd_ddl_types=>ty_t_ddlnames,
    lt_msg              TYPE bapiret2_t.

*Get Users non-active objects
  SELECT *
    FROM dwinactiv
    WHERE uname = @SY-uname
  INTO CORRESPONDING FIELDS OF TABLE @LT_inactive_objects.


* add Objects user added manually in selection screen
  LOOP AT p_ddl_n[] INTO DATA(ls_p_ddl).
    APPEND VALUE #( object =  'DDLS' obj_name = ls_p_ddl-low ) TO lt_inactive_objects.
  ENDLOOP.

*Exampale for DDLS to activate
*No need to enter manually, the program pulls out your non-active objects and lets you choose from them.
  IF 1 = 2.
    lt_inactive_objects = VALUE #( ( object = 'DDLS' obj_name = 'ZFISF_I_CLAIM_CLAT' )
                                   ( object = 'DDLS' obj_name = 'ZFISF_B_CLAIM_CLAS' )
                                   ( object = 'DDLS' obj_name = 'ZFISF_B_CLAIM_CLAT' )
                                   ( object = 'DDLS' obj_name = 'ZFISF_I_CLAIM_CLAS' ) ).
  ENDIF.

  IF lt_inactive_objects IS NOT INITIAL.

    SORT lt_inactive_objects  BY object obj_name.
    DELETE ADJACENT DUPLICATES FROM  lt_inactive_objects  COMPARING object obj_name.

    CALL FUNCTION 'REUSE_ALV_POPUP_TO_SELECT'
      EXPORTING
        i_title              = 'Select Inactive Objectd'
        i_selection          = 'X'
        i_zebra              = 'X'
        i_checkbox_fieldname = 'CHECKBOX'
        i_tabname            = 'LT_INACTIVE_OBJECTS'
        it_fieldcat          = gt_fieldcat
      TABLES
        t_outtab             = lt_inactive_objects " Selection value table
      EXCEPTIONS
        program_error        = 1
        OTHERS               = 2.

    DELETE lt_inactive_objects WHERE checkbox IS INITIAL.
  ENDIF.


  IF lt_inactive_objects IS NOT INITIAL..

    lt_worklist = CORRESPONDING #( lt_inactive_objects ).
    CONCATENATE sy-uname sy-datum sy-uzeit INTO lv_logname.

*Sets the DDLS in active mode but there are still not really Activated
    CALL FUNCTION 'DD_WORKLIST_ACT'
      EXPORTING
        logname        = lv_logname
        inactive       = 'X'
        mode           = 'T'
      IMPORTING
        rc             = l_subrc
      TABLES
        worklist       = lt_worklist
        actrc          = lt_actrc
      EXCEPTIONS
        no_objects     = 1
        access_failure = 2
        locked         = 3
        OTHERS         = 4.
  ENDIF.


  lt_ddl_names = VALUE #( FOR line IN lt_inactive_objects WHERE ( object = 'DDLS' ) ( ddlname = line-obj_name ) ) .


  IF lt_ddl_names IS NOT INITIAL..

    TRY.
        DATA(lo_ddl_handler)  =  cl_dd_ddl_handler_factory=>create( ).

        LOOP AT lt_ddl_names INTO DATA(ls_ddl).

          lo_ddl_handler->read( EXPORTING name         = ls_ddl-ddlname
                                IMPORTING ddddlsrcv_wa = DATA(ls_ddddlsrcv_wa) ).
*     Dummy change that it will have what to activate
          lo_ddl_handler->save( EXPORTING name         = ls_ddl-ddlname
                                          put_state    = 'N'
                                          ddddlsrcv_wa = ls_ddddlsrcv_wa ).
        ENDLOOP.

*   Activate all dummy changes(But in the end, it will Activate a everything better.)
        lo_ddl_handler->mass_activate( EXPORTING names     = lt_ddl_names
                                       IMPORTING logname   = DATA(logname)
                                                 rc        = DATA(rc)
                                                 actrc_tab = DATA(actrc_tab) ). " Result of Activations

        CALL FUNCTION 'DD_WORKLIST_ACT'
          EXPORTING
            logname        = lv_logname
            mode           = 'O'
          IMPORTING
            rc             = l_subrc
          TABLES
            worklist       = lt_worklist
            actrc          = lt_actrc
          EXCEPTIONS
            no_objects     = 1
            access_failure = 2
            locked         = 3
            OTHERS         = 4.

      CATCH cx_dd_ddl_read INTO DATA(le1). " Read exception
      CATCH cx_dd_ddl_save INTO DATA(le2). " Write exception
      CATCH cx_dd_ddl_activate INTO DATA(le3). " Exception in activation
      CATCH cx_root INTO DATA(le4). " Exception in activation
    ENDTRY.

  ENDIF.
  APPEND LINES OF lt_actrc TO actrc_tab.

  lt_msg = CORRESPONDING #( actrc_tab MAPPING row = rc
                                              id = arbgb
                                              number = msgnr
                                              message_v1 = var1
                                              message_v2 = var2
                                              message_v3 = var3
                                              message_v4 = var4 ).


  MODIFY lt_msg FROM VALUE #( type = '' )  TRANSPORTING type WHERE type IS NOT INITIAL.
  MODIFY lt_msg FROM VALUE #( type = 'S' ) TRANSPORTING type WHERE row = 0 .
  MODIFY lt_msg FROM VALUE #( type = 'W' ) TRANSPORTING type WHERE row = 4.
  MODIFY lt_msg FROM VALUE #( type = 'E' ) TRANSPORTING type WHERE row = 8.
  MODIFY lt_msg FROM VALUE #( type = 'I' ) TRANSPORTING type WHERE type IS INITIAL .


  SORT lt_msg.
  DELETE ADJACENT DUPLICATES FROM lt_msg COMPARING ALL FIELDS.
  DELETE lt_msg WHERE id IS INITIAL OR number IS INITIAL.

  IF line_exists( actrc_tab[ rc = 8  ] ).
    MESSAGE i003(mdg_cds_generate) DISPLAY LIKE 'E' WITH 'Error during activation'.
  ELSEIF line_exists( actrc_tab[ rc = 4  ] ) OR
         line_exists( actrc_tab[ rc = 0  ] ) .
    MESSAGE i003(mdg_cds_generate) DISPLAY LIKE 'S' WITH 'Success'.
  ELSEIF lt_ddl_names IS INITIAL.
    MESSAGE i003(mdg_cds_generate) DISPLAY LIKE 'W' WITH 'Inactive Objects not found/Or not Selected'.

  ELSE.
    MESSAGE i003(mdg_cds_generate) DISPLAY LIKE 'W' WITH 'Activeation not detected'.
  ENDIF.


  IF lt_msg IS NOT INITIAL.
    CALL FUNCTION 'FB_MESSAGES_DISPLAY_POPUP'
      EXPORTING
        it_return = lt_msg
      EXCEPTIONS
        OTHERS    = 3.
  ENDIF.

Enjoy!

 

2 Comments
sap_cohort
Active Contributor
0 Kudos

This is a great tool.  I ran into this issue a while ago and this would have been very useful.

Thanks for the share!  

Gal_Kogan
Discoverer

Excellent solution,
thanks for sharing.

Labels in this area