Enterprise Resource Planning Blogs by Members
Gain new perspectives and knowledge about enterprise resource planning in blog posts from community members. Share your own comments and ERP insights today!
cancel
Showing results for 
Search instead for 
Did you mean: 
Former Member

Introduction


     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  = <-- standard project definition to be copied
       no_dialog                             = abap_true
       replace_string             = <-- project definition to be created
     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.

   CALL FUNCTION 'CJDW_GET_NEW_NUMBERS'.
   CALL FUNCTION 'CJDT_GET_NEW_NUMBERS'.

   SET SCREEN 0.

   COMMIT WORK.




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.



5 Comments
Labels in this area