********************************************************************
* 事务代码:ZFIR004 *
* 程序名称:ZFIR004 *
* 程序目的:项目进度表 *
* 设 计 人: *
* 开 发 人:Seele *
* 设计时间:2022-09-19 *
* 程序类型: ABAP/4 程序 *
* 应用类型: FI *
* 描 述: 项目进度表 *
*(修改日志)--------------------------------------------------------*
* *
* 日志号 修改人 修改时间 修改说明 传输号码 *
* ---- ---- ------ -----------
* 001 Seele 2022-09-19 创建程序 DS4K900374 *
********************************************************************
REPORT zfir004.
*----------------------------------------------------------------------*
* 数据库表声明/Database table declaration
*----------------------------------------------------------------------*
TABLES:prps. " WBS(工作中断结构) 元素主数据
*----------------------------------------------------------------------*
* 结构声明类型/Structure type declaration
*----------------------------------------------------------------------*
*&---主表数据/master table data
TYPES:BEGIN OF ty_main,
posid TYPE prps-posid, " WBS元素
post1 TYPE prps-post1, " WBS描述
prart TYPE prps-prart, " 项目类型
txt30 TYPE tj02t-txt30, " 项目状态
psphi TYPE prps-psphi, " 项目定义
post1j TYPE proj-post1, " 项目定义描述
fkstl TYPE prps-fkstl, " 负责的成本中心
pbukr TYPE prps-pbukr, " 公司代码
verna TYPE prps-verna, " 项目负责人
wtjhr_y TYPE bpja-wtjhr, " 预算金额
wtjhr_x TYPE bpja-wtjhr, " 已下达预算
wtjhr_h TYPE bpja-wtjhr, " 已花费预算
gjahr TYPE acdoca-gjahr, " 会计年度
poper TYPE acdoca-poper, " 期间
total TYPE acdoca-ksl, " 小计
END OF ty_main.
TYPES:BEGIN OF ty_config,
account_name TYPE zfit004-account_name, " 成本要素组
account_from TYPE zfit004-account_from, " 从成本要素
account_to TYPE zfit004-account_to , " 到成本要素
END OF ty_config.
TYPES:BEGIN OF ty_acdoca,
* rldnr TYPE acdoca-rldnr, " 分类账
* rbukrs TYPE acdoca-rbukrs, " 公司代码
* gjahr TYPE acdoca-gjahr, " 会计年度
* belnr TYPE acdoca-belnr, " 凭证编号
* docln TYPE acdoca-docln, " 行项目
ksl TYPE acdoca-ksl , "
ps_posid TYPE acdoca-ps_posid, " WBS元素
* ksl TYPE acdoca-ksl, " 本币金额
END OF ty_acdoca.
* 保存内表的字段名称
TYPES:BEGIN OF ty_field,
fieldnm TYPE txt30,
END OF ty_field.
*----------------------------------------------------------------------*
* 全局变量定义/Global variable definition
*----------------------------------------------------------------------*
*&---全局内表定义
DATA:gt_main TYPE STANDARD TABLE OF ty_main. " 主数据表
DATA:gt_config TYPE STANDARD TABLE OF ty_config. " 配置表
DATA:gt_acdoca TYPE STANDARD TABLE OF ty_acdoca.
DATA:gt_field TYPE STANDARD TABLE OF ty_field. " 动态内表字段列表
DATA:gr_toutput TYPE REF TO data, " 动态内表
gr_soutput TYPE REF TO data. " 动态工作区
*&---全局结构定义
DATA:gs_main TYPE ty_main. " 主数据结构
DATA:gs_config TYPE ty_config. " 配置表结构
DATA:gs_acdoca TYPE ty_acdoca. " 合计
*&---------------------------------------------------------------------*
*& 字段串定义/Field-symbols *
*&---------------------------------------------------------------------*
FIELD-SYMBOLS:<fs_main> TYPE ty_main,
<fs_toutput> TYPE table, " ALV动态内表
<fs_soutput> TYPE ANY, " ALV动态工作区
<fs_foutput> TYPE ANY. " ALV动态表头
*&---------------------------------------------------------------------*
*& ALV TYPE/ALV 类型定义
*&---------------------------------------------------------------------*
*&---ALV数据组,类型池
TYPE-POOLS:slis,
vrm.
*&---定义ALV显示的字段列及其描述等属性
DATA:gt_fieldcat TYPE STANDARD TABLE OF lvc_s_fcat, " ALV 控制: 字段目录
gs_fieldcat TYPE lvc_s_fcat, " ALV 控制: 字段目录
gs_layout TYPE lvc_s_layo. " ALV 控制: 布局结构
*&---------------------------------------------------------------------*
*& Macro 宏定义
*&---------------------------------------------------------------------*
DEFINE mcr_set_catalog.
gs_fieldcat-fieldname = &1. " 字段技术名称
gs_fieldcat-coltext = &2. " 显示名称
gs_fieldcat-ref_table = &3. " 参照表
gs_fieldcat-ref_field = &4. " 参照表字段
gs_fieldcat-qfieldname = &5. " 参考计量单位的字段名称
gs_fieldcat-key = &6. " key 值
gs_fieldcat-edit = &7. " 可编辑
APPEND gs_fieldcat TO gt_fieldcat.
CLEAR gs_fieldcat.
END-OF-DEFINITION.
*&---------------------------------------------------------------------*
*& Selection Screen/选择屏幕
*&---------------------------------------------------------------------*
*&---选择屏幕块
SELECTION-SCREEN BEGIN OF BLOCK blk01 WITH FRAME TITLE TEXT-101.
*&---范围
SELECT-OPTIONS:s_pbukr FOR prps-pbukr, " 公司代码
s_posid FOR prps-posid. " WBS元素
*&---单值
PARAMETERS:p_gjahr LIKE acdoca-gjahr OBLIGATORY DEFAULT sy-datum+0(4), " 会计年度
p_poper LIKE acdoca-poper OBLIGATORY DEFAULT sy-datum+4(2). " 期间
SELECTION-SCREEN END OF BLOCK blk01.
*&---------------------------------------------------------------------*
*& Start-of-selection/开始选择屏幕 *
*&---------------------------------------------------------------------*
START-OF-SELECTION.
*&---内表数据获取
PERFORM frm_get_data.
IF gt_main IS INITIAL.
MESSAGE s001(zfi001). " 未查找到符合条件的数据
EXIT.
ENDIF.
*&---------------------------------------------------------------------*
*& end-of-selection/结束选择屏幕(程序结束处理,输出等) *
*&---------------------------------------------------------------------*
END-OF-SELECTION.
*&===ALV 输出
*&---设置ALV输出格式
PERFORM frm_init_layout.
*&---设置ALV输出字段
PERFORM frm_set_fieldcat.
*&---设置
*&---ALV 显示
PERFORM frm_display_alv.
*&---------------------------------------------------------------------*
*& Form frm_get_data
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
* -->P_10 text
*----------------------------------------------------------------------*
FORM frm_get_data.
FREE:gt_main.
*&---获取主数据表内容PRPS PROJ
SELECT
prps~posid, " WBS元素
prps~post1, " WBS描述
prps~prart, " 项目类型
prps~psphi, " 项目定义
prps~fkstl, " 负责的成本中心
prps~pbukr, " 公司代码
prps~verna, " 项目负责人
prps~objnr, " 对象编号
proj~post1 AS post1j " 项目定义描述
FROM prps
LEFT JOIN proj ON prps~pspnr = proj~pspnr
WHERE
prps~pbukr IN @s_pbukr AND
prps~posid IN @s_posid
INTO TABLE @DATA(lt_data).
*&---主数据表为空则终止取数
IF sy-subrc <> 0.
EXIT.
ENDIF.
*&---主数据表属性信息获取
IF lt_data IS NOT INITIAL.
*&---项目状态
SELECT
tj02t~txt30, " 项目状态
jest~stat, " 对象状态
jest~objnr " 对象编号
FROM jest
LEFT JOIN tj02t ON jest~stat = tj02t~istat
FOR ALL ENTRIES IN @lt_data
WHERE
jest~stat IN ( 'I0001','I0002','I0045','I0046','I0076' ) AND
tj02t~spras = @sy-langu AND
jest~objnr = @lt_data-objnr
INTO TABLE @DATA(lt_jest).
SORT lt_jest BY objnr.
*&---预算金额 已下达预算 已花费预算
SELECT
objnr, " 对象编号
wrttp, " 值类型
wtjhr " 业务货币中的年度值
FROM bpja
FOR ALL ENTRIES IN @lt_data
WHERE
objnr = @lt_data-objnr AND
wrttp IN ( '41','45','42' )
INTO TABLE @DATA(lt_bpja).
SORT lt_bpja BY objnr wrttp.
ENDIF.
*&---主表数据组织
*&---循环内表,赋值物料组,物料描述
LOOP AT lt_data INTO DATA(ls_data).
*&---初始化
CLEAR gs_main.
*&---赋值主数据
MOVE-CORRESPONDING ls_data TO gs_main.
gs_main-gjahr = p_gjahr.
gs_main-poper = p_poper.
*&---赋值项目状态
READ TABLE lt_jest INTO DATA(ls_jest) WITH KEY objnr = ls_data-objnr BINARY SEARCH.
IF sy-subrc = 0.
MOVE-CORRESPONDING ls_jest TO gs_main.
ENDIF.
*&---赋值预算金额
READ TABLE lt_bpja INTO DATA(ls_bpja) WITH KEY objnr = ls_data-objnr wrttp = '41' BINARY SEARCH.
IF sy-subrc = 0.
gs_main-wtjhr_y = ls_bpja-wtjhr.
ENDIF.
*&---赋值已下达预算
READ TABLE lt_bpja INTO ls_bpja WITH KEY objnr = ls_data-objnr wrttp = '45' BINARY SEARCH.
IF sy-subrc = 0.
gs_main-wtjhr_x = ls_bpja-wtjhr.
ENDIF.
*&---赋值已花费预算
READ TABLE lt_bpja INTO ls_bpja WITH KEY objnr = ls_data-objnr wrttp = '42' BINARY SEARCH.
IF sy-subrc = 0.
gs_main-wtjhr_h = ls_bpja-wtjhr.
ENDIF.
APPEND gs_main TO gt_main.
ENDLOOP.
SORT gt_main BY posid.
ENDFORM. " frm_get_data
*&---------------------------------------------------------------------*
*& Form frm_init_layout
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
* --> p1 text
* <-- p2 text
*----------------------------------------------------------------------*
FORM frm_init_layout .
CLEAR gs_layout.
gs_layout-zebra = 'X' . " 斑马线
gs_layout-cwidth_opt = 'X' . " 自动调整ALVL列宽
gs_layout-sel_mode = 'A' . " 选择行列
ENDFORM. " frm_init_layout
*&---------------------------------------------------------------------*
*& Form frm_fieldcat
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
* --> p1 text
* <-- p2 text
*----------------------------------------------------------------------*
FORM frm_set_fieldcat .
DATA: lt_key TYPE STANDARD TABLE OF ty_config.
DATA: lv_fieldname TYPE string.
DATA: lr_descr TYPE REF TO cl_abap_structdescr.
*&---配置表中取出动态表头
SELECT
account_name
account_from
account_to
FROM zfit004
INTO CORRESPONDING FIELDS OF TABLE gt_config.
SORT gt_config BY account_name.
lt_key = gt_config.
DELETE ADJACENT DUPLICATES FROM lt_key COMPARING account_name.
*&---ALV 输出字段目录,涉及字段必须大写
mcr_set_catalog: 'POSID' TEXT-A01 'PRPS' 'POSID' '' 'X' '', " WBS元素
'POST1' TEXT-A02 'PRPS' 'POST1' '' 'X' '', " WBS描述
'PRART' TEXT-A03 'PRPS' 'PRART' '' '' '', " 项目类型
'TXT30' TEXT-A04 'TJ02T' 'TXT30' '' '' '', " 项目状态
'PSPHI' TEXT-A05 'PRPS' 'PSPHI' '' '' '', " 项目定义
'POST1J' TEXT-A06 'PROJ' 'POST1' '' '' '', " 项目定义描述
'FKSTL' TEXT-A07 'PRPS' 'FKSTL' '' '' '', " 负责的成本中心
'PBUKR' TEXT-A08 'PRPS' 'PBUKR' '' '' '', " 公司代码
'VERNA' TEXT-A09 'PRPS' 'VERNA' '' '' '', " 项目负责人
'WTJHR_Y' TEXT-A10 'BPJA' 'WTJHR' '' '' '', " 预算金额
'WTJHR_X' TEXT-A11 'BPJA' 'WTJHR' '' '' '', " 已下达预算
'WTJHR_H' TEXT-A12 'BPJA' 'WTJHR' '' '' '', " 已花费预算
'GJAHR' TEXT-A13 'ACDOCA' 'GJAHR' '' '' '', " 会计年度
'POPER' TEXT-A14 'ACDOCA' 'POPER' '' '' ''. " 期间
* 'KSL' TEXT-A16 'ACDOCA' 'KSL' '' '' ''. " 本币金额
*&---ALV 增加动态表头
LOOP AT lt_key INTO gs_config.
lv_fieldname = 'KSL' && sy-tabix.
mcr_set_catalog: lv_fieldname gs_config-account_name 'ACDOCA' 'KSL' '' '' ''. " 成本要素组-->本币金额
ENDLOOP.
mcr_set_catalog: 'TOTAL' TEXT-A15 'ACDOCA' 'KSL' '' '' ''. " 小计
*&---创建动态内表
CALL METHOD cl_alv_table_create=>create_dynamic_table
EXPORTING
it_fieldcatalog = gt_fieldcat
IMPORTING
ep_table = gr_toutput.
ASSIGN gr_toutput->* TO <fs_toutput>. " 分配生成的内表地址给指针
CREATE DATA gr_soutput LIKE LINE OF <fs_toutput>.
ASSIGN gr_soutput->* TO <fs_soutput>. " 分配生成的工作区地址给指针
PERFORM frm_process_data.
ENDFORM. " frm_fieldcat
*&---------------------------------------------------------------------*
*& Form frm_display_alv
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
* --> p1 text
* <-- p2 text
*----------------------------------------------------------------------*
FORM frm_display_alv .
*&---ALV 显示函数
CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY_LVC'
EXPORTING
i_callback_program = sy-repid
is_layout_lvc = gs_layout
it_fieldcat_lvc = gt_fieldcat[]
i_callback_pf_status_set = 'FRM_USER_STATUS'
i_default = 'X'
i_save = 'A'
TABLES
t_outtab = <fs_toutput>
EXCEPTIONS
program_error = 1
OTHERS = 2.
IF sy-subrc <> 0.
MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
ENDIF.
ENDFORM. " frm_display_alv
*&---------------------------------------------------------------------*
*& Form frm_user_status
*&---------------------------------------------------------------------*
* 设置用户菜单栏状态
*----------------------------------------------------------------------*
* --> pt_extab 需要排除的菜单按钮
* <-- p2 text
*----------------------------------------------------------------------*
FORM frm_user_status USING ps_extab TYPE slis_t_extab. "GUI
SET PF-STATUS 'STATUS_1000' EXCLUDING ps_extab.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form frm_process_data
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& --> p1 text
*& <-- p2 text
*&---------------------------------------------------------------------*
FORM frm_process_data .
RANGES lr_racct FOR acdoca-racct.
DATA: lv_fieldname TYPE string,
lv_tabix TYPE i,
lv_count TYPE i, " 动态内表字段计数(只针对科目余额)
ls_rracct LIKE LINE OF lr_racct,
lt_key TYPE STANDARD TABLE OF ty_config,
lt_acdoca TYPE STANDARD TABLE OF ty_acdoca.
FIELD-SYMBOLS: <fs_ksl> TYPE ANY,
<fs_total> TYPE ANY.
*&---主数据转移至动态内表
SORT gt_main BY posid.
LOOP AT gt_main INTO gs_main.
MOVE-CORRESPONDING gs_main TO <fs_soutput>.
APPEND <fs_soutput> TO <fs_toutput>.
ENDLOOP.
*&---汇总相同类型行项目
lt_key = gt_config.
SORT lt_key BY account_name.
SORT gt_config BY account_name.
DELETE ADJACENT DUPLICATES FROM lt_key COMPARING account_name.
*&---汇总科目余额相同的区间至range
LOOP AT lt_key INTO DATA(ls_key).
READ TABLE gt_config TRANSPORTING NO FIELDS WITH KEY account_name = ls_key-account_name BINARY SEARCH.
IF sy-subrc = 0.
lv_tabix = sy-tabix.
CLEAR lr_racct[].
LOOP AT gt_config INTO gs_config FROM lv_tabix.
IF gs_config-account_name <> ls_key-account_name.
EXIT.
ENDIF.
CLEAR ls_rracct.
ls_rracct-low = gs_config-account_from.
ls_rracct-high = gs_config-account_to.
ls_rracct-option = 'BT'.
ls_rracct-sign = 'I'.
APPEND ls_rracct TO lr_racct.
ENDLOOP.
ENDIF.
*---根据range获取表动态内表数据
lv_count = lv_count + 1.
SELECT
rldnr ,
rbukrs ,
gjahr ,
belnr ,
docln ,
ps_posid,
ksl ,
ksl
FROM acdoca
FOR ALL ENTRIES IN @gt_main
WHERE
ps_posid = @gt_main-posid AND
rbukrs = @gt_main-pbukr AND
poper = @p_poper AND
gjahr = @p_gjahr AND
racct IN @lr_racct
INTO CORRESPONDING FIELDS OF TABLE @lt_acdoca.
CLEAR gt_acdoca.
LOOP AT lt_acdoca INTO DATA(ls_acdoca).
MOVE-CORRESPONDING ls_acdoca TO gs_acdoca.
COLLECT gs_acdoca INTO gt_acdoca.
ENDLOOP.
*---根据变量名<fs_soutput>-ksl*动态给成本要素组赋值
LOOP AT gt_acdoca INTO ls_acdoca.
READ TABLE gt_main TRANSPORTING NO FIELDS WITH KEY posid = ls_acdoca-ps_posid BINARY SEARCH.
IF sy-subrc = 0.
lv_tabix = sy-tabix.
MOVE-CORRESPONDING ls_acdoca TO <FS_SOUTPUT>.
READ TABLE <fs_toutput> ASSIGNING <fs_soutput> INDEX lv_tabix. " <fs_toutput> 和 gt_main 具有相同的顺序,所以直接取对应位置
IF sy-subrc = 0.
lv_fieldname = '<FS_SOUTPUT>-' && 'KSL' && lv_count.
ASSIGN (lv_fieldname) TO <fs_ksl>. " 静态编译,将动态内表ksl*的值赋值给<fs_ksl>
<fs_ksl> = ls_acdoca-ksl. " 操作<fs_ksl>就等同于操作<fs_soutput>-ksl*
lv_fieldname = '<FS_SOUTPUT>-TOTAL'.
ASSIGN (lv_fieldname) TO <fs_total>.
<fs_total> = <fs_total> + ls_acdoca-ksl. " 合计
ENDIF.
ENDIF.
ENDLOOP.
ENDLOOP.
ENDFORM.
ABAP 动态内表模板
于 2022-09-29 13:10:58 首次发布