ALV TREE 實例


ALV TREE 實例

 

REPORT  ZRPT_PS_PS021TREE                          .

TABLES: PROJ,          "項目定義數據
        PRPS,          "WBS元素數據
        ZCJ30,         "AFCEID
        TCJ04,         "項目負責人數據
        TCJ1,          "項目類型數據
        TJ30,          "項目狀態數據
        TJ30T,         "項目狀態文本
        TBP1T,         "預算參數文件文本
        EKKN,          "采購憑證中的帳戶設置
        EKBE,          "采購憑證歷史
        EKPO,          "采購訂單明細
        COEP,          "成本控制對象
        BPGE,          "總計值的總計記錄
        ZPS001,        "項目屬性
        BSEG,          "會計憑證行項目
        RBKP,          "憑證表頭:發票收據
        ZPS006,         "行業分類
        JEST.

DATA:T_GJAHR(6) TYPE C,
     H_GJAHR(6) TYPE C,
     G_MONTH  LIKE BSIK-MONAT,           "當前月份
     G_MONTH2 LIKE BSIK-MONAT,           "當前月份下一月
     G_DATE  LIKE SY-UCOMM,              "截止當前月份為止時間
     G_DATE2 LIKE SY-UCOMM,              "截止去年年底為止時間
     G_DATE3 LIKE SY-UCOMM,              "當月時間
     G_CONUT(4) TYPE N,                  "項目行數
     G_PSPHI LIKE PRPS-PSPHI,            "用來判斷項目是否相同
     G_PSPNR LIKE PRPS-PSPNR,            "用來判斷WBS是否相同
     G_NETPR LIKE BPGE-WTGES,            "WBS的憑證和PO金額合計
     G_NETPRSUM LIKE BPGE-WTGES.         "項目金額總記

*權限對象使用
DATA: BEGIN OF TAB_G_BUKRS OCCURS 0,
       BUKRS LIKE T001-BUKRS,
       END OF TAB_G_BUKRS.

*內表定義
DATA: BEGIN OF TAB_G_PROJ OCCURS 0,
         VBUKR     LIKE PROJ-VBUKR,        "公司代碼
         PSPHI     LIKE PRPS-PSPHI,        "項目編號
         PSPNR     LIKE PRPS-PSPNR,        "WBS編號
         CON(4),                           "項目行數序號
         PSPID     LIKE PROJ-PSPID,        "項目定義
         POST1     LIKE PRPS-POST1,        "項目名稱
         POSID     LIKE PRPS-POSID,        "WBS元素
         POST2     LIKE PRPS-POST1,        "項目名稱
         STUFE     LIKE PRPS-STUFE,        "項目層次
         UP        LIKE PRHI-UP,            "層級關系
         EBELN     LIKE EKPO-EBELN,        "采購訂單/憑證號
         TXZ01(100),        "采購訂單文本/憑證文本/成本要素文本
         OBJNR     LIKE PRPS-OBJNR,        "項目對象號
         ZBMOUNT   LIKE BPGE-WTGES,        "預算金額(Budget)
         ZNETPR    LIKE BPGE-WTGES,        "PO總金額(含稅)
         EXPSUM    LIKE ZPS001-EXPSUM,     "預計完工金額
         ZEMOUNT   LIKE BPGE-WTGES,        "剩余預算金額
         GJAHR     LIKE BSEG-GJAHR,        "年度
         ID        LIKE ICON-ID,            "層次打開圖標
         COLOR(4)  TYPE  C,                 "顏色
       END OF TAB_G_PROJ.

*ALV輸出用
DATA: TAB_G_OUT LIKE TAB_G_PROJ OCCURS 0 WITH HEADER LINE,
      REC_G_OUT LIKE TAB_G_OUT.
*計算總值
DATA: TAB_G_OUTSUM LIKE TAB_G_PROJ OCCURS 0 WITH HEADER LINE.
*展開WBS用
DATA:TAB_G_OUTID LIKE TAB_G_PROJ OCCURS 0 WITH HEADER LINE.
*判斷數據重復用
DATA: TAB_G_OUTDEL LIKE TAB_G_PROJ OCCURS 0 WITH HEADER LINE.

*判斷同一WBS元素不同憑證用數據用
DATA: TAB_G_OUTWBS LIKE TAB_G_PROJ OCCURS 0 WITH HEADER LINE.

*項目層級表
DATA:TAB_G_PSHI LIKE PRHI OCCURS 0 WITH HEADER LINE.
*實際合同金額用表
DATA TAB_G_RPSCO TYPE STANDARD TABLE OF RPSCO WITH HEADER LINE.

*帶WBS的采購訂單
DATA:BEGIN OF TAB_G_EKKN OCCURS 0,
     PSPNR LIKE EKKN-PS_PSP_PNR,"WBS元素
     EBELN LIKE EKPO-EBELN,"PO號
     EBELP LIKE EKPO-EBELP,"PO行項目
     END OF TAB_G_EKKN.
*PO金額表
DATA:BEGIN OF TAB_G_EKPO OCCURS 0,
     BUKRS LIKE EKPO-BUKRS,"公司
     PSPNR LIKE EKKN-PS_PSP_PNR,"WBS元素
     PSPID LIKE ZPS003-PSPID,"項目
     POSID LIKE ZPS003-POSID, "WBS元素
     EBELN LIKE EKPO-EBELN,"PO號
     EBELP LIKE EKPO-EBELP,"行項目
     GJAHR  LIKE COVP-GJAHR, "年度
     TXZ01 LIKE EKPO-TXZ01,"PO文本
     NETWR LIKE EKPO-NETWR,"PO金額
     RETPO LIKE EKPO-RETPO,"退貨標識
     NETPR LIKE EKPO-NETWR, "凈價格(以憑證貨幣計)
     MENGE LIKE EKPO-MENGE, "采購訂單數量
     PEINH LIKE EKPO-PEINH, "價格單位
     MWSKZ LIKE EKPO-MWSKZ, "稅代碼
     WKURS LIKE EKKO-WKURS, "匯率
     KBETR LIKE KONP-KBETR, "
     WAERS LIKE EKKO-WAERS,      "貨幣符號
     KNUMV LIKE EKKO-KNUMV,      "單據條件數
     KBETR1 LIKE KONV-KBETR,      "運費
     END OF TAB_G_EKPO.

*運費計算
DATA:BEGIN OF TAB_G_KONV OCCURS 0,
     KNUMV LIKE KONV-KNUMV,
     KPOSN LIKE KONV-KPOSN,
     KSCHL LIKE KONV-KSCHL,
     KBETR LIKE KONV-KBETR,
     END OF TAB_G_KONV.

*PO項目文本用
DATA: TAB_G_EKPODEL LIKE TAB_G_EKPO OCCURS 0 WITH HEADER LINE.
*PO金額匯總表
DATA: TAB_G_EKPOSUM LIKE TAB_G_EKPO OCCURS 0 WITH HEADER LINE.
*合同期初用
DATA: TAB_G_ZPS003 LIKE TAB_G_EKPO OCCURS 0 WITH HEADER LINE.
*外幣用
DATA:AMOUNT_EX  LIKE BAPICURR-BAPICURR,
     AMOUNT_IN LIKE BAPICURR-BAPICURR.
*無PO憑證表
DATA: BEGIN OF TAB_G_COVP OCCURS 0,
      BUKRS  LIKE T001-BUKRS,"公司
      OBJNR  LIKE PRPS-OBJNR,"對象號
      BELNR  LIKE COVP-REFBN,"憑證號
      BUDAT  LIKE BSIS-BUDAT,"記賬日期
      GJAHR  LIKE COVP-GJAHR, "年度
      BUZEI  LIKE COVP-BUZEI,
      BELNR1 LIKE COVP-BELNR,
      KSTAR  LIKE COVP-KSTAR,"成本要素
      TXT20  LIKE SKAT-TXT20,"成本要素名稱
      WOGBTR LIKE COVP-WOGBTR,"本位幣
      SGTXT  LIKE COVP-SGTXT, "憑證文本
    END OF TAB_G_COVP.
* 無PO憑證項目文本用
DATA:TAB_G_COVPDEL LIKE TAB_G_COVP OCCURS 0 WITH HEADER LINE.
*無PO憑證金額匯總用
DATA:TAB_G_COVPSUM LIKE TAB_G_COVP OCCURS 0 WITH HEADER LINE.

*成本要素用
DATA:BEGIN OF TAB_G_SKAT OCCURS 0,
     SAKNR LIKE SKAT-SAKNR,"成本要素名稱
     TXT20 LIKE SKAT-TXT20,"成本要素名稱
     END OF TAB_G_SKAT.

DATA:  G_ALV_FIELDCAT  TYPE LVC_T_FCAT,
*參照 LVC_S_FCAT 結構定義字段列工作區
       G_ALV_FIELD  TYPE LVC_S_FCAT,
       G_TOOLBAR    TYPE REF TO CL_GUI_TOOLBAR.


DATA: G_ALV_TREE         TYPE REF TO CL_GUI_ALV_TREE,
      G_CUSTOM_CONTAINER TYPE REF TO CL_GUI_CUSTOM_CONTAINER.

TYPES: BEGIN OF TY_WBS,
        POSID  TYPE PRPS-POSID,           "WBS元素
        POST2(100)  TYPE C,           "WBS描述
        STUFE  TYPE PRPS-STUFE,           "層次
        ZBMOUNT   LIKE BPGE-WTGES,        "預算金額(Budget)
        ZNETPR    LIKE BPGE-WTGES,        "PO總金額(含稅)
        EXPSUM    LIKE ZPS001-EXPSUM,     "預計完工金額
        ZEMOUNT   LIKE BPGE-WTGES,        "剩余預算金額
        VBUKR     LIKE PROJ-VBUKR,        "公司代碼
        GJAHR     LIKE COVP-GJAHR, "年度
        EBELN     LIKE EKKO-EBELN,
       END OF TY_WBS.

DATA: GT_WBS TYPE STANDARD TABLE OF TY_WBS,
      GS_WBS TYPE TY_WBS.

DATA: OK_CODE LIKE SY-UCOMM,
      SAVE_OK LIKE SY-UCOMM,           "OK-Code
      G_MAX TYPE I VALUE 255.

DATA: GT_FCAT  TYPE  LVC_T_FCAT,
      GS_FCAT  TYPE  LVC_S_FCAT.
*下載抬頭數據用
DATA: BEGIN OF TAB_G_XIZA OCCURS 0,
      TEXT(25) TYPE C,
     END OF TAB_G_XIZA.
DATA: BEGIN OF TAB_G_XIZAITEM OCCURS 0,
        POSID(30)   TYPE C,        "WBS元素
        POST2(100)   TYPE C,        "WBS描述
        ZBMOUNT(20) TYPE C,        "預算金額(Budget)
        ZNETPR(20)  TYPE C,        "PO總金額(含稅)
        ZEMOUNT(20) TYPE C,        "剩余預算金額
        EXPSUM(20)  TYPE C,        "預計完工金額
     END OF TAB_G_XIZAITEM.
*---------------------------------------------------------------------*
*          SELECTION-SCREEN
*---------------------------------------------------------------------*
SELECTION-SCREEN BEGIN OF BLOCK A WITH FRAME TITLE TEXT-001.
PARAMETERS: P_GJAHR  LIKE BSIK-GJAHR DEFAULT SY-DATUM+0(4) OBLIGATORY,
            P_MONTH  LIKE BSIK-MONAT DEFAULT SY-DATUM+4(2) OBLIGATORY.
SELECT-OPTIONS: S_VBUKR  FOR PROJ-VBUKR OBLIGATORY,        "公司代碼
                S_PSPID  FOR PROJ-PSPID,                   "項目定義
*                S_POSID  FOR PRPS-POSID,                   "WBS元素
                S_PRART  FOR TCJ1-PRART,                   "項目類型
                S_VERNR  FOR TCJ04-VERNR,                  "項目負責
                S_USR00  FOR ZPS006-USR00.                   "行業分類
*PARAMETERS: R1 AS CHECKBOX. "展開
SELECTION-SCREEN END OF BLOCK A.

SELECTION-SCREEN BEGIN OF BLOCK C WITH FRAME TITLE TEXT-003.
PARAMETERS: R3 RADIOBUTTON GROUP B DEFAULT 'X',          "顯示全部
            R4 RADIOBUTTON GROUP B.                      "顯示未完工
SELECTION-SCREEN END OF BLOCK C.

AT SELECTION-SCREEN.
*權限檢查
  SELECT BUKRS FROM T001 INTO TABLE TAB_G_BUKRS
  WHERE BUKRS IN S_VBUKR.
  DELETE ADJACENT DUPLICATES FROM TAB_G_BUKRS COMPARING BUKRS.
  LOOP AT TAB_G_BUKRS.
    AUTHORITY-CHECK OBJECT 'ZPS021'
                        ID 'ACTVT' FIELD '03'
                        ID 'BUKRS' FIELD TAB_G_BUKRS-BUKRS.
    IF SY-SUBRC <> 0.
      MESSAGE '您沒有權限!' TYPE 'E'.
    ENDIF.
  ENDLOOP.
*屏幕數據檢查
  IF P_GJAHR = '0000' OR P_GJAHR+0(1) = 0.
    MESSAGE '輸入年度不存在!' TYPE  'E'.
  ENDIF.
  IF P_MONTH > '12' OR P_MONTH = 0.
    MESSAGE '輸入月份不存在!' TYPE  'E'.
  ENDIF.

*----------------------------------------------------------------------*
*       CLASS lcl_tree_event_receiver DEFINITION
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
CLASS LCL_TREE_EVENT_RECEIVER DEFINITION.

  PUBLIC SECTION.
    METHODS HANDLE_NODE_DOUBLE_CLICK
      FOR EVENT NODE_DOUBLE_CLICK OF CL_GUI_ALV_TREE
      IMPORTING NODE_KEY SENDER.
    METHODS HANDLE_ITEM_DOUBLE_CLICK
      FOR EVENT ITEM_DOUBLE_CLICK OF CL_GUI_ALV_TREE
      IMPORTING FIELDNAME NODE_KEY.
ENDCLASS.                    "lcl_tree_event_receiver DEFINITION
*----------------------------------------------------------------------*
*       CLASS lcl_toolbar_event_receive DEFINITION
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
CLASS LCL_TOOLBAR_EVENT_RECEIVER DEFINITION.

  PUBLIC SECTION.
* ?4. Define an event handler method to react to fired function codes
*     of the toolbar.                   .
    METHODS: ON_FUNCTION_SELECTED
               FOR EVENT FUNCTION_SELECTED OF CL_GUI_TOOLBAR
                 IMPORTING FCODE.

ENDCLASS.                    "lcl_toolbar_event_receiver DEFINITION
*----------------------------------------------------------------------*
*       CLASS LCL_TREE_EVENT_RECEIVER IMPLEMENTATION
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
CLASS LCL_TREE_EVENT_RECEIVER IMPLEMENTATION.

  METHOD HANDLE_NODE_DOUBLE_CLICK.
    DATA: LT_CHILDREN TYPE LVC_T_NKEY.

    CALL METHOD SENDER->GET_CHILDREN
      EXPORTING
        I_NODE_KEY  = NODE_KEY
      IMPORTING
        ET_CHILDREN = LT_CHILDREN.

    IF NOT LT_CHILDREN IS INITIAL.

      CALL METHOD SENDER->EXPAND_NODE
        EXPORTING
          I_NODE_KEY    = NODE_KEY
          I_LEVEL_COUNT = 2.
    ENDIF.

  ENDMETHOD.                    "handle_node_double_click

  METHOD HANDLE_ITEM_DOUBLE_CLICK.
    DATA: L_VALUE TYPE LVC_VALUE,
          L_LAYI  TYPE LVC_T_LAYI,
          L_LAYN  TYPE LVC_S_LAYN .
    DATA:G_EBELN LIKE EKKN-EBELN.
    CALL METHOD G_ALV_TREE->GET_OUTTAB_LINE
      EXPORTING
        I_NODE_KEY     = NODE_KEY
      IMPORTING
        E_OUTTAB_LINE  = GS_WBS
        E_NODE_TEXT    = L_VALUE
        ET_ITEM_LAYOUT = L_LAYI
        ES_NODE_LAYOUT = L_LAYN
      EXCEPTIONS
        NODE_NOT_FOUND = 1
        OTHERS         = 2.
    IF SY-SUBRC = 0.
      IF GS_WBS-POSID+0(2) = 'CN'.
        SET PARAMETER ID 'PRO' FIELD GS_WBS-POSID.
        CALL TRANSACTION 'CJ03' AND SKIP FIRST SCREEN.
      ELSEIF GS_WBS-POSID+0(1) = '9'.
        SET PARAMETER ID 'BLN' FIELD GS_WBS-POSID.
        SET PARAMETER ID 'BUK' FIELD GS_WBS-VBUKR.
        SET PARAMETER ID 'GJR' FIELD GS_WBS-GJAHR.
        CALL TRANSACTION 'FB03' AND SKIP FIRST SCREEN.
      ELSE.
        CLEAR:G_EBELN.
        SELECT SINGLE EBELN
        FROM EKKN
        INTO G_EBELN
        WHERE EBELN = GS_WBS-POSID.
        IF SY-SUBRC = 0.
          SET PARAMETER ID 'BES' FIELD GS_WBS-POSID.
          CALL TRANSACTION 'ME23N' AND SKIP FIRST SCREEN.
        ELSE.
          MESSAGE '無此PO!' TYPE  'S'.
        ENDIF.
      ENDIF.
    ENDIF.

  ENDMETHOD.                    "handle_item_double_click

ENDCLASS.                    "lcl_tree_event_receiver IMPLEMENTATION
*---------------------------------------------------------------------*
*       CLASS lcl_toolbar_event_receiver IMPLEMENTATION
*---------------------------------------------------------------------*
*       ........                                                      *
*---------------------------------------------------------------------*
CLASS LCL_TOOLBAR_EVENT_RECEIVER IMPLEMENTATION.
*
  METHOD ON_FUNCTION_SELECTED.
    DATA: LT_SELECTED_NODES TYPE LVC_T_NKEY,
          L_SELECTED_NODE   TYPE LVC_NKEY,
          L_RC              TYPE C.

* ?5. Query the function codes of the toolbar in your implementation.
    CASE FCODE.
      WHEN 'XIZA'."下載數據
        PERFORM XIZA_DATA.
    ENDCASE.
  ENDMETHOD.                    "on_function_selected

ENDCLASS.                    "lcl_toolbar_event_receiver IMPLEMENTATION

END-OF-SELECTION.

  CALL SCREEN 100.

*&---------------------------------------------------------------------*
*&      Module  PBO  OUTPUT
*&---------------------------------------------------------------------*
*       process before output
*----------------------------------------------------------------------*
MODULE PBO OUTPUT.

  SET PF-STATUS 'MAIN100'.
  SET TITLEBAR 'MAINTITLE'.

  IF G_ALV_TREE IS INITIAL.
    PERFORM INIT_TREE.

    CALL METHOD CL_GUI_CFW=>FLUSH
      EXCEPTIONS
        CNTL_SYSTEM_ERROR = 1
        CNTL_ERROR        = 2.
    IF SY-SUBRC NE 0.
      CALL FUNCTION 'POPUP_TO_INFORM'
        EXPORTING
          TITEL = 'Automation Queue failure'(801)
          TXT1  = 'Internal error:'(802)
          TXT2  = 'A method in the automation queue'(803)
          TXT3  = 'caused a failure.'(804).
    ENDIF.
  ENDIF.

ENDMODULE.                             " PBO  OUTPUT
*&---------------------------------------------------------------------*
*&      Module  PAI  INPUT
*&---------------------------------------------------------------------*
*       process after input
*----------------------------------------------------------------------*
MODULE PAI INPUT.
  SAVE_OK = OK_CODE.
  CLEAR OK_CODE.

  CASE SAVE_OK.
    WHEN 'EXIT' OR 'BACK' OR 'CANC'.
      PERFORM EXIT_PROGRAM.

    WHEN OTHERS.
      CALL METHOD CL_GUI_CFW=>DISPATCH.

  ENDCASE.

  CALL METHOD CL_GUI_CFW=>FLUSH.
ENDMODULE.                             " PAI  INPUT

*&---------------------------------------------------------------------*
*&      Form  init_tree
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*  -->  p1        text
*  <--  p2        text
*----------------------------------------------------------------------*
FORM INIT_TREE.

  DATA: L_TREE_CONTAINER_NAME(30) TYPE C.

  L_TREE_CONTAINER_NAME = 'CCONTAINER1'.

  CREATE OBJECT G_CUSTOM_CONTAINER
    EXPORTING
      CONTAINER_NAME              = L_TREE_CONTAINER_NAME
    EXCEPTIONS
      CNTL_ERROR                  = 1
      CNTL_SYSTEM_ERROR           = 2
      CREATE_ERROR                = 3
      LIFETIME_ERROR              = 4
      LIFETIME_DYNPRO_DYNPRO_LINK = 5.
  IF SY-SUBRC <> 0.
    MESSAGE X208(00) WITH 'ERROR'(100).
  ENDIF.

* create tree control
  CREATE OBJECT G_ALV_TREE
    EXPORTING
      PARENT                      = G_CUSTOM_CONTAINER
      NODE_SELECTION_MODE         = CL_GUI_COLUMN_TREE=>NODE_SEL_MODE_SINGLE
      ITEM_SELECTION              = 'X'
      NO_HTML_HEADER              = 'X'
      NO_TOOLBAR                  = ''
    EXCEPTIONS
      CNTL_ERROR                  = 1
      CNTL_SYSTEM_ERROR           = 2
      CREATE_ERROR                = 3
      LIFETIME_ERROR              = 4
      ILLEGAL_NODE_SELECTION_MODE = 5
      FAILED                      = 6
      ILLEGAL_COLUMN_NAME         = 7.
  IF SY-SUBRC <> 0.
    MESSAGE X208(00) WITH 'ERROR'.                          "#EC NOTEXT
  ENDIF.


*主節點抬頭描述
  DATA L_HIERARCHY_HEADER TYPE TREEV_HHDR.
  PERFORM BUILD_HIERARCHY_HEADER CHANGING L_HIERARCHY_HEADER.
*項目內表抬頭描述
  PERFORM BUILD_FIELDCATEGORY.
  DATA: G_LAYOUT1 TYPE LVC_S_LAYO."布局結構
  DATA: LS_VARIANT TYPE DISVARIANT."格式 (外部使用)
  LS_VARIANT-REPORT = SY-REPID."ABAP 程序名稱


  CALL METHOD G_ALV_TREE->SET_TABLE_FOR_FIRST_DISPLAY
    EXPORTING
      I_SAVE              = 'A'
      IS_HIERARCHY_HEADER = L_HIERARCHY_HEADER
      IS_VARIANT          = LS_VARIANT
    CHANGING
      IT_OUTTAB           = GT_WBS   "table must be empty !
      IT_FIELDCATALOG     = GT_FCAT.

  PERFORM CREATE_HIERARCHY."讀取數據

  PERFORM CHANGE_TOOLBAR."增加工具欄
  PERFORM REGISTER_EVENTS_TOOLBAR."增加工具欄觸發
  PERFORM REGISTER_EVENTS.

  CALL METHOD G_ALV_TREE->FRONTEND_UPDATE.

ENDFORM.                               " init_tree
*&---------------------------------------------------------------------*
*&      Form  build_hierarchy_header
*&---------------------------------------------------------------------*
*       build hierarchy-header-information
*----------------------------------------------------------------------*
*      -->P_L_HIERARCHY_HEADER  strucxture for hierarchy-header
*----------------------------------------------------------------------*
FORM BUILD_HIERARCHY_HEADER CHANGING
                            P_HIERARCHY_HEADER TYPE TREEV_HHDR.
  P_HIERARCHY_HEADER-HEADING = 'WBS元素/合同號/憑證號'(300).
  P_HIERARCHY_HEADER-TOOLTIP = 'WBS'(400).
  P_HIERARCHY_HEADER-WIDTH = 50.
  P_HIERARCHY_HEADER-WIDTH_PIX = ' '.

ENDFORM.                               " build_hierarchy_header
*&---------------------------------------------------------------------*
*&      Form  exit_program
*&---------------------------------------------------------------------*
*       free object and leave program
*----------------------------------------------------------------------*
FORM EXIT_PROGRAM.

  CALL METHOD G_CUSTOM_CONTAINER->FREE.
  LEAVE PROGRAM.

ENDFORM.                               " exit_program
*&---------------------------------------------------------------------*
*&      Form  create_hierarchy
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*  -->  p1        text
*  <--  p2        text
*----------------------------------------------------------------------*
FORM CREATE_HIERARCHY.

  DATA: LS_WBS TYPE TY_WBS,
        LT_WBS TYPE TY_WBS OCCURS 0.

  DATA: LT_NODES TYPE TABLE OF LVC_NKEY WITH HEADER LINE,
        L_CUR_NODE TYPE LVC_NKEY,
        L_FORMER_STUFE TYPE PRPS-STUFE,
        L_INDEX  TYPE I.

* 讀取數據
  PERFORM FRM_DATA_GET.
  LOOP AT TAB_G_OUT.
    CLEAR:LS_WBS.
    MOVE-CORRESPONDING TAB_G_OUT TO LS_WBS.
    APPEND LS_WBS TO LT_WBS.
  ENDLOOP.

*  SELECT PRPS~POSID PRPS~POST1 PRPS~STUFE
*  FROM PRPS
*  INNER JOIN PROJ ON PROJ~PSPNR = PRPS~PSPHI
*  INTO TABLE LT_WBS
*  WHERE PROJ~PSPID = 'CNJX00A10001'.
*  UP TO 200 ROWS.

*  SORT LT_WBS BY POSID.

  LOOP AT LT_WBS INTO LS_WBS.

    IF LS_WBS-STUFE = '1'.
      REFRESH LT_NODES.
      L_INDEX = LS_WBS-STUFE.
      PERFORM ADD_NODES USING    LS_WBS
                                 ''
                        CHANGING L_CUR_NODE.
      READ TABLE LT_NODES INDEX L_INDEX.
      IF SY-SUBRC NE 0.
        APPEND L_CUR_NODE TO LT_NODES.
      ENDIF.

    ELSEIF LS_WBS-STUFE > L_FORMER_STUFE.      "on change of l_yyyymm
      L_INDEX = LS_WBS-STUFE - 1.
      READ TABLE LT_NODES INDEX L_INDEX.

      PERFORM ADD_NODES USING    LS_WBS
                                 LT_NODES
                        CHANGING L_CUR_NODE.
*---->保存新的當前節點
      APPEND L_CUR_NODE TO LT_NODES.
    ELSEIF LS_WBS-STUFE < L_FORMER_STUFE.
      L_INDEX = LS_WBS-STUFE - 1.
      READ TABLE LT_NODES INDEX L_INDEX.

      PERFORM ADD_NODES USING    LS_WBS
                                 LT_NODES
                        CHANGING L_CUR_NODE.
*---->將當前節點及之后后的所有臨時存儲節點KEY刪除
      L_INDEX = L_INDEX + 1.
      DELETE LT_NODES INDEX L_INDEX.
      DO.
        READ TABLE LT_NODES INDEX L_INDEX.
        IF SY-SUBRC = 0.
          DELETE LT_NODES INDEX L_INDEX.
        ELSE.
          EXIT.
        ENDIF.
      ENDDO.
*---->保存新的當前節點
      APPEND L_CUR_NODE TO LT_NODES.
    ELSE.
      L_INDEX = LS_WBS-STUFE - 1.
      READ TABLE LT_NODES INDEX L_INDEX.
      PERFORM ADD_NODES USING    LS_WBS
                                 LT_NODES
                        CHANGING L_CUR_NODE.
    ENDIF.
    L_FORMER_STUFE = LS_WBS-STUFE.
    IF LS_WBS-EBELN IS INITIAL.
*---->將當前節點及之后后的所有臨時存儲節點KEY刪除
      L_INDEX = L_INDEX + 1.
      DELETE LT_NODES INDEX L_INDEX.
      DO.
        READ TABLE LT_NODES INDEX L_INDEX.
        IF SY-SUBRC = 0.
          DELETE LT_NODES INDEX L_INDEX.
        ELSE.
          EXIT.
        ENDIF.
      ENDDO.
*---->保存新的當前節點
      APPEND L_CUR_NODE TO LT_NODES.
    ENDIF.
  ENDLOOP.

ENDFORM.                               " create_hierarchy
*&---------------------------------------------------------------------*
*&      Form  add_nodes
*&---------------------------------------------------------------------*
FORM ADD_NODES  USING     PS_WBS TYPE TY_WBS
                          P_CNODE_KEY TYPE LVC_NKEY
                CHANGING  P_NNODE_KEY TYPE LVC_NKEY.

  DATA: L_NODE_TEXT TYPE LVC_VALUE.

  CALL FUNCTION 'CONVERSION_EXIT_ABPSN_OUTPUT'
    EXPORTING
      INPUT  = PS_WBS-POSID
    IMPORTING
      OUTPUT = L_NODE_TEXT.

  CALL METHOD G_ALV_TREE->ADD_NODE
    EXPORTING
      I_RELAT_NODE_KEY = P_CNODE_KEY
      I_RELATIONSHIP   = CL_GUI_COLUMN_TREE=>RELAT_LAST_CHILD
      I_NODE_TEXT      = L_NODE_TEXT
      IS_OUTTAB_LINE   = PS_WBS
    IMPORTING
      E_NEW_NODE_KEY   = P_NNODE_KEY.

ENDFORM.                               " add_month
*&---------------------------------------------------------------------*
*&      Form  build_fieldcategory
*&---------------------------------------------------------------------*
FORM BUILD_FIELDCATEGORY .
  CLEAR:GS_FCAT,GT_FCAT,GT_FCAT[].
  GS_FCAT-FIELDNAME      =  'POST2'.
  GS_FCAT-SELTEXT        =  'WBS描述/合同描述/成本要素描述/憑證描述'.    " 字段輸出名稱
  GS_FCAT-COLTEXT        =  'WBS描述/合同描述/成本要素描述/憑證描述'.    " 字段輸出名稱
  GS_FCAT-JUST           =  'L'.
  GS_FCAT-OUTPUTLEN      =  '100'.        " 輸出長度
  APPEND GS_FCAT TO GT_FCAT.
  CLEAR  GS_FCAT.

  GS_FCAT-FIELDNAME      =  'ZBMOUNT'.
  GS_FCAT-SELTEXT        =  '預算(元)'.    " 字段輸出名稱
  GS_FCAT-COLTEXT        =  '預算(元)'.    " 字段輸出名稱
  GS_FCAT-COL_OPT        = 'X'.
  GS_FCAT-JUST           =  'L'.
  GS_FCAT-DATATYPE       = 'CURR'.
  GS_FCAT-OUTPUTLEN      =  '20'.        " 輸出長度
  APPEND GS_FCAT TO GT_FCAT.
  CLEAR  GS_FCAT.

  GS_FCAT-FIELDNAME      =  'ZNETPR'.
  GS_FCAT-SELTEXT        =  '合同金額/無PO金額(元)'.    " 字段輸出名稱
  GS_FCAT-COLTEXT        =  '合同金額/無PO金額(元)'.    " 字段輸出名稱
  GS_FCAT-COL_OPT        = 'X'.
  GS_FCAT-JUST           =  'L'.
  GS_FCAT-DATATYPE       = 'CURR'.
  GS_FCAT-OUTPUTLEN      =  '30'.        " 輸出長度
  APPEND GS_FCAT TO GT_FCAT.
  CLEAR  GS_FCAT.

  GS_FCAT-FIELDNAME      =  'ZEMOUNT'.
  GS_FCAT-SELTEXT        =  '差額(元)'.    " 字段輸出名稱
  GS_FCAT-COLTEXT        =  '差額(元)'.    " 字段輸出名稱
  GS_FCAT-COL_OPT        = 'X'.
  GS_FCAT-JUST           =  'L'.
  GS_FCAT-DATATYPE       = 'CURR'.
  GS_FCAT-OUTPUTLEN      =  '20'.        " 輸出長度
  APPEND GS_FCAT TO GT_FCAT.
  CLEAR  GS_FCAT.

  GS_FCAT-FIELDNAME      =  'EXPSUM'.
  GS_FCAT-SELTEXT        =  '項目預計完成(元)'.    " 字段輸出名稱
  GS_FCAT-COLTEXT        =  '項目預計完成(元)'.    " 字段輸出名稱
  GS_FCAT-COL_OPT        = 'X'.
  GS_FCAT-JUST           =  'L'.
  GS_FCAT-DATATYPE       = 'CURR'.
  GS_FCAT-OUTPUTLEN      =  '25'.        " 輸出長度
  APPEND GS_FCAT TO GT_FCAT.
  CLEAR  GS_FCAT.

ENDFORM.                    " build_fieldcategory
*&---------------------------------------------------------------------*
*&      Form  register_events
*&---------------------------------------------------------------------*
FORM REGISTER_EVENTS .
  DATA: LT_EVENTS TYPE CNTL_SIMPLE_EVENTS,
        L_EVENT TYPE CNTL_SIMPLE_EVENT,
        L_EVENT_RECEIVER TYPE REF TO LCL_TREE_EVENT_RECEIVER.

  CALL METHOD G_ALV_TREE->GET_REGISTERED_EVENTS
    IMPORTING
      EVENTS = LT_EVENTS.

  L_EVENT-EVENTID = CL_GUI_COLUMN_TREE=>EVENTID_NODE_DOUBLE_CLICK.
  APPEND L_EVENT TO LT_EVENTS.
  L_EVENT-EVENTID = CL_GUI_COLUMN_TREE=>EVENTID_ITEM_DOUBLE_CLICK.
  APPEND L_EVENT TO LT_EVENTS.

  CALL METHOD G_ALV_TREE->SET_REGISTERED_EVENTS
    EXPORTING
      EVENTS                    = LT_EVENTS
    EXCEPTIONS
      CNTL_ERROR                = 1
      CNTL_SYSTEM_ERROR         = 2
      ILLEGAL_EVENT_COMBINATION = 3.
  IF SY-SUBRC <> 0.
    MESSAGE X208(00) WITH 'ERROR'.                          "#EC NOTEXT
  ENDIF.

  CREATE OBJECT L_EVENT_RECEIVER.
  SET HANDLER L_EVENT_RECEIVER->HANDLE_NODE_DOUBLE_CLICK FOR G_ALV_TREE.
  SET HANDLER L_EVENT_RECEIVER->HANDLE_ITEM_DOUBLE_CLICK FOR G_ALV_TREE.

ENDFORM.                    " register_events
*&---------------------------------------------------------------------*
*&      Form  FRM_DATA_GET
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*  -->  p1        text
*  <--  p2        text
*----------------------------------------------------------------------*
FORM FRM_DATA_GET .
*  付款金額用時間設定
  G_MONTH  = P_MONTH.
  G_MONTH2 = P_MONTH + 1.
  CONCATENATE P_GJAHR G_MONTH2 '01' INTO G_DATE.          "截止當前月份為止時間
  CONCATENATE P_GJAHR '01' '01' INTO G_DATE2.             "截止去年年底為止時間
  CONCATENATE P_GJAHR P_MONTH '01' INTO G_DATE3.          "當月時間

*取已分配預算項目和AFCE數據
  SELECT PROJ~VBUKR            "公司
         PROJ~PSPID            "項目定義
         PROJ~POST1 AS POST1   "項目描述
         PRPS~PSPHI            "項目號碼
         PRPS~POSID            "WBS元素
         PRPS~POST1 AS POST2   "WBS描述
         PRPS~PSPNR            "WBS編號
         PRPS~OBJNR            "項目對象號
         PRPS~STUFE            "項目層次
   FROM PROJ
   INNER JOIN PRPS  ON PRPS~PSPHI = PROJ~PSPNR
   INTO CORRESPONDING FIELDS OF TABLE TAB_G_PROJ
   WHERE PROJ~VBUKR IN S_VBUKR "公司
     AND PROJ~PSPID IN S_PSPID "項目定義
*     AND PRPS~POSID IN S_POSID "WBS元素
     AND PROJ~VERNR IN S_VERNR "項目負責人
     AND PRPS~PRART IN S_PRART "項目類型
     AND PRPS~USR00 IN S_USR00 "行業分類
     AND PRPS~LOEVM = ''."刪除標識

*項目狀態
  IF R4 = 'X'.
    LOOP AT TAB_G_PROJ.
      SELECT SINGLE *
      FROM JEST
      WHERE OBJNR = TAB_G_PROJ-OBJNR
        AND STAT = 'I0046'
        AND INACT = ''.
      IF SY-SUBRC = 0.
        DELETE TAB_G_PROJ.
      ENDIF.
      CLEAR:TAB_G_PROJ.
    ENDLOOP.
  ENDIF.

  IF NOT TAB_G_PROJ[] IS INITIAL.
*取項目層級關系
    SELECT *
    FROM PRHI
    INTO TABLE TAB_G_PSHI
    FOR ALL ENTRIES IN TAB_G_PROJ
    WHERE PSPHI = TAB_G_PROJ-PSPHI "項目定義編號
      AND POSNR = TAB_G_PROJ-PSPNR."WBS編號

*取帶WBS的PO
    SELECT PS_PSP_PNR AS PSPNR "WBS編號
           EBELN                "PO號
           EBELP                "PO行項目
    FROM EKKN
    INTO TABLE TAB_G_EKKN
    FOR ALL ENTRIES IN TAB_G_PROJ
    WHERE AEDAT < G_DATE                "PO創建日期
      AND PS_PSP_PNR = TAB_G_PROJ-PSPNR "WBS編號
      AND PS_PSP_PNR <> ''.             "WBS編號

    SORT TAB_G_EKKN BY EBELN.
*PO總金額
    IF TAB_G_EKKN[] IS NOT INITIAL.
      SELECT EKPO~BUKRS "公司
             EKPO~EBELN "PO號
             EKPO~EBELP "PO項目
             EKPO~NETWR "PO貨幣的凈訂單價值
             EKPO~RETPO "退貨項目
             EKPO~NETPR "凈價格(以憑證貨幣計)
             EKPO~MENGE "采購訂單數量
             EKPO~PEINH "價格單位
             EKPO~MWSKZ "稅代碼
             EKKO~WKURS "匯率
             EKKO~WAERS"貨幣符號
             EKPO~TXZ01 "PO文本
             EKKO~KNUMV "單據條件數
      FROM EKPO
      INNER JOIN EKKO ON EKKO~EBELN = EKPO~EBELN
      INTO CORRESPONDING FIELDS OF TABLE TAB_G_EKPO
      FOR ALL ENTRIES IN TAB_G_EKKN
      WHERE EKKO~BUKRS IN S_VBUKR         "公司
        AND EKPO~EBELN = TAB_G_EKKN-EBELN "PO號
        AND EKPO~EBELP = TAB_G_EKKN-EBELP "PO行項目
        AND EKPO~LOEKZ <> 'L'.            "刪除標識

      SORT TAB_G_EKPO BY BUKRS EBELN.
      IF TAB_G_EKPO[] IS NOT INITIAL.

      ENDIF.
      LOOP AT TAB_G_EKPO.
        READ TABLE TAB_G_EKKN WITH KEY EBELN = TAB_G_EKPO-EBELN
                                       EBELP = TAB_G_EKPO-EBELP.
        IF SY-SUBRC = 0.
          TAB_G_EKPO-PSPNR = TAB_G_EKKN-PSPNR.
*取稅率
          SELECT SINGLE KONP~KBETR
          FROM  A003
          INNER JOIN KONP ON KONP~KNUMH = A003~KNUMH
          INTO TAB_G_EKPO-KBETR
          WHERE A003~KAPPL = 'TX'
            AND A003~MWSKZ = TAB_G_EKPO-MWSKZ
            AND A003~KSCHL IN ('MWVS', 'MWCN')
            AND A003~ALAND = 'CN'
            AND KONP~KOPOS = '01'.
          MODIFY TAB_G_EKPO.

          IF TAB_G_EKPO-RETPO = 'X'."退貨訂單判斷
*PO總金額(含稅)
            IF TAB_G_EKPO-KBETR = ''.
              TAB_G_EKPO-NETPR  = TAB_G_EKPO-NETPR * TAB_G_EKPO-MENGE *
                         TAB_G_EKPO-WKURS / TAB_G_EKPO-PEINH.

              TAB_G_EKPO-NETPR  = 0 - TAB_G_EKPO-NETPR .
            ELSE.
              IF TAB_G_EKPO-MWSKZ = 'T0'.
                TAB_G_EKPO-NETPR = TAB_G_EKPO-NETPR * TAB_G_EKPO-MENGE *
              TAB_G_EKPO-WKURS / TAB_G_EKPO-PEINH / ( 1 - 7 / 100 ).
              ELSE.
                TAB_G_EKPO-NETPR = TAB_G_EKPO-NETPR * TAB_G_EKPO-MENGE *
                          TAB_G_EKPO-WKURS / TAB_G_EKPO-PEINH +  TAB_G_EKPO-NETPR *
                          TAB_G_EKPO-MENGE * TAB_G_EKPO-KBETR * TAB_G_EKPO-WKURS / 1000 /
                          TAB_G_EKPO-PEINH.
              ENDIF.
* 運費
              CLEAR:TAB_G_KONV,TAB_G_KONV[].
              SELECT KNUMV
                     KPOSN
                     KSCHL
                     KBETR
              FROM KONV
              INTO TABLE TAB_G_KONV
              WHERE KNUMV = TAB_G_EKPO-KNUMV
                AND KPOSN = TAB_G_EKPO-EBELP
                AND KSCHL IN ('FRB2','ZKG1').
              LOOP AT TAB_G_KONV.
                TAB_G_EKPO-KBETR1 = TAB_G_EKPO-KBETR1 + TAB_G_KONV-KBETR.
              ENDLOOP.
              TAB_G_EKPO-NETWR = TAB_G_EKPO-NETWR + TAB_G_EKPO-KBETR1.
              TAB_G_EKPO-NETPR = TAB_G_EKPO-NETPR + TAB_G_EKPO-KBETR1.
              TAB_G_EKPO-NETPR  = 0 - TAB_G_EKPO-NETPR ."PO總金額(含稅)
              TAB_G_EKPO-NETWR = 0 - TAB_G_EKPO-NETWR."*PO總金額
            ENDIF.
*PO總金額
            TAB_G_EKPO-NETWR = TAB_G_EKPO-NETWR * TAB_G_EKPO-WKURS.
          ELSE.

*PO總金額(含稅)
            IF TAB_G_EKPO-KBETR = ''.
              TAB_G_EKPO-NETPR = TAB_G_EKPO-NETPR * TAB_G_EKPO-MENGE *
                          TAB_G_EKPO-WKURS / TAB_G_EKPO-PEINH.
            ELSE.
              IF TAB_G_EKPO-MWSKZ = 'T0'.
                TAB_G_EKPO-NETPR = TAB_G_EKPO-NETPR * TAB_G_EKPO-MENGE *
              TAB_G_EKPO-WKURS / TAB_G_EKPO-PEINH / ( 1 - 7 / 100 ).
              ELSE.
                TAB_G_EKPO-NETPR = TAB_G_EKPO-NETPR * TAB_G_EKPO-MENGE *
                          TAB_G_EKPO-WKURS / TAB_G_EKPO-PEINH + TAB_G_EKPO-NETPR *
                          TAB_G_EKPO-MENGE * TAB_G_EKPO-KBETR * TAB_G_EKPO-WKURS /
                          1000 / TAB_G_EKPO-PEINH.
              ENDIF.
            ENDIF.
*PO總金額
            TAB_G_EKPO-NETWR = TAB_G_EKPO-NETWR * TAB_G_EKPO-WKURS.
* 運費
            CLEAR:TAB_G_KONV,TAB_G_KONV[].
            SELECT KNUMV
                   KPOSN
                   KSCHL
                   KBETR
            FROM KONV
            INTO TABLE TAB_G_KONV
            WHERE KNUMV = TAB_G_EKPO-KNUMV
              AND KPOSN = TAB_G_EKPO-EBELP
              AND KSCHL IN ('FRB2','ZKG1').
            LOOP AT TAB_G_KONV.
              TAB_G_EKPO-KBETR1 = TAB_G_EKPO-KBETR1 + TAB_G_KONV-KBETR.
            ENDLOOP.
            TAB_G_EKPO-NETWR = TAB_G_EKPO-NETWR + TAB_G_EKPO-KBETR1.
            TAB_G_EKPO-NETPR = TAB_G_EKPO-NETPR + TAB_G_EKPO-KBETR1.
          ENDIF.
        ENDIF.
        MODIFY TAB_G_EKPO.
        CLEAR:TAB_G_EKPO.
      ENDLOOP.

*取合同期初金額
      CLEAR:TAB_G_ZPS003,TAB_G_ZPS003[].
      SELECT VBUKR AS BUKRS
             PSPID
             EBELN
             POSID
             GJAHR
             NETPRALL AS NETPR
             TXZ01
      FROM ZPS003
      INTO CORRESPONDING FIELDS OF TABLE TAB_G_ZPS003
      FOR ALL ENTRIES IN TAB_G_PROJ
      WHERE VBUKR = TAB_G_PROJ-VBUKR "公司
        AND PSPID = TAB_G_PROJ-PSPID "項目定義
        AND GJAHR =< SY-DATUM+0(4).

*查找WBS編號
      LOOP AT TAB_G_ZPS003.
        CALL FUNCTION 'CONVERSION_EXIT_ABPSN_INPUT'
          EXPORTING
            INPUT  = TAB_G_ZPS003-POSID
          IMPORTING
            OUTPUT = TAB_G_ZPS003-POSID.
        READ TABLE TAB_G_PROJ WITH KEY PSPID = TAB_G_ZPS003-PSPID
                                       POSID = TAB_G_ZPS003-POSID.
        IF SY-SUBRC = 0.
          TAB_G_ZPS003-PSPNR = TAB_G_PROJ-PSPNR.
          CLEAR:TAB_G_ZPS003-PSPID,TAB_G_ZPS003-POSID.
          MODIFY TAB_G_ZPS003.
        ELSE.
          DELETE TAB_G_ZPS003.
        ENDIF.
      ENDLOOP.

*根據PO,年度確定最新數據
      SORT TAB_G_ZPS003 BY BUKRS PSPNR EBELN GJAHR DESCENDING.
*刪除重復數據取出最新PO期初
      DELETE ADJACENT DUPLICATES FROM TAB_G_ZPS003 COMPARING BUKRS PSPNR EBELN.

      APPEND LINES OF TAB_G_ZPS003 TO TAB_G_EKPO.
*PO總金額匯總
      APPEND LINES OF TAB_G_EKPO TO TAB_G_EKPODEL.
      CLEAR:TAB_G_EKPO-EBELP,TAB_G_EKPO-RETPO,TAB_G_EKPO-TXZ01,
      TAB_G_EKPO-WKURS,TAB_G_EKPO-MWSKZ,TAB_G_EKPO-KBETR,
      TAB_G_EKPO-PSPID,TAB_G_EKPO-POSID, TAB_G_EKPO-WAERS, TAB_G_EKPO-KNUMV.
      MODIFY TAB_G_EKPO TRANSPORTING EBELP TXZ01 RETPO WKURS MWSKZ KBETR PSPID POSID WAERS KNUMV
                               WHERE EBELN <> ''.
      SORT TAB_G_EKPO BY BUKRS PSPNR EBELN.
      LOOP AT TAB_G_EKPO.
        COLLECT TAB_G_EKPO INTO TAB_G_EKPOSUM.
        APPEND TAB_G_EKPOSUM.
      ENDLOOP.
    ENDIF.
  ENDIF.
  DELETE TAB_G_EKPOSUM WHERE BUKRS = ''.

*無PO憑證
  IF TAB_G_PROJ[] IS NOT INITIAL.
    SELECT BUKRS   "公司代碼
           BELNR AS BELNR1
           BUZEI
           OBJNR   "對象號
           GJAHR   "年度
           REFBN AS BELNR   "憑證號
           BUDAT   "記賬日期
           KSTAR   "成本要素
           WOGBTR  "本位幣
           SGTXT
    FROM COVP
    INTO CORRESPONDING FIELDS OF TABLE TAB_G_COVP
    FOR ALL ENTRIES IN TAB_G_PROJ
    WHERE KOKRS = 'YHGP' "控制范圍
      AND LEDNR = '00'
      AND BUKRS = TAB_G_PROJ-VBUKR "公司
      AND OBJNR = TAB_G_PROJ-OBJNR "對象
      AND VERSN = '000'
      AND AWTYP = 'BKPF'
      AND WRTTP = '04'
      AND BUDAT < G_DATE "憑證日期
      AND AWREF_REV = ''
              %_HINTS
        DB2    '&SUBSTITUTE VALUES&'
        ORACLE '&SUBSTITUTE VALUES&'.
  ENDIF.

*成本要素
  IF TAB_G_COVP[] IS NOT INITIAL.
    SELECT SAKNR   "成本要素
           TXT20   "成本要素名稱
    FROM SKAT
    INTO TABLE TAB_G_SKAT
    FOR ALL ENTRIES IN TAB_G_COVP
    WHERE KTOPL = 'YHGP'  "控制范圍
      AND SPRAS = SY-LANGU "語言
      AND SAKNR = TAB_G_COVP-KSTAR.   "成本要素
  ENDIF.

  LOOP AT TAB_G_COVP.
*判斷是否有現金,銀行科目
    SELECT SINGLE *
    FROM BSEG
    WHERE BUKRS = TAB_G_COVP-BUKRS  "公司
      AND BELNR = TAB_G_COVP-BELNR  "憑證號
      AND GJAHR = TAB_G_COVP-GJAHR  "年度
      AND HKONT BETWEEN '0002000001' AND '0002109999'."科目
    IF SY-SUBRC <> 0.
*判斷是否有供應商
      SELECT SINGLE *
      FROM BSEG
      WHERE BUKRS = TAB_G_COVP-BUKRS "公司
        AND BELNR = TAB_G_COVP-BELNR "憑證號
        AND GJAHR = TAB_G_COVP-GJAHR "年度
        AND LIFNR <> ''.             "供應商
      IF SY-SUBRC <> 0.
        DELETE TAB_G_COVP.
      ELSE.
*成本要素名稱
        READ TABLE TAB_G_SKAT WITH KEY SAKNR = TAB_G_COVP-KSTAR.   "成本要素
        IF SY-SUBRC = 0.
          TAB_G_COVP-TXT20 = TAB_G_SKAT-TXT20."成本要素名稱
          MODIFY TAB_G_COVP.
        ENDIF.
      ENDIF.
    ELSE.
*成本要素名稱
      READ TABLE TAB_G_SKAT WITH KEY SAKNR = TAB_G_COVP-KSTAR.   "成本要素
      IF SY-SUBRC = 0.
        TAB_G_COVP-TXT20 = TAB_G_SKAT-TXT20."成本要素名稱
        MODIFY TAB_G_COVP.
      ENDIF.
    ENDIF.
    CLEAR:TAB_G_COVP.
  ENDLOOP.
  SORT TAB_G_COVP BY OBJNR BELNR GJAHR.
  APPEND LINES OF TAB_G_COVP TO TAB_G_COVPDEL.

  CLEAR: TAB_G_COVP-BELNR1,   "憑證號
         TAB_G_COVP-BUDAT,   "記賬日期
         TAB_G_COVP-KSTAR,   "成本要素
         TAB_G_COVP-SGTXT.   " 文本
  MODIFY TAB_G_COVP TRANSPORTING BELNR1 BUDAT KSTAR SGTXT
                          WHERE BELNR <> ''.
  SORT TAB_G_COVP BY OBJNR BELNR.

*憑證金額匯總
  LOOP AT TAB_G_COVP.
    COLLECT TAB_G_COVP INTO TAB_G_COVPSUM.
    APPEND TAB_G_COVPSUM.
  ENDLOOP.
*刪除為空的憑證
  DELETE TAB_G_COVPSUM WHERE BELNR = ''.


  CLEAR:TAB_G_OUT,TAB_G_OUT[].
*無PO憑證金額明細
  LOOP AT TAB_G_COVPSUM.
    READ TABLE TAB_G_PROJ WITH KEY OBJNR = TAB_G_COVPSUM-OBJNR.
    IF SY-SUBRC = 0.
      TAB_G_OUT-VBUKR  = TAB_G_PROJ-VBUKR.            "公司
      TAB_G_OUT-PSPID  = TAB_G_PROJ-PSPID.            "項目定義
      TAB_G_OUT-PSPHI  = TAB_G_PROJ-PSPHI.            "項目定義
      TAB_G_OUT-POST1  = TAB_G_PROJ-POST1.            "項目描述
      TAB_G_OUT-PSPNR  = TAB_G_PROJ-PSPNR.            "WBS號碼
      TAB_G_OUT-OBJNR  = TAB_G_PROJ-OBJNR.            "對象號
      TAB_G_OUT-POSID  = TAB_G_PROJ-POSID.            "WBS元素
      TAB_G_OUT-POST2  = TAB_G_PROJ-POST2.            "WBS描述
      TAB_G_OUT-STUFE  = TAB_G_PROJ-STUFE.            "層次
    ENDIF.
*合並同WBS元素及同一憑證不同行項目文本
    LOOP AT TAB_G_COVPDEL  WHERE OBJNR = TAB_G_COVPSUM-OBJNR
                             AND BELNR = TAB_G_COVPSUM-BELNR.
      IF TAB_G_OUT-TXZ01 IS INITIAL.
        CONCATENATE TAB_G_COVPDEL-TXT20 ';' TAB_G_COVPDEL-SGTXT INTO TAB_G_OUT-TXZ01.
      ELSE.
        CONCATENATE TAB_G_OUT-TXZ01 '/'  TAB_G_COVPDEL-TXT20 ';' TAB_G_COVPDEL-SGTXT INTO TAB_G_OUT-TXZ01.
      ENDIF.
      CLEAR:TAB_G_COVPDEL.
    ENDLOOP.
    TAB_G_OUT-EBELN = TAB_G_COVPSUM-BELNR.  "無PO憑證
    TAB_G_OUT-ZNETPR = TAB_G_COVPSUM-WOGBTR. "無PO金額
    TAB_G_OUT-GJAHR = TAB_G_COVPSUM-GJAHR.
    COLLECT TAB_G_OUT.
    CLEAR:TAB_G_OUT,TAB_G_COVPSUM,TAB_G_PROJ.
  ENDLOOP.

* PO金額明細
  LOOP AT TAB_G_EKPOSUM.
    READ TABLE TAB_G_PROJ WITH KEY PSPNR = TAB_G_EKPOSUM-PSPNR.
    IF SY-SUBRC = 0.
      TAB_G_OUT-VBUKR  = TAB_G_PROJ-VBUKR.            "公司
      TAB_G_OUT-PSPID  = TAB_G_PROJ-PSPID.            "項目定義
      TAB_G_OUT-PSPHI  = TAB_G_PROJ-PSPHI.            "項目定義
      TAB_G_OUT-POST1  = TAB_G_PROJ-POST1.            "項目描述
      TAB_G_OUT-PSPNR  = TAB_G_PROJ-PSPNR.            "WBS號碼
      TAB_G_OUT-OBJNR  = TAB_G_PROJ-OBJNR.            "對象號
      TAB_G_OUT-POSID  = TAB_G_PROJ-POSID.            "WBS元素
      TAB_G_OUT-POST2  = TAB_G_PROJ-POST2.            "WBS描述
      TAB_G_OUT-STUFE  = TAB_G_PROJ-STUFE.            "層次
    ENDIF.
* 取出PO項目文本
    LOOP AT TAB_G_EKPODEL WHERE PSPNR = TAB_G_EKPOSUM-PSPNR
                            AND EBELN = TAB_G_EKPOSUM-EBELN.
      IF TAB_G_OUT-TXZ01 IS INITIAL.
        TAB_G_OUT-TXZ01 = TAB_G_EKPODEL-TXZ01.
      ELSE.
        CONCATENATE TAB_G_OUT-TXZ01 '/' TAB_G_EKPODEL-TXZ01 INTO TAB_G_OUT-TXZ01.
      ENDIF.
      CLEAR:TAB_G_EKPODEL.
    ENDLOOP.

    TAB_G_OUT-EBELN = TAB_G_EKPOSUM-EBELN.  "PO號
    TAB_G_OUT-ZNETPR = TAB_G_EKPOSUM-NETPR. "PO金額(含稅)
    APPEND TAB_G_OUT.
    CLEAR:TAB_G_OUT,TAB_G_PROJ,TAB_G_EKPOSUM.
  ENDLOOP.

  SORT TAB_G_OUT BY PSPHI PSPNR.
  CLEAR:G_NETPR,TAB_G_OUTSUM,TAB_G_OUTSUM[],G_NETPRSUM.
*匯總憑證及PO金額
  LOOP AT TAB_G_OUT.
    G_NETPR = G_NETPR + TAB_G_OUT-ZNETPR.  "WBS金額匯總
    G_NETPRSUM = G_NETPRSUM + TAB_G_OUT-ZNETPR. "項目金額匯總
*匯總同一WBS的憑證及PO金額
    AT END OF PSPNR.
      TAB_G_OUTSUM-PSPNR = TAB_G_OUT-PSPNR.
      TAB_G_OUTSUM-ZNETPR = G_NETPR.
      APPEND TAB_G_OUTSUM.
      CLEAR:G_NETPR,TAB_G_OUTSUM.
    ENDAT.
*匯總同一項目憑證及PO金額
    AT END OF PSPHI.
      TAB_G_OUTSUM-PSPHI = TAB_G_OUT-PSPHI.
      TAB_G_OUTSUM-ZNETPR = G_NETPRSUM.
      APPEND TAB_G_OUTSUM.
      CLEAR:G_NETPRSUM,TAB_G_OUTSUM.
    ENDAT.
  ENDLOOP.

*無憑證的WBS元素
  SORT TAB_G_PROJ BY PSPID POSID.
  APPEND LINES OF TAB_G_PROJ TO TAB_G_OUT.
  SORT TAB_G_OUT BY PSPID POSID EBELN.

  CLEAR:TAB_G_OUTDEL,TAB_G_OUTDEL[],G_CONUT,G_PSPHI.
  LOOP AT TAB_G_OUT.
*計算同一項目的WBS行數
    G_CONUT = G_CONUT + 1.
    IF G_PSPHI <> TAB_G_OUT-PSPHI."不同項目時行數為1
      G_CONUT = 1.
    ENDIF.
    TAB_G_OUT-CON = G_CONUT.

*層級關系
    READ TABLE TAB_G_PSHI WITH KEY  POSNR = TAB_G_OUT-PSPNR.
    IF SY-SUBRC = 0.
      TAB_G_OUT-UP = TAB_G_PSHI-UP.
    ENDIF.

*PO和憑證為空時代表此行為同一WBS多憑證和PO的匯總行.
    IF TAB_G_OUT-EBELN = ''.
      READ TABLE TAB_G_OUTDEL WITH KEY OBJNR = TAB_G_OUT-OBJNR.
      IF SY-SUBRC <> 0.
        APPEND TAB_G_OUT TO TAB_G_OUTDEL.
*項目預算
        SELECT SINGLE WTGES
        FROM BPGE
        INTO TAB_G_OUT-ZBMOUNT
        WHERE OBJNR = TAB_G_OUT-OBJNR
          AND WRTTP = '41'
          AND VORGA = 'KBUD'.
      ENDIF.

* 憑證及合同金額
      READ TABLE TAB_G_OUTSUM WITH KEY PSPNR = TAB_G_OUT-PSPNR.
      IF SY-SUBRC = 0.
        TAB_G_OUT-ZNETPR = TAB_G_OUTSUM-ZNETPR."憑證及合同金額
*差額=預算金額-憑證及PO金額
        TAB_G_OUT-ZEMOUNT = TAB_G_OUT-ZBMOUNT - TAB_G_OUTSUM-ZNETPR. "差額
      ELSE.
*無PO及憑證金額時,直接取預算金額
        TAB_G_OUT-ZEMOUNT = TAB_G_OUT-ZBMOUNT."差額
      ENDIF.
    ENDIF.

    IF TAB_G_OUT-STUFE = '1'."主項目相關處理
      READ TABLE TAB_G_OUTSUM WITH KEY PSPHI = TAB_G_OUT-PSPHI.
      IF SY-SUBRC = 0.
        TAB_G_OUT-ZNETPR = TAB_G_OUTSUM-ZNETPR."憑證及合同金額
*差額=預算金額-憑證及PO金額
        TAB_G_OUT-ZEMOUNT = TAB_G_OUT-ZBMOUNT - TAB_G_OUTSUM-ZNETPR."差額
      ELSE.
*無PO及憑證金額時,直接取預算金額
        TAB_G_OUT-ZEMOUNT = TAB_G_OUT-ZBMOUNT."差額
      ENDIF.

*讀取工程相關數據
      SELECT SINGLE EXPSUM        "預計完工金額
        FROM ZPS001
        INTO TAB_G_OUT-EXPSUM
        WHERE PSPID = TAB_G_OUT-PSPID.
      TAB_G_OUT-ID = '@0E@'."主項目的展開標志
      TAB_G_OUT-COLOR = 'C310'."顏色設置
    ELSE.
      TAB_G_OUT-COLOR = 'C100'."顏色設置
    ENDIF.

* WBS相同時,憑證及PO號,描述放入WBS元素及WBS描述字段
    IF G_PSPNR = TAB_G_OUT-PSPNR.
      TAB_G_OUT-POSID = TAB_G_OUT-EBELN.
      TAB_G_OUT-POST2 = TAB_G_OUT-TXZ01.
      TAB_G_OUT-STUFE = TAB_G_OUT-STUFE + 1.
      TAB_G_OUT-COLOR = 'C101'."顏色設置
    ENDIF.

    G_PSPNR = TAB_G_OUT-PSPNR. "WBS編號
    G_PSPHI = TAB_G_OUT-PSPHI. "項目編號

    MODIFY TAB_G_OUT.
    CLEAR:TAB_G_OUT.
  ENDLOOP.

  SORT TAB_G_OUT BY VBUKR PSPHI STUFE DESCENDING.
  CLEAR:TAB_G_OUTID,TAB_G_OUTID[],G_NETPR,G_NETPRSUM,REC_G_OUT.

*把WBS元素的下層WBS元素的PO及憑證金額匯總放入上一層.
  LOOP AT TAB_G_OUT WHERE STUFE <> '1'
                       AND EBELN = ''.
    LOOP AT TAB_G_OUT INTO REC_G_OUT  WHERE UP = TAB_G_OUT-PSPNR
                                        AND EBELN = ''.
      G_NETPR = G_NETPR + REC_G_OUT-ZNETPR.
      CLEAR:REC_G_OUT.
    ENDLOOP.
    TAB_G_OUT-ZNETPR =  TAB_G_OUT-ZNETPR + G_NETPR.
    TAB_G_OUT-ZEMOUNT = TAB_G_OUT-ZBMOUNT - TAB_G_OUT-ZNETPR.
    MODIFY  TAB_G_OUT.
    CLEAR: G_NETPR,TAB_G_OUT.
  ENDLOOP.
  SORT TAB_G_OUT BY VBUKR PSPHI CON ASCENDING.

ENDFORM.                    " FRM_DATA_GET
*&---------------------------------------------------------------------*
*&      Form  CHANGE_TOOLBAR
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*  -->  p1        text
*  <--  p2        text
*----------------------------------------------------------------------*
FORM CHANGE_TOOLBAR .

  CALL METHOD G_ALV_TREE->GET_TOOLBAR_OBJECT
    IMPORTING
      ER_TOOLBAR = G_TOOLBAR.

  CHECK NOT G_TOOLBAR IS INITIAL. "could happen if you do not use the
  "standard toolbar

  CALL METHOD G_TOOLBAR->ADD_BUTTON
    EXPORTING
      FCODE     = ''
      ICON      = ''
      BUTN_TYPE = CNTB_BTYPE_SEP.

* add Standard Button to toolbar (for Delete Subtree)
  CALL METHOD G_TOOLBAR->ADD_BUTTON
    EXPORTING
      FCODE     = 'XIZA'
      ICON      = '@49@'
      BUTN_TYPE = CNTB_BTYPE_BUTTON
      TEXT      = '下載數據'
      QUICKINFO = TEXT-901.   "Delete subtree
ENDFORM.                    " CHANGE_TOOLBAR
*&---------------------------------------------------------------------*
*&      Form  REGISTER_EVENTS_TOOLBAR
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*  -->  p1        text
*  <--  p2        text
*----------------------------------------------------------------------*
FORM REGISTER_EVENTS_TOOLBAR .
  DATA: IT_EVENTS TYPE CNTL_SIMPLE_EVENTS,
        I_EVENT TYPE CNTL_SIMPLE_EVENT,
        I_EVENT_RECEIVER TYPE REF TO LCL_TOOLBAR_EVENT_RECEIVER.

  CALL METHOD G_ALV_TREE->GET_REGISTERED_EVENTS
    IMPORTING
      EVENTS = IT_EVENTS.

* register events on frontend
  CALL METHOD G_ALV_TREE->SET_REGISTERED_EVENTS
    EXPORTING
      EVENTS                    = IT_EVENTS
    EXCEPTIONS
      CNTL_ERROR                = 1
      CNTL_SYSTEM_ERROR         = 2
      ILLEGAL_EVENT_COMBINATION = 3.
  IF SY-SUBRC <> 0.
    MESSAGE X208(00) WITH 'ERROR'.                          "#EC NOTEXT
  ENDIF.

  CREATE OBJECT I_EVENT_RECEIVER.
  SET HANDLER I_EVENT_RECEIVER->ON_FUNCTION_SELECTED FOR G_TOOLBAR.
ENDFORM.                    " REGISTER_EVENTS_TOOLBAR
*&---------------------------------------------------------------------*
*&      Form  XIZA_DATA
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*  -->  p1        text
*  <--  p2        text
*----------------------------------------------------------------------*
FORM XIZA_DATA .
  DATA: V_PASS_PATH1 LIKE RLGRAP-FILENAME .
  DATA: V_PASS_PATH TYPE STRING .
  DATA: FILENAME TYPE STRING .
  DATA: ACTION TYPE I.
  DATA:G_STUFE LIKE PRPS-STUFE.

*抬頭數據
  CLEAR:TAB_G_XIZA,TAB_G_XIZA[],GS_FCAT.
  TAB_G_XIZA-TEXT = 'WBS元素/合同號/憑證號'.
  APPEND TAB_G_XIZA.
  LOOP AT GT_FCAT INTO GS_FCAT.
    TAB_G_XIZA-TEXT = GS_FCAT-SELTEXT.
    APPEND TAB_G_XIZA.
    CLEAR:GS_FCAT,TAB_G_XIZA.
  ENDLOOP.

*項目數據
  CLEAR:TAB_G_XIZAITEM,TAB_G_XIZAITEM[],GS_WBS,G_STUFE.
  LOOP AT GT_WBS INTO GS_WBS.
    IF  G_STUFE IS NOT INITIAL.
      IF GS_WBS-STUFE = 1.
        IF GS_WBS-STUFE <> G_STUFE.
          APPEND TAB_G_XIZAITEM.
        ENDIF.
      ENDIF.
    ENDIF.
    TAB_G_XIZAITEM-POSID   = GS_WBS-POSID. "WBS元素
    TAB_G_XIZAITEM-POST2   = GS_WBS-POST2. "WBS描述
    TAB_G_XIZAITEM-ZBMOUNT = GS_WBS-ZBMOUNT."預算金額(Budget)
    TAB_G_XIZAITEM-ZNETPR  = GS_WBS-ZNETPR. "PO總金額(含稅)
    TAB_G_XIZAITEM-ZEMOUNT = GS_WBS-ZEMOUNT."剩余預算金額
    TAB_G_XIZAITEM-EXPSUM  = GS_WBS-EXPSUM. "預計完工金額

    CONDENSE:TAB_G_XIZAITEM-ZBMOUNT,TAB_G_XIZAITEM-ZNETPR,TAB_G_XIZAITEM-EXPSUM, TAB_G_XIZAITEM-ZEMOUNT.
    APPEND TAB_G_XIZAITEM.
    G_STUFE = GS_WBS-STUFE.
    CLEAR:GS_WBS,TAB_G_XIZAITEM.
  ENDLOOP.

  CLEAR FILENAME .
  CALL FUNCTION 'GUI_FILE_SAVE_DIALOG'
    EXPORTING
      FILE_FILTER       = '.XLS'
      DEFAULT_EXTENSION = 'DAT'
      DEFAULT_FILE_NAME = 'PS項目工程月報表'
    IMPORTING
      FULLPATH          = V_PASS_PATH
      USER_ACTION       = ACTION.
  IF ACTION <> 9 .
    V_PASS_PATH1 = V_PASS_PATH .
    CALL FUNCTION 'MS_EXCEL_OLE_STANDARD_DAT'
      EXPORTING
        FILE_NAME  = V_PASS_PATH1
      TABLES
        DATA_TAB   = TAB_G_XIZAITEM[]
        FIELDNAMES = TAB_G_XIZA.
  ENDIF.
ENDFORM.                    " XIZA_DATA

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM