Creating an operative project structure in SAP project system based on a standard project structure or on another operative structure using BAPIs might be a very difficult task. The reason for that is that before the relevant BAPI for saving the new operative project structure could be called it would be necessary to select from the template project structure every single possible project object and sometimes there might be many. Among possible project objects we could list project definitions, WBS elements, network headers, network activities, network activity elements, milestones, material components, PS texts, relationships, etc.

     Luckily for us SAP comes with two function modules that when called in the correct order and together with some other function modules do the complex work with possibly much less lines of code. The functions are “CJWB_PROJECT_COPY” and “CJDT_CREATE_ACT_FOR_NEW_PRJ”.

     The first of the function modules is in charge of creating project definitions, WBS elements and other objects related to WBS elements (e.g. PS texts and WBS element milestones). The second function module is in charge of attaching standard network headers and their dependents objects (e.g. network activities, network activity elements, milestones, material components, etc.) to the objects previously generated by function module “CJWB_PROJECT_COPY”.

     Among the function modules other than the ones already mentioned that also have to be called in order to successfully accomplish the standard project copy the most important are “CJDW_GET_NEW_NUMBERS” and “CJDT_GET_NEW_NUMBERS”. These function modules are in charge of replacing temporary internal numbers by correct internal numbers that will be updated to the database (e.g. OBJNR numbers).

Code Samples

     Below are two sample codes for copying standard project structure. The first is a simple code for cases in which network headers are not necessary while the latter is a slightly 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 transactions CJ20N and CJ2B (includes LCNPB_MF4T, LCNPB_MF55 and LCJTRF3B).

Sample 1: Simple project structure without network headers

   sy-ucomm = 'GEN1'.    CALL FUNCTION 'CJWB_PROJECT_COPY'      EXPORTING        call_from                                       = 'P'        standard_wbs_to_be_copied  = 

Sample 2: Project structure with network headers and some data manipulation

 REPORT zstdprojcopy. DATA: lt_cjdi          TYPE TABLE OF rcj_markl. DATA: ls_cjdi          LIKE LINE OF lt_cjdi. DATA: ls_proj          LIKE proj. DATA: ls_prps          LIKE prps. DATA: l_vsnmr          LIKE vskopf-vsnmr. DATA: ls_tc10          LIKE tc10. DATA: ls_tcn41         LIKE tcn41. DATA: l_old_ucomm      LIKE sy-ucomm. DATA: l_old_tcode      LIKE sy-tcode. DATA: l_start_termin   TYPE ps_plfaz. DATA: l_end_termin     TYPE ps_plsez. DATA: l_ntw_found      TYPE c LENGTH 1. CONSTANTS: c_vorgabe   TYPE caufvd-plart VALUE '1'. 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_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 SELECTION-SCREEN BEGIN OF BLOCK a WITH FRAME. PARAMETERS: p_sproj TYPE projs-pspid OBLIGATORY. PARAMETERS: p_tproj TYPE proj-pspid OBLIGATORY. SELECTION-SCREEN END OF BLOCK a. * Target project start and end dates SELECTION-SCREEN BEGIN OF BLOCK b WITH FRAME. PARAMETERS: p_plfaz TYPE ps_plfaz. PARAMETERS: p_plsez TYPE ps_plsez. SELECTION-SCREEN END OF BLOCK b. START-OF-SELECTION.    IF p_plfaz IS INITIAL.      l_start_termin = sy-datum.    ELSE.      l_start_termin = p_plfaz.    ENDIF.    IF p_plsez IS INITIAL.      l_end_termin = sy-datum.    ELSE.      l_end_termin = p_plsez.    ENDIF. * The two lines of code below might look strange at first, but they are necessary because in include FCJWBI00_OK_CODE_PAI somewhere * inside function 'CJWB_PROJECT_COPY' the system checks the sy-ucomm. If it is empty the process is aborted and only the project * definition is created. 'GEN1' is the same ucomm used in the copying process of the project builder (CJ20N)    l_old_ucomm = sy-ucomm.    sy-ucomm = 'GEN1'.    CALL FUNCTION 'CJWB_PROJECT_COPY'      EXPORTING        call_from                  = 'P'        standard_wbs_to_be_copied  = p_sproj        start_termin               = l_start_termin        end_termin                 = l_end_termin        no_dialog                  = abap_true        replace_string             = p_tproj      IMPORTING        project_workarea           = ls_proj        vsnmr_copy                 = l_vsnmr      EXCEPTIONS        existing_project           = 1        existing_project_in_paging = 2        wrong_call                 = 3        wbs_for_copy_not_found     = 4        error_pspid_generate       = 5        no_copy                    = 6        error                      = 7        OTHERS                     = 8. * Just for demonstration purposes in lines from 79 to 98 the person responsible and the applicant number are changed in the project definition. * Of course this could also be accomplished by substitution rules or BAdIs...    ls_proj-vernr = c_vernr.    ls_proj-astnr = c_astnr.    CALL FUNCTION 'CJDW_PROJ_MODIFY'      EXPORTING        i_proj        = ls_proj      EXCEPTIONS        beakz         = 1        pspnr         = 2        error_message = 98        OTHERS        = 99.    CALL FUNCTION 'CJDW_GET_TREE'      EXPORTING        levels    = 99        x_outline = space      TABLES        elements  = lt_cjdi      EXCEPTIONS        not_found = 1        OTHERS    = 2. * Also for demonstration purposes in lines from 102 to 126 the person responsible and the applicant number are changed in each WBS element of the structure. * This could also be accomplished by substitution rules or BAdIs...    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.        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.    ENDLOOP. * Prepare call of 'CJDT_CREATE_ACT_FOR_NEW_PRJ'    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 based on transaction code.    l_old_tcode = sy-tcode.    sy-tcode = 'CJ20N'.    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 = 'CJ2D'. * 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 = 'CJ20N'. * 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        vsnmr_copy  = l_vsnmr        sched_param = space        flg_new_prj = abap_true      EXCEPTIONS        no_entries  = 1        OTHERS      = 2.    IF sy-subrc = 0.      l_ntw_found = abap_true.    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. * Check if any required field is still empty. This function module is optional and could result in disruptive pop-ups    CALL FUNCTION 'CJWB_CHECK_BEFORE_COMMIT'      EXCEPTIONS        cancel = 1. * 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_asterisk          i_view_object = c_asterisk          i_sub_view    = space          i_aktyp       = c_change          i_pronr       = ls_proj-pspnr        EXCEPTIONS          not_found     = 1          OTHERS        = 2.    ENDIF. * 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.    sy-ucomm = l_old_ucomm. * Set screen 0. The function 'CJWB_PROJECT_COPY' sets screen 0200 and if this is not overwritten here a dump may occurr (screen not found)    SET SCREEN 0.    CALL FUNCTION 'LOCATION_CORRECT'      EXPORTING        bild            = space        bildgruppe      = space        kopfgruppe      = space        positionsgruppe = space        programm        = space        stackstufe      = 0        trtyp           = space. END-OF-SELECTION. 

New NetWeaver Information at

Very Helpfull

User Rating: Be the first one !