Introduction
Last week I have created a blog post with some information on which function modules should be called in order to create a completely new operative project structure in SAP project system based on a standard project structure or on another operative structure (Function calls for standard project structure copy in SAP Project System).
It turns out that SAP offers another function module in the same function group of function module “CJWB_PROJECT_COPY” that allows the insertion of an entire substructure below and already existent operative WBS element. This function module is "CJWB_SUBTREE_COPY".
The function calls necessary for successfully accomplish the standard project sub-structure insertion are almost the same as the ones necessary to successfully accomplish the standard project copy. The main difference is that in the first case it is necessary to read the operative project to which the new sub-structure should be added. This is accomplished with function module "CJDW_SELECT_BASIC_DATA".
Code Samples
Just as in last week's blog post below are two sample codes for adding a standard project sub-structure. The first is a simple code for cases in which network headers are not necessary while the latter is a more complex code for cases in which network headers are necessary. The second code sample also contains some lines for manipulating WBS element data (project responsible and applicant number) for demonstration purposes.
The sample are based on the calls performed in standard transaction CJ20N (include LCNPB_MF38).
Sample 1: Simple project sub-structure without network headers
CALL FUNCTION 'CJDW_SELECT_BASIC_DATA' EXPORTING project = <-- operative project definition to which the standard project sub-structure will be added EXCEPTIONS entry_element_not_found = 1 missing_parameter = 2 project_not_found = 3 project_inact = 4 error_message = 98 OTHERS = 99. CALL FUNCTION 'CJWB_PROJECT_INIT_EXTERN_CALL' EXPORTING i_method = 'INITIALIZE' i_aktyp = 'V' i_entry_pronr = <-- operative WBS element below which the standard project sub-structure should be added EXCEPTIONS not_found = 1 OTHERS = 2. CALL FUNCTION 'CJWB_SUBTREE_COPY' EXPORTING pspnr_source = <-- top standard WBS element of the standard project sub-structure to be added pspnr_target = <-- operative WBS element below which the standard project sub-structure should be added direction = '1' type_of_element = 'S' EXCEPTIONS wrong_call = 1 OTHERS = 2. CALL FUNCTION 'CJDW_GET_NEW_NUMBERS'. CALL FUNCTION 'CJDT_GET_NEW_NUMBERS'.
Sample 2: Project sub-structure with network headers and some data manipulation
REPORT zaddsubstr. DATA: lt_cjdi TYPE TABLE OF rcj_markl. DATA: lt_rcj_kopnr TYPE TABLE OF rcj_kopnr. DATA: ls_cjdi LIKE LINE OF lt_cjdi. DATA: ls_proj LIKE proj. DATA: ls_prps LIKE prps. DATA: ls_tc10 LIKE tc10. DATA: ls_tcn41 LIKE tcn41. DATA: l_pspid TYPE ps_pspid. DATA: l_psphi TYPE ps_psphi. DATA: l_pspnr_top TYPE prps-pspnr. DATA: l_old_tcode LIKE sy-tcode. DATA: l_ntw_found TYPE c LENGTH 1. CONSTANTS: c_tcode TYPE tcode VALUE 'CJ20N'. CONSTANTS: c_vorgabe TYPE caufvd-plart VALUE '1'. CONSTANTS: c_direction TYPE c LENGTH 1 VALUE '1'. CONSTANTS: c_meth_init TYPE fcode VALUE 'INITIALIZE'. CONSTANTS: c_type_elem TYPE selkz VALUE 'S'. CONSTANTS: c_aplid TYPE c LENGTH 1 VALUE 'G'. CONSTANTS: c_change TYPE c LENGTH 1 VALUE 'V'. CONSTANTS: c_asterisk TYPE c LENGTH 1 VALUE '*'. CONSTANTS: c_plus TYPE c LENGTH 1 VALUE '+'. CONSTANTS: c_meth_tmex TYPE fcode VALUE 'TMEX'. CONSTANTS: c_vernr TYPE ps_vernr VALUE 99. CONSTANTS: c_astnr TYPE ps_astnr VALUE 99. * Source and Target Project Definitions * Here the source is the standard WBS element to be added to the existing structure and the target is the operative WBS element below which a new sub structure should be added SELECTION-SCREEN BEGIN OF BLOCK a WITH FRAME. PARAMETERS: p_spspnr TYPE prpss-pspnr OBLIGATORY. PARAMETERS: p_tpspnr TYPE prps-pspnr OBLIGATORY. SELECTION-SCREEN END OF BLOCK a. * Select data from target WBS Element SELECT SINGLE psphi INTO l_psphi FROM prps WHERE pspnr = p_tpspnr. SELECT SINGLE pspid FROM proj INTO l_pspid WHERE pspnr = l_psphi. CALL FUNCTION 'CJDW_SELECT_BASIC_DATA' EXPORTING enqueue = abap_true project = l_pspid EXCEPTIONS entry_element_not_found = 1 missing_parameter = 2 project_not_found = 3 project_inact = 4 error_message = 98 OTHERS = 99. CALL FUNCTION 'CJWB_PROJECT_INIT_EXTERN_CALL' EXPORTING i_method = c_meth_init i_aktyp = c_change i_entry_pronr = p_tpspnr EXCEPTIONS not_found = 1 OTHERS = 2. CALL FUNCTION 'CJWB_SUBTREE_COPY' EXPORTING pspnr_source = p_spspnr pspnr_target = p_tpspnr direction = c_direction type_of_element = c_type_elem IMPORTING ex_first_element = l_pspnr_top TABLES newnumbers = lt_rcj_kopnr dialtab_exp = lt_cjdi EXCEPTIONS wrong_call = 1 OTHERS = 2. * Only for demonstration purposes in lines from 83 to 109 the person responsible and the applicant number are changed in each new WBS element of the structure. LOOP AT lt_cjdi INTO ls_cjdi. CLEAR ls_prps. CALL FUNCTION 'CJDW_PRPS_GET' EXPORTING index = ls_cjdi-index IMPORTING e_prps = ls_prps EXCEPTIONS cancel = 1 not_found = 2 OTHERS = 3. IF sy-subrc = 0. IF ls_prps-objnr(2) = 'TM'. ls_prps-vernr = c_vernr. ls_prps-astnr = c_astnr. CALL FUNCTION 'CJDW_PRPS_MODIFY' EXPORTING beakz = c_change index = ls_cjdi-index i_prps = ls_prps EXCEPTIONS not_found = 1 posnr = 2 OTHERS = 3. ENDIF. ENDIF. ENDLOOP. * Prepare call of 'CJDT_CREATE_ACT_FOR_NEW_PRJ' CALL FUNCTION 'CJDW_GLOBAL_VALUES' IMPORTING v_proj = ls_proj. CALL FUNCTION 'CO_TA_TCN41_READ' EXPORTING plnaw = 'N' profidnetz = ls_proj-vprof IMPORTING tcn41_exp = ls_tcn41 EXCEPTIONS not_found = 01. * The two lines of code below might also look strange at first, but they are also necessary because in includes LCJTRFJ8 and LCJTRFI2 * somewhere inside function 'CJTR_CALL_FROM_EXTERN' the system selects some default values from some tables based on the transaction code. l_old_tcode = sy-tcode. sy-tcode = c_tcode. CALL FUNCTION 'CJTR_CALL_FROM_EXTERN' EXPORTING aplid = c_aplid fcode_imp = space proj_imp = ls_proj trtyp_imp = c_change top_imp = 1 TABLES cjdi_imp = lt_cjdi EXCEPTIONS no_existing_psp = 1 no_pprofil = 2 OTHERS = 3. SELECT SINGLE * INTO ls_tc10 FROM tc10 WHERE tcode = c_tcode. * Again a strange but necessary line of code. In include LCOKOF1S somewhere inside function 'CJDT_CREATE_ACT_FOR_NEW_PRJ' the system * selects the default value for the order category from table t490 based on the transaction code. It would also be a possibility to * create a new entry in the aforementioned table with the transaction code in context (i.e. tcode of the current program) sy-tcode = c_tcode. * Function for adding network objects to the previously created project structure CALL FUNCTION 'CJDT_CREATE_ACT_FOR_NEW_PRJ' EXPORTING tc10wa = ls_tc10 tcn41_imp = ls_tcn41 proj_imp = ls_proj sched_param = space flg_new_prj = space EXCEPTIONS no_entries = 1 OTHERS = 2. IF sy-subrc = 0. l_ntw_found = abap_true. CALL FUNCTION 'CO_IT_SET_FLG_ITAB_NEW'. PERFORM dtab_create_complete(saplcjtr). ENDIF. CALL FUNCTION 'CNEV_05_COPY_EVOP' EXPORTING i_kokrs = ls_proj-vkokr. CALL FUNCTION 'CO_BT_PROJKN_DET' EXPORTING projn_pa = space projn_tv = space. CALL FUNCTION 'NW_EX_SET_NETSTUFE_MAX_PROJECT' EXPORTING i_profidproj = ls_proj-profl EXCEPTIONS project_profile_does_not_exist = 1 network_profile_does_not_exist = 2 OTHERS = 3. * Call network scheduling if network exists IF l_ntw_found = abap_true. CALL FUNCTION 'CJWB_PROJECT_INIT_EXTERN_CALL' EXPORTING i_method = c_meth_tmex i_object = c_plus i_view_object = c_asterisk i_sub_view = space i_aktyp = c_change i_pronr = l_pspnr_top EXCEPTIONS not_found = 1 OTHERS = 2. ENDIF. * Check if any required field is still empty. This function module is optional could result in disruptive pop-ups CALL FUNCTION 'CJWB_CHECK_BEFORE_COMMIT' EXCEPTIONS cancel = 1. * Prepare commit of WBS element dates table (PRTE) CALL FUNCTION 'CJTR_POST_DATES' EXCEPTIONS sched_wrong = 1 check_top_down = 2 OTHERS = 3. * Prepare commit of network data if network exists IF l_ntw_found = abap_true. CALL FUNCTION 'CO_BT_PROJKN_DET' EXPORTING projn_pa = c_vorgabe projn_tv = space. CALL FUNCTION 'CO_ZV_ORDER_POST' EXPORTING commit_flag = abap_false ext_flg = abap_true trans_typ = c_change no_dialog = abap_true EXCEPTIONS update_reject = 1 budget_reject = 2 OTHERS = 3. ENDIF. * Substitute internal numbers CALL FUNCTION 'CJDW_GET_NEW_NUMBERS'. CALL FUNCTION 'CJDT_GET_NEW_NUMBERS'. COMMIT WORK. sy-tcode = l_old_tcode. END-OF-SELECTION.