提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
前言
以前给Canada客户开发过基于国际会计准则的P&L,B&S动态报表,并且基于实际核算和预算的角度,如果大家有需要可以直接使用,报表内容完全可配置无需二次开发
提示:以下是本篇文章正文内容,下面案例可供参考
一、Front
二、Code
因为Canada客户的系统已经登不上了,所以自己又重新实现了一遍
REPORT ZXXX.
* -----------------------------------------------------------------------
* TABLES
* -----------------------------------------------------------------------
TABLES: bkpf.
* -----------------------------------------------------------------------
* DATA
* -----------------------------------------------------------------------
DATA: gs_pro_los TYPE ztfi017,
gt_pro_los TYPE TABLE OF ztfi017,
gs_assets TYPE ztfi017,
gt_assets TYPE TABLE OF ztfi017.
DATA: gv_num TYPE i,
gv_flag TYPE i,
gv_flag1 TYPE i,
gv_fieldcat_lines TYPE i.
DATA: gr_table TYPE REF TO data,
gr_wa TYPE REF TO data,
gs_budget TYPE ztfm001,
gt_budget TYPE TABLE OF ztfm001.
DATA: gt_earn1 TYPE TABLE OF faglflext-hsl01,
gs_earn1 LIKE LINE OF gt_earn1.
FIELD-SYMBOLS: <gf_table> TYPE STANDARD TABLE,
<gf_wa> TYPE any.
* -----------------------------------------------------------------------
* P A R A M E T E R S & S E L E C T - O P T I O N S
* -----------------------------------------------------------------------
SELECTION-SCREEN BEGIN OF BLOCK bk1 WITH FRAME TITLE TEXT-001.
SELECT-OPTIONS: s_bukrs FOR bkpf-bukrs,
s_gjahr FOR bkpf-gjahr,
s_monat FOR bkpf-monat.
SELECTION-SCREEN END OF BLOCK bk1.
SELECTION-SCREEN BEGIN OF BLOCK bk2 WITH FRAME TITLE TEXT-002.
PARAMETERS: rb1 TYPE c RADIOBUTTON GROUP r1 USER-COMMAND uc1 DEFAULT 'X', "资产负债表
rb2 TYPE c RADIOBUTTON GROUP r1. "损益表
SELECTION-SCREEN END OF BLOCK bk2.
SELECTION-SCREEN BEGIN OF BLOCK bk4 WITH FRAME TITLE TEXT-003.
PARAMETERS: rb5 TYPE c RADIOBUTTON GROUP r3 USER-COMMAND uc3 DEFAULT 'X', "只显示实际
rb6 TYPE c RADIOBUTTON GROUP r3, "只显示预算
rb7 TYPE c RADIOBUTTON GROUP r3. "显示预算与实际
SELECTION-SCREEN END OF BLOCK bk4.
* ----------------------------------------------------------------------*
* ALV层级关系定义
* ----------------------------------------------------------------------*
DATA: gs_layout TYPE lvc_s_layo.
DATA: gs_fieldcat TYPE lvc_s_fcat,
gt_fieldcat TYPE lvc_t_fcat,
gs_fieldcat_re TYPE lvc_s_fcat,
gt_fieldcat_re TYPE lvc_t_fcat,
gs_fieldcat_bu TYPE lvc_s_fcat,
gt_fieldcat_bu TYPE lvc_t_fcat.
* &---------------------------------------------------------------------*
* & Define marco
* &---------------------------------------------------------------------*
DEFINE marco_fieldacat.
&1 = &1 + 1.
gs_fieldcat-col_pos = &1.
gs_fieldcat-fieldname = &2.
gs_fieldcat-coltext = &3.
gs_fieldcat-icon = &4.
gs_fieldcat-no_zero = &5.
gs_fieldcat-checkbox = &6.
gs_fieldcat-ref_table = &7.
gs_fieldcat-ref_field = &8.
gs_fieldcat-edit = &9.
gs_fieldcat-parameter0 = 'X'.
APPEND gs_fieldcat TO gt_fieldcat.
END-OF-DEFINITION.
* &---------------------------------------------------------------------*
* & INITIALIZATION
* &---------------------------------------------------------------------*
INITIALIZATION.
* &---------------------------------------------------------------------*
* & START-OF-SELECTION
* &---------------------------------------------------------------------*
START-OF-SELECTION.
PERFORM frm_layout.
PERFORM frm_get_budget.
IF rb1 = 'X'.
gv_flag = 2.
gv_flag1 = 3.
PERFORM frm_set_fieldacat_assets.
PERFORM fm_get_dynamic_structure.
PERFORM frm_get_data_assets.
PERFORM frm_display_alv.
ELSE.
gv_flag = 4.
gv_flag1 = 5.
PERFORM frm_set_fieldacat_loss.
PERFORM fm_get_dynamic_structure.
PERFORM frm_get_data_profit_loss.
PERFORM frm_display_alv.
ENDIF.
END-OF-SELECTION.
* &---------------------------------------------------------------------*
* & Form FRM_SET_FIELDACAT_ASSETS
* &---------------------------------------------------------------------*
* & text
* &---------------------------------------------------------------------*
* & --> p1 text
* & <-- p2 text
* &---------------------------------------------------------------------*
FORM frm_set_fieldacat_assets .
DATA l_colpos TYPE lvc_s_fcat-col_pos VALUE 0.
CHECK gt_fieldcat IS INITIAL.
IF sy-langu EQ '1'.
marco_fieldacat:
l_colpos 'ZCOST' '成本要素' '' '' '' 'STXITFR' 'TDLINE' ''.
IF rb7 EQ 'X'.
marco_fieldacat:
l_colpos 'ZVARIANCE' '预算实际差异' '' '' '' 'ACDOCA' 'TSL' ''.
ENDIF.
ELSE.
marco_fieldacat:
l_colpos 'ZCOST' 'Cost Element' '' '' '' 'STXITFR' 'TDLINE' ''.
IF rb7 EQ 'X'.
marco_fieldacat:
l_colpos 'ZVARIANCE' 'Budget Actual Variance' '' '' '' 'ACDOCA' 'TSL' ''.
ENDIF.
ENDIF.
ENDFORM.
* &---------------------------------------------------------------------*
* & Form FRM_SET_FIELDACAT_
* &---------------------------------------------------------------------*
* & text
* &---------------------------------------------------------------------*
* & --> p1 text
* & <-- p2 text
* &---------------------------------------------------------------------*
FORM frm_set_fieldacat_loss .
DATA l_colpos TYPE lvc_s_fcat-col_pos VALUE 0.
CHECK gt_fieldcat IS INITIAL.
IF sy-langu = '1'.
marco_fieldacat:
l_colpos 'ZCOST' '成本要素' '' '' '' 'STXITFR' 'TDLINE' '',
l_colpos 'ZRETOTAL' '实际总计' '' '' '' 'ACDOCA' 'TSL' '',
l_colpos 'ZBUTOTAL' '预算总计' '' '' '' 'ACDOCA' 'TSL' ''.
IF rb7 EQ 'X'.
marco_fieldacat:
l_colpos 'ZVARIANCE' '预算实际差异' '' '' '' 'ACDOCA' 'TSL' ''.
ENDIF.
ELSE.
marco_fieldacat:
l_colpos 'ZCOST' 'Cost Elements' '' '' '' 'STXITFR' 'TDLINE' '',
l_colpos 'ZRETOTAL' 'Actual Total' '' '' '' 'ACDOCA' 'TSL' '',
l_colpos 'ZBUTOTAL' 'Budget Total' '' '' '' 'ACDOCA' 'TSL' ''.
IF rb7 EQ 'X'.
marco_fieldacat
l_colpos 'ZVARIANCE' 'Budget Actual Variance' '' '' '' 'ACDOCA' 'TSL' ''.
ENDIF.
ENDIF.
ENDFORM.
* &---------------------------------------------------------------------*
* & Form FRM_LAYOUT
* &---------------------------------------------------------------------*
* & text
* &---------------------------------------------------------------------*
* & --> p1 text
* & <-- p2 text
* &---------------------------------------------------------------------*
FORM frm_layout .
gs_layout-box_fname = 'ZSEL'.
gs_layout-zebra = 'X'.
gs_layout-cwidth_opt = 'X'."设置Grid的字段列宽度自动适应
ENDFORM.
*&---------------------------------------------------------------------*
*& Form FRM_GET_BUDGET
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& --> p1 text
*& <-- p2 text
*&---------------------------------------------------------------------*
FORM frm_get_budget .
SELECT
*
INTO CORRESPONDING FIELDS OF TABLE @gt_budget
FROM
ztfm001
WHERE
gjahr IN @s_gjahr AND
monat IN @s_monat.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form FM_GET_DYNAMIC_STRUCTURE
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& --> p1 text
*& <-- p2 text
*&---------------------------------------------------------------------*
FORM fm_get_dynamic_structure .
DATA: BEGIN OF ls_dygjahr,
gjahr TYPE bkpf-gjahr,
END OF ls_dygjahr.
DATA: BEGIN OF ls_dymonat,
monat TYPE bkpf-monat,
END OF ls_dymonat.
DATA: lt_dygjahr LIKE TABLE OF ls_dygjahr,
lt_dymonat LIKE TABLE OF ls_dymonat.
DATA: lv_num TYPE i,
lv_dygjahr_lines TYPE i,
lv_dymonat_lines TYPE i,
lv_index TYPE i,
lv_reality(10) TYPE c,
lv_budget(10) TYPE c,
lv_variance(10) TYPE c.
"获取年度
"单值
LOOP AT s_gjahr INTO DATA(ls_gjahr) WHERE option EQ 'EQ'.
IF NOT ls_gjahr-low IS INITIAL.
ls_dygjahr-gjahr = ls_gjahr-low.
ELSEIF NOT ls_gjahr-high IS INITIAL.
ls_dygjahr-gjahr = ls_gjahr-high.
ENDIF.
APPEND ls_dygjahr TO lt_dygjahr.
CLEAR:ls_gjahr , ls_dygjahr.
ENDLOOP.
"区间
READ TABLE s_gjahr INTO ls_gjahr WITH KEY option = 'BT'.
IF sy-subrc EQ 0.
lv_num = ls_gjahr-high - ls_gjahr-low.
IF lv_num GT 0.
DO lv_num + 1 TIMES.
ls_dygjahr-gjahr = ls_gjahr-low + sy-index - 1.
APPEND ls_dygjahr TO lt_dygjahr.
ENDDO.
ELSE.
ls_dygjahr-gjahr = ls_gjahr-low.
APPEND ls_dygjahr TO lt_dygjahr.
CLEAR ls_gjahr.
ENDIF.
CLEAR ls_gjahr.
ENDIF.
"去重
DELETE ADJACENT DUPLICATES FROM lt_dygjahr.
"获取行数
DESCRIBE TABLE lt_dygjahr LINES lv_dygjahr_lines.
"获取期间
"单值
LOOP AT s_monat INTO DATA(ls_monat) WHERE option EQ 'EQ'.
IF NOT ls_monat-low IS INITIAL.
ls_dymonat-monat = ls_monat-low.
ELSEIF NOT ls_monat-high IS INITIAL.
ls_dymonat-monat = ls_monat-high.
ENDIF.
APPEND ls_dymonat TO lt_dymonat.
CLEAR:ls_monat , ls_dymonat.
ENDLOOP.
CLEAR lv_num.
"区间
READ TABLE s_monat INTO ls_monat WITH KEY option = 'BT'.
IF sy-subrc = 0.
lv_num = ls_monat-high - ls_monat-low.
IF lv_num GT 0.
DO lv_num + 1 TIMES.
ls_dymonat-monat = ls_monat-low + sy-index - 1.
APPEND ls_dymonat TO lt_dymonat.
ENDDO.
ELSE.
ls_dymonat-monat = ls_monat-low.
APPEND ls_dymonat TO lt_dymonat.
CLEAR ls_monat.
ENDIF.
CLEAR ls_monat.
ENDIF.
"去重
DELETE ADJACENT DUPLICATES FROM lt_dymonat COMPARING monat.
"获取行数
DESCRIBE TABLE lt_dymonat LINES lv_dymonat_lines.
IF lv_dygjahr_lines NE 0 AND lv_dymonat_lines EQ 0.
lv_dymonat_lines = 12.
ENDIF.
DO 12 TIMES.
ls_dymonat-monat = sy-index.
APPEND ls_dymonat TO lt_dymonat.
CLEAR ls_dymonat.
ENDDO.
IF sy-langu EQ '1' .
lv_reality = '实际'.
lv_budget = '预算'.
ELSE.
lv_reality = 'Actual'.
lv_budget = 'Budget'.
lv_variance = 'Variance'.
ENDIF.
IF rb5 EQ 'X' OR rb7 EQ 'X'.
"创建动态fieldcat-实际
DO lv_dygjahr_lines TIMES.
READ TABLE lt_dygjahr INTO ls_dygjahr INDEX sy-index.
IF sy-subrc EQ 0.
DO lv_dymonat_lines TIMES.
READ TABLE lt_dymonat INTO ls_dymonat INDEX sy-index.
IF sy-subrc EQ 0.
gs_fieldcat-col_pos = gv_flag + lv_index + sy-index.
gs_fieldcat-fieldname = 'RE' && ls_dygjahr-gjahr && ls_dymonat-monat.
gs_fieldcat-coltext = lv_reality && ' ' && ls_dygjahr-gjahr && '-' && ls_dymonat-monat.
gs_fieldcat-dd_outlen = 50.
gs_fieldcat-ref_table = 'EKPO'.
gs_fieldcat-ref_field = 'NETWR'.
APPEND gs_fieldcat TO gt_fieldcat.
CLEAR:ls_dymonat , gs_fieldcat.
ENDIF.
IF lv_dymonat_lines EQ sy-index.
lv_index = lv_index + sy-index..
ENDIF.
ENDDO.
CLEAR ls_dygjahr.
ENDIF.
ENDDO.
ENDIF.
CLEAR lv_index.
IF rb6 EQ 'X' OR rb7 EQ 'X'.
"创建动态fieldcat-预算
DO lv_dygjahr_lines TIMES.
READ TABLE lt_dygjahr INTO ls_dygjahr INDEX sy-index.
IF sy-subrc EQ 0.
DO lv_dymonat_lines TIMES.
READ TABLE lt_dymonat INTO ls_dymonat INDEX sy-index.
IF sy-subrc EQ 0.
gs_fieldcat-col_pos = gv_flag + lv_index + sy-index.
gs_fieldcat-fieldname = 'BU' && ls_dygjahr-gjahr && ls_dymonat-monat.
gs_fieldcat-coltext = lv_budget && ' ' && ls_dygjahr-gjahr && '-' && ls_dymonat-monat.
gs_fieldcat-dd_outlen = 50.
gs_fieldcat-ref_table = 'EKPO'.
gs_fieldcat-ref_field = 'NETWR'.
APPEND gs_fieldcat TO gt_fieldcat.
CLEAR:ls_dymonat , gs_fieldcat.
ENDIF.
IF lv_dymonat_lines EQ sy-index.
lv_index = lv_index + sy-index..
ENDIF.
ENDDO.
CLEAR ls_dygjahr.
ENDIF.
ENDDO.
"创建动态fieldcat-期间实际预算差额
CLEAR lv_index.
DO lv_dygjahr_lines TIMES.
READ TABLE lt_dygjahr INTO ls_dygjahr INDEX sy-index.
IF sy-subrc EQ 0.
DO lv_dymonat_lines TIMES.
READ TABLE lt_dymonat INTO ls_dymonat INDEX sy-index.
IF sy-subrc EQ 0.
gs_fieldcat-col_pos = gv_flag + lv_index + sy-index.
gs_fieldcat-fieldname = 'ZVARIANCE' && ls_dygjahr-gjahr && ls_dymonat-monat.
gs_fieldcat-coltext = lv_variance && ' ' && ls_dygjahr-gjahr && '-' && ls_dymonat-monat.
gs_fieldcat-dd_outlen = 50.
gs_fieldcat-ref_table = 'EKPO'.
gs_fieldcat-ref_field = 'NETWR'.
APPEND gs_fieldcat TO gt_fieldcat.
CLEAR:ls_dymonat , gs_fieldcat.
ENDIF.
IF lv_dymonat_lines EQ sy-index.
lv_index = lv_index + sy-index..
ENDIF.
ENDDO.
CLEAR ls_dygjahr.
ENDIF.
ENDDO.
ENDIF.
DESCRIBE TABLE gt_fieldcat LINES gv_fieldcat_lines.
CLEAR gs_fieldcat.
"SEL
gs_fieldcat-col_pos = gv_fieldcat_lines + 1.
gs_fieldcat-fieldname = 'ZSEL'.
gs_fieldcat-coltext = 'ZSEL'.
gs_fieldcat-no_out = 'X'.
APPEND gs_fieldcat TO gt_fieldcat.
CLEAR gs_fieldcat.
"根据fieldcat生成内表
CALL METHOD cl_alv_table_create=>create_dynamic_table
EXPORTING
it_fieldcatalog = gt_fieldcat
IMPORTING
ep_table = gr_table
EXCEPTIONS
generate_subpool_dir_full = 1
OTHERS = 2.
"引用类型要使用必须先赋值给字符变量
ASSIGN gr_table->* TO <gf_table>.
"根据字段变量创建引用类型工作区
CREATE DATA gr_wa LIKE LINE OF <gf_table>.
"将引用类型工作区赋值给字符变量
ASSIGN gr_wa->* TO <gf_wa>.
"field拆分-实际/预算
LOOP AT gt_fieldcat INTO gs_fieldcat.
IF gs_fieldcat-fieldname CS 'RE' AND ( rb5 EQ 'X' OR rb7 EQ 'X' ).
MOVE-CORRESPONDING gs_fieldcat TO gs_fieldcat_re.
APPEND gs_fieldcat_re TO gt_fieldcat_re.
ELSEIF gs_fieldcat-fieldname CS 'BU' AND ( rb6 EQ 'X' OR rb7 EQ 'X' ).
MOVE-CORRESPONDING gs_fieldcat TO gs_fieldcat_bu.
APPEND gs_fieldcat_bu TO gt_fieldcat_bu.
ENDIF.
CLEAR: gs_fieldcat ,gs_fieldcat_re , gs_fieldcat_bu.
ENDLOOP.
CLEAR: gv_fieldcat_lines , lv_index.
ENDFORM.
* &---------------------------------------------------------------------*
* & Form FRM_GET_DATA_ASSETS
* &---------------------------------------------------------------------*
* & text
* &---------------------------------------------------------------------*
* & --> p1 text
* & <-- p2 text
* &---------------------------------------------------------------------*
FORM frm_get_data_assets.
DATA: lt_result TYPE match_result_tab,
lt_value TYPE TABLE OF string.
DATA: lv_index TYPE i,
lv_fieldname TYPE string,
lv_fieldname_index TYPE string,
lv_num(2) TYPE n,
lv_assets_sum TYPE faglflext-hslvt,
lv_last_sum TYPE faglflext-hslvt,
lv_fieldname1 TYPE string,
lv_assets_lines TYPE i,
lv_strlen TYPE i,
lv_result TYPE i,
lv_offset TYPE int4,
lv_length TYPE i,
lv_budget_sum TYPE faglflext-hslvt,
lv_fieldcat_lines_re TYPE i,
lv_fieldcat_lines_bu TYPE i,
lv_total_assets TYPE faglflext-hslvt,
lv_total_liabilities_equity TYPE faglflext-hslvt,
lv_re_sum TYPE faglflext-hslvt,
lv_bu_sum TYPE faglflext-hslvt,
lv_variant TYPE string,
lv_tmp TYPE faglflext-hslvt,
lv_acct TYPE c,
lv_value TYPE string,
lv_zcalc TYPE string.
DATA orf_1 TYPE REF TO cx_root.
FIELD-SYMBOLS: <lf>,
<lf_zcost>,
<lf_bukrs>,
<lf_bukrs_name>,
<lf_racct>,
<lf_racct_name>,
<lf_dy>,
<lf_lvt>,
<lf_waers>,
<lf_zvariance>,
<lf_re_peva>,
<lf_bu_peva>.
RANGES :r_racct FOR acdoca-racct.
lv_fieldname1 = 'FAGLFLEXT' && '-'.
"获取资产负债表格式
SELECT
*
INTO CORRESPONDING FIELDS OF TABLE @gt_assets
FROM
ztfi017
WHERE
ztype = '0'
ORDER BY zrow.
"成本要素文本补充空格
LOOP AT gt_assets INTO gs_assets.
DO gs_assets-zspace TIMES.
CONCATENATE '' gs_assets-zcost_text INTO gs_assets-zcost_text RESPECTING BLANKS.
ENDDO.
MODIFY gt_assets FROM gs_assets TRANSPORTING zcost_text.
CLEAR gs_assets.
ENDLOOP.
DESCRIBE TABLE gt_assets LINES lv_assets_lines.
"资产负债类
SELECT
faglflext~ryear,
faglflext~rbukrs,
faglflext~racct,
faglflext~kslvt,
faglflext~ksl01,
faglflext~ksl02,
faglflext~ksl03,
faglflext~ksl04,
faglflext~ksl05,
faglflext~ksl06,
faglflext~ksl07,
faglflext~ksl08,
faglflext~ksl09,
faglflext~ksl10,
faglflext~ksl11,
faglflext~ksl12,
faglflext~ksl13,
faglflext~ksl14,
faglflext~ksl15,
faglflext~ksl16,
faglflext~hslvt,
faglflext~hsl01,
faglflext~hsl02,
faglflext~hsl03,
faglflext~hsl04,
faglflext~hsl05,
faglflext~hsl06,
faglflext~hsl07,
faglflext~hsl08,
faglflext~hsl09,
faglflext~hsl10,
faglflext~hsl11,
faglflext~hsl12,
faglflext~hsl13,
faglflext~hsl14,
faglflext~hsl15,
faglflext~hsl16,
faglflext~rtcur AS waers,
t001~butxt AS zbukrs_name,
cskt~ktext AS zkostl_name,
skat~txt50 AS zracct_name
INTO TABLE @DATA(lt_faglflext)
FROM
faglflext
LEFT JOIN t001 ON faglflext~rbukrs EQ t001~bukrs
LEFT JOIN cskt ON faglflext~rcntr EQ cskt~kostl AND
cskt~kokrs EQ '1000' AND
cskt~spras EQ @sy-langu AND
cskt~datbi GE @sy-datum
LEFT JOIN skat ON faglflext~racct EQ skat~saknr AND
skat~ktopl EQ '1000' AND
skat~spras = @sy-langu
WHERE
rbukrs IN @s_bukrs AND
ryear IN @s_gjahr AND
( racct LIKE '1%' OR
racct LIKE '2%' OR
racct LIKE '4%' OR
racct LIKE '9%' )
ORDER BY rbukrs , ryear , rbukrs , racct.
DATA(lt_data) = lt_faglflext.
DELETE ADJACENT DUPLICATES FROM lt_data COMPARING rbukrs ryear rbukrs racct.
"获取fiedcat行数-实际
DESCRIBE TABLE gt_fieldcat_re LINES lv_fieldcat_lines_re.
"获取fiedcat行数-预算
DESCRIBE TABLE gt_fieldcat_bu LINES lv_fieldcat_lines_bu.
DO lv_assets_lines TIMES.
IF sy-index EQ 1.
gv_fieldcat_lines = gv_fieldcat_lines - gv_flag1.
ENDIF.
"输出报表样式赋值
READ TABLE gt_assets INTO gs_assets INDEX sy-index.
IF sy-subrc EQ 0.
SHIFT gs_assets-zglacct LEFT DELETING LEADING space.
ASSIGN COMPONENT 'ZCOST' OF STRUCTURE <gf_wa> TO <lf_zcost>.
IF <lf_zcost> IS ASSIGNED.
<lf_zcost> = gs_assets-zcost_text.
ENDIF.
ENDIF.
"需计算科目处理
IF NOT gs_assets-zglacct IS INITIAL OR NOT gs_assets-zcalc IS INITIAL.
"若配置表科目字段有值则直接计入需计算科目结构
IF NOT gs_assets-zglacct IS INITIAL.
APPEND VALUE #( sign = 'I' option = 'EQ' low = gs_assets-zglacct ) TO r_racct.
ELSE.
"若配置表中没有则进行循环
WHILE NOT gs_assets-zcalc IS INITIAL.
"将科目表中维护的计算规则进行分割,到内表进行循环,对于求和项利用递归思想将所有参与求和计算的科目汇总到科目结构
SPLIT gs_assets-zcalc AT '+' INTO TABLE lt_value.
LOOP AT lt_value INTO lv_value.
READ TABLE gt_assets INTO DATA(ls_assets) WITH KEY zrow = lv_value.
IF sy-subrc EQ 0.
IF NOT ls_assets-zglacct IS INITIAL.
APPEND VALUE #( sign = 'I' option = 'EQ' low = ls_assets-zglacct ) TO r_racct.
ELSE.
IF NOT lv_zcalc IS INITIAL.
lv_zcalc = lv_zcalc && '+' && ls_assets-zcalc. "遇到嵌套的计算逻辑,将上层的计算逻辑列出重新参与循环,直到找到最底层的到科目的计算逻辑,此方法不管嵌套多少层都适用
ELSE.
lv_zcalc = ls_assets-zcalc.
ENDIF.
ENDIF.
CLEAR ls_assets.
ENDIF.
CLEAR lv_value.
ENDLOOP.
CLEAR gs_assets-zcalc.
gs_assets-zcalc = lv_zcalc.
CLEAR lv_zcalc.
ENDWHILE.
ENDIF.
ENDIF.
IF NOT r_racct[] IS INITIAL.
IF rb5 EQ 'X' OR rb7 EQ 'X'.
"循环为动态列赋值-实际
DO lv_fieldcat_lines_re TIMES.
lv_index = sy-index.
"读取fieldcat的列名称
READ TABLE gt_fieldcat_re INTO gs_fieldcat_re INDEX lv_index.
IF sy-subrc = 0.
"循环次数 = 月值
lv_num = gs_fieldcat_re-fieldname+6(2).
lv_fieldname = 'HSLVT'.
LOOP AT lt_faglflext ASSIGNING FIELD-SYMBOL(<lf_faglflext>) WHERE ryear = gs_fieldcat_re-fieldname+2(4) AND
racct IN r_racct[].
"合计
DO lv_num TIMES.
IF sy-index < 10.
lv_fieldname_index = 'HSL' && '0' && sy-index.
ELSE.
lv_fieldname_index = 'HSL' && sy-index.
ENDIF.
ASSIGN COMPONENT lv_fieldname_index OF STRUCTURE <lf_faglflext> TO <lf>.
IF <lf> IS ASSIGNED.
lv_assets_sum = lv_assets_sum + <lf>.
ENDIF.
CLEAR:lv_fieldname_index .
ENDDO.
ASSIGN COMPONENT lv_fieldname OF STRUCTURE <lf_faglflext> TO <lf_lvt>.
IF <lf_lvt> IS ASSIGNED.
lv_assets_sum = lv_assets_sum + <lf_lvt>.
ENDIF.
lv_last_sum = <lf_faglflext>-hsl13 + <lf_faglflext>-hsl14 + <lf_faglflext>-hsl15 + <lf_faglflext>-hsl16.
IF lv_num = 12.
lv_assets_sum = lv_assets_sum + lv_last_sum.
ENDIF.
CLEAR: lv_last_sum .
ENDLOOP.
ENDIF.
ASSIGN COMPONENT gs_fieldcat_re-fieldname OF STRUCTURE <gf_wa> TO <lf_dy>.
IF <lf_dy> IS ASSIGNED.
IF <lf_zcost> CS 'Earnings - Current Year'.
lv_assets_sum = abs( lv_assets_sum ).
gs_earn1 = lv_assets_sum.
APPEND gs_earn1 TO gt_earn1.
<lf_dy> = lv_assets_sum.
ELSEIF <lf_zcost> CS 'Total Equity' OR <lf_zcost> CS 'Total Liabilities and Equity'.
READ TABLE gt_earn1 INTO gs_earn1 INDEX sy-index.
<lf_dy> = lv_assets_sum + gs_earn1.
ELSE.
<lf_dy> = lv_assets_sum.
ENDIF.
ENDIF.
lv_re_sum = lv_re_sum + lv_assets_sum.
lv_variant = 'ZVARIANCE' && gs_fieldcat_re-fieldname+2.
ASSIGN COMPONENT lv_variant OF STRUCTURE <gf_wa> TO <lf_re_peva>.
IF <lf_re_peva> IS ASSIGNED.
IF sy-subrc EQ 0.
<lf_re_peva> = lv_assets_sum.
ENDIF.
ENDIF.
CLEAR lv_assets_sum.
ENDDO.
ENDIF.
CLEAR: lv_index , lv_num.
IF rb6 EQ 'X' OR rb7 EQ 'X'.
"循环为动态列赋值-预算
DO lv_fieldcat_lines_bu TIMES.
"因为本身有1列固定所以要偏移1位进行取值
lv_index = sy-index.
"读取fieldcat的列名称
READ TABLE gt_fieldcat_bu INTO gs_fieldcat_bu INDEX lv_index.
IF sy-subrc = 0.
"循环次数 = 月值
lv_num = gs_fieldcat_bu-fieldname+6(2).
LOOP AT gt_budget INTO gs_budget WHERE gjahr = gs_fieldcat_bu-fieldname+2(4) AND
monat = gs_fieldcat_bu-fieldname+6(2) AND
saknr IN r_racct[].
lv_budget_sum = lv_budget_sum + gs_budget-dmbtr.
CLEAR gs_budget.
ENDLOOP.
ENDIF.
ASSIGN COMPONENT gs_fieldcat_bu-fieldname OF STRUCTURE <gf_wa> TO <lf_dy>.
IF <lf_dy> IS ASSIGNED.
<lf_dy> = lv_budget_sum.
ENDIF.
lv_bu_sum = lv_bu_sum + lv_budget_sum.
lv_variant = 'ZVARIANCE' && gs_fieldcat_bu-fieldname+2.
ASSIGN COMPONENT lv_variant OF STRUCTURE <gf_wa> TO <lf_bu_peva>.
IF <lf_bu_peva> IS ASSIGNED.
IF sy-subrc EQ 0.
<lf_bu_peva> = <lf_bu_peva> - lv_budget_sum.
ENDIF.
ENDIF.
CLEAR: lv_budget_sum , lv_variant.
ENDDO.
ENDIF.
CLEAR: gs_fieldcat_re , gs_fieldcat_bu , lv_num , lv_assets_sum.
ENDIF.
IF rb7 EQ 'X'.
ASSIGN COMPONENT 'ZVARIANCE' OF STRUCTURE <gf_wa> TO <lf_zvariance>.
IF <lf_zvariance> IS ASSIGNED.
<lf_zvariance> = lv_bu_sum - abs( lv_re_sum ).
ENDIF.
ENDIF.
APPEND <gf_wa> TO <gf_table>.
CLEAR: gs_assets , r_racct[] , <gf_wa> , lv_re_sum , lv_bu_sum , lv_acct.
ENDDO.
ENDFORM.
* &---------------------------------------------------------------------*
* & Form FRM_GET_DATA_PROFIT_LOSS
* &---------------------------------------------------------------------*
* & text
* &---------------------------------------------------------------------*
* & --> p1 text
* & <-- p2 text
* &---------------------------------------------------------------------*
FORM frm_get_data_profit_loss .
DATA: lt_result TYPE match_result_tab,
lt_value TYPE TABLE OF string.
DATA: lv_index TYPE i,
lv_loss_sum TYPE acdoca-hsl,
lv_budget_sum TYPE acdoca-hsl,
lv_fieldname TYPE acdoca-fiscyearper,
lv_pro_los_lines TYPE i,
lv_strlen TYPE i,
lv_result TYPE i,
lv_offset TYPE int4,
lv_length TYPE i,
lv_fieldcat_lines_re TYPE i,
lv_fieldcat_lines_bu TYPE i,
lv_re_total TYPE acdoca-hsl,
lv_bu_total TYPE acdoca-hsl,
lv_re_sum TYPE acdoca-hsl,
lv_bu_sum TYPE acdoca-hsl,
lv_variant TYPE string,
lv_value TYPE string,
lv_zcalc TYPE string.
FIELD-SYMBOLS: <lf>,
<lf_bukrs>,
<lf_zcost>,
<lf_bukrs_name>,
<lf_kostl>,
<lf_kostl_name>,
<lf_aufnr>,
<lf_racct>,
<lf_racct_name>,
<lf_dy>,
<lf_waers>,
<lf_ztotal>,
<lf_zvariance>,
<lf_re_peva>,
<lf_bu_peva>.
RANGES: r_fiscyearper FOR acdoca-fiscyearper,
r_racct FOR acdoca-racct.
"获取fiedcat行数
DESCRIBE TABLE gt_fieldcat LINES gv_fieldcat_lines.
DO gv_fieldcat_lines TIMES.
READ TABLE gt_fieldcat INTO gs_fieldcat INDEX sy-index + 3.
IF sy-subrc EQ 0.
lv_fieldname = gs_fieldcat-fieldname+2(4) && 0 && gs_fieldcat-fieldname+6(2).
APPEND VALUE #( sign = 'I' option = 'EQ' low = lv_fieldname ) TO r_fiscyearper.
ENDIF.
CLEAR:gs_fieldcat , lv_fieldname.
ENDDO.
"获取损益表格式
SELECT
*
INTO CORRESPONDING FIELDS OF TABLE @gt_pro_los
FROM
ztfi017
WHERE
ztype = '1'
ORDER BY zrow.
"成本要素文本补充空格
LOOP AT gt_pro_los INTO gs_pro_los.
DO gs_pro_los-zspace TIMES.
CONCATENATE '' gs_pro_los-zcost_text INTO gs_pro_los-zcost_text RESPECTING BLANKS.
ENDDO.
MODIFY gt_pro_los FROM gs_pro_los TRANSPORTING zcost_text.
CLEAR gs_pro_los.
ENDLOOP.
DESCRIBE TABLE gt_pro_los LINES lv_pro_los_lines.
"损益类
SELECT
acdoca~fiscyearper,
acdoca~rbukrs,
acdoca~rcntr,
acdoca~racct,
acdoca~aufnr,
acdoca~ksl,
acdoca~hsl,
acdoca~rwcur AS waers,
t001~butxt AS zbukrs_name,
cskt~ktext AS zkostl_name,
skat~txt50 AS zracct_name
INTO TABLE @DATA(lt_acdoca)
FROM
acdoca
LEFT JOIN t001 ON acdoca~rbukrs EQ t001~bukrs
LEFT JOIN cskt ON acdoca~rcntr EQ cskt~kostl AND
cskt~kokrs EQ '1000' AND
cskt~spras EQ @sy-langu AND
cskt~datbi GE @sy-datum
LEFT JOIN skat ON acdoca~racct EQ skat~saknr AND
skat~ktopl EQ '1000' AND
skat~spras = @sy-langu
WHERE
rbukrs IN @s_bukrs AND
gjahr IN @s_gjahr AND
fiscyearper IN @r_fiscyearper AND
( racct LIKE '6%' OR
racct LIKE '8%' OR
racct LIKE '9%' )
ORDER BY rbukrs , rcntr , racct , aufnr.
DATA(lt_data) = lt_acdoca.
DELETE ADJACENT DUPLICATES FROM lt_data COMPARING rbukrs rcntr racct aufnr.
"获取fiedcat行数-实际
DESCRIBE TABLE gt_fieldcat_re LINES lv_fieldcat_lines_re.
"获取fiedcat行数-预算
DESCRIBE TABLE gt_fieldcat_bu LINES lv_fieldcat_lines_bu.
DO lv_pro_los_lines TIMES.
IF sy-index EQ 1.
gv_fieldcat_lines = gv_fieldcat_lines - gv_flag1.
ENDIF.
"默认行赋值
READ TABLE gt_pro_los INTO gs_pro_los INDEX sy-index.
IF sy-subrc EQ 0.
SHIFT gs_pro_los-zglacct LEFT DELETING LEADING space.
ASSIGN COMPONENT 'ZCOST' OF STRUCTURE <gf_wa> TO <lf_zcost>.
IF <lf_zcost> IS ASSIGNED.
IF sy-subrc EQ 0.
<lf_zcost> = gs_pro_los-zcost_text.
ENDIF.
ENDIF.
ENDIF.
"需计算科目处理
IF NOT gs_pro_los-zglacct IS INITIAL OR NOT gs_pro_los-zcalc IS INITIAL.
"若配置表科目字段有值则直接计入需计算科目结构
IF NOT gs_pro_los-zglacct IS INITIAL.
APPEND VALUE #( sign = 'I' option = 'EQ' low = gs_pro_los-zglacct ) TO r_racct.
ELSE.
"若配置表中没有则进行循环
WHILE NOT gs_pro_los-zcalc IS INITIAL.
"将科目表中维护的计算规则进行分割,到内表进行循环,对于求和项利用递归思想将所有参与求和计算的科目汇总到科目结构
SPLIT gs_pro_los-zcalc AT '+' INTO TABLE lt_value.
LOOP AT lt_value INTO lv_value.
READ TABLE gt_pro_los INTO DATA(ls_pro_los) WITH KEY zrow = lv_value.
IF sy-subrc EQ 0.
IF NOT ls_pro_los-zglacct IS INITIAL.
APPEND VALUE #( sign = 'I' option = 'EQ' low = ls_pro_los-zglacct ) TO r_racct.
ELSE.
IF NOT lv_zcalc IS INITIAL.
lv_zcalc = lv_zcalc && '+' && ls_pro_los-zcalc. "遇到嵌套的计算逻辑,将上层的计算逻辑列出重新参与循环,直到找到最底层的到科目的计算逻辑,此方法不管嵌套多少层都适用
ELSE.
lv_zcalc = ls_pro_los-zcalc.
ENDIF.
ENDIF.
CLEAR ls_pro_los.
ENDIF.
CLEAR lv_value.
ENDLOOP.
CLEAR gs_pro_los-zcalc.
gs_pro_los-zcalc = lv_zcalc.
CLEAR lv_zcalc.
ENDWHILE.
ENDIF.
ENDIF.
IF NOT r_racct[] IS INITIAL.
IF rb5 EQ 'X' OR rb7 EQ 'X'.
"循环为动态列赋值-实际
DO lv_fieldcat_lines_re TIMES.
"因为本身有2列固定所以要偏移1位进行取值
lv_index = sy-index.
"读取fieldcat的列名称
READ TABLE gt_fieldcat_re INTO gs_fieldcat_re INDEX lv_index.
IF sy-subrc EQ 0.
lv_fieldname = gs_fieldcat_re-fieldname+2(4) && '0' && gs_fieldcat_re-fieldname+6(2).
LOOP AT lt_acdoca ASSIGNING FIELD-SYMBOL(<lf_acdoca>) WHERE rbukrs IN s_bukrs[] AND
racct IN r_racct[] AND
fiscyearper EQ lv_fieldname.
lv_loss_sum = lv_loss_sum + <lf_acdoca>-hsl.
ENDLOOP.
ASSIGN COMPONENT gs_fieldcat_re-fieldname OF STRUCTURE <gf_wa> TO <lf_dy>.
IF <lf_dy> IS ASSIGNED.
IF sy-subrc EQ 0.
<lf_dy> = lv_loss_sum.
ENDIF.
ENDIF.
lv_variant = 'ZVARIANCE' && gs_fieldcat_re-fieldname+2.
ASSIGN COMPONENT lv_variant OF STRUCTURE <gf_wa> TO <lf_re_peva>.
IF <lf_re_peva> IS ASSIGNED.
IF sy-subrc EQ 0.
<lf_re_peva> = lv_loss_sum.
ENDIF.
ENDIF.
ENDIF.
lv_re_total = lv_re_total + lv_loss_sum.
lv_re_sum = lv_re_sum + lv_loss_sum.
CLEAR: gs_fieldcat_re , lv_fieldname , lv_loss_sum , lv_variant.
ENDDO.
ASSIGN COMPONENT 'ZRETOTAL' OF STRUCTURE <gf_wa> TO <lf_ztotal>.
IF <lf_ztotal> IS ASSIGNED.
IF sy-subrc EQ 0.
<lf_ztotal> = lv_re_total.
ENDIF.
ENDIF.
ENDIF.
CLEAR: lv_index , lv_re_total.
IF rb6 EQ 'X' OR rb7 EQ 'X'.
"循环为动态列赋值-预算
DO lv_fieldcat_lines_bu TIMES.
lv_index = sy-index.
"读取fieldcat的列名称
READ TABLE gt_fieldcat_bu INTO gs_fieldcat_bu INDEX lv_index.
IF sy-subrc EQ 0.
IF gs_fieldcat_bu-fieldname NE 'ZBUTOTAL'.
LOOP AT gt_budget INTO gs_budget WHERE bukrs IN s_bukrs[] AND
gjahr = gs_fieldcat_bu-fieldname+2(4) AND
monat = gs_fieldcat_bu-fieldname+6(2) AND
saknr IN r_racct[].
lv_budget_sum = lv_budget_sum + gs_budget-dmbtr.
CLEAR gs_budget.
ENDLOOP.
ASSIGN COMPONENT gs_fieldcat_bu-fieldname OF STRUCTURE <gf_wa> TO <lf_dy>.
IF <lf_dy> IS ASSIGNED.
IF sy-subrc EQ 0.
<lf_dy> = lv_budget_sum.
ENDIF.
ENDIF.
lv_variant = 'ZVARIANCE' && gs_fieldcat_bu-fieldname+2.
ASSIGN COMPONENT lv_variant OF STRUCTURE <gf_wa> TO <lf_bu_peva>.
IF <lf_bu_peva> IS ASSIGNED.
IF sy-subrc EQ 0.
<lf_bu_peva> = <lf_bu_peva> - lv_budget_sum.
ENDIF.
ENDIF.
ENDIF.
ENDIF.
lv_bu_total = lv_bu_total + lv_budget_sum.
lv_bu_sum = lv_bu_sum + lv_budget_sum.
CLEAR: gs_fieldcat_bu , lv_fieldname , lv_budget_sum.
ENDDO.
ASSIGN COMPONENT 'ZBUTOTAL' OF STRUCTURE <gf_wa> TO <lf_ztotal>.
IF <lf_ztotal> IS ASSIGNED.
IF sy-subrc EQ 0.
<lf_ztotal> = lv_bu_total.
ENDIF.
ENDIF.
ENDIF.
CLEAR: lv_index , lv_bu_total , lv_budget_sum.
ENDIF.
IF rb7 EQ 'X'.
ASSIGN COMPONENT 'ZVARIANCE' OF STRUCTURE <gf_wa> TO <lf_zvariance>.
IF <lf_zvariance> IS ASSIGNED.
IF sy-subrc EQ 0.
<lf_zvariance> = lv_bu_sum - abs( lv_re_sum ).
ENDIF.
ENDIF.
ENDIF.
APPEND <gf_wa> TO <gf_table>.
CLEAR: gs_pro_los , r_racct[] , <gf_wa> , lv_bu_sum , lv_re_sum.
ENDDO.
ENDFORM.
* &---------------------------------------------------------------------*
* & Form FRM_SET_PF_STATUS
* &---------------------------------------------------------------------*
* & text
* &---------------------------------------------------------------------*
* & --> p1 text
* & <-- p2 text
* &---------------------------------------------------------------------*
FORM frm_set_pf_status USING t_extab TYPE slis_t_extab.
SET PF-STATUS 'STANDARD'.
SET TITLEBAR 'TITLEBAR'.
ENDFORM.
* &---------------------------------------------------------------------*
* & Form FRM_USER_COMMAND
* &---------------------------------------------------------------------*
* & text
* &---------------------------------------------------------------------*
* -->P_SY_UCOMM text
* -->P_PS_SELFIELD text
* &---------------------------------------------------------------------*
FORM frm_user_command USING pv_ucomm LIKE sy-ucomm
ps_selfield TYPE slis_selfield.
DATA lv_grid TYPE REF TO cl_gui_alv_grid.
* &将变更的数据刷新
CALL FUNCTION 'GET_GLOBALS_FROM_SLVC_FULLSCR'
IMPORTING
e_grid = lv_grid.
CALL METHOD lv_grid->check_changed_data.
ps_selfield-refresh = 'X'.
* CASE pv_ucomm.
* WHEN '&IC1'.
* PERFORM frm_fbl3n USING ps_selfield.
* ENDCASE.
CALL METHOD lv_grid->refresh_table_display.
ENDFORM.
* &---------------------------------------------------------------------*
* & Form FRM_TOP_OF_PAGE
* &---------------------------------------------------------------------*
* & text
* &---------------------------------------------------------------------*
FORM frm_top_of_page.
DATA :ls_list_commentary TYPE slis_listheader,
lt_list_commentary TYPE slis_t_listheader,
lt_month_names LIKE TABLE OF t247.
"H = Header, S = Selection, A = Action
ls_list_commentary-typ = 'H'.
ls_list_commentary-info = 'Unilia (Canada) Fuel Cells, Inc.'.
APPEND ls_list_commentary TO lt_list_commentary.
"资产负债
IF rb1 EQ 'X'.
ls_list_commentary-typ = 'H'.
ls_list_commentary-info = 'Balance Sheet'.
APPEND ls_list_commentary TO lt_list_commentary.
ELSE.
"损益
ls_list_commentary-typ = 'H'.
ls_list_commentary-info = 'Profit and Loss'.
APPEND ls_list_commentary TO lt_list_commentary.
ENDIF.
"获取月份名称
CALL FUNCTION 'MONTH_NAMES_GET'
EXPORTING
language = sy-langu
TABLES
month_names = lt_month_names
EXCEPTIONS
month_names_not_found = 1
OTHERS = 2.
IF rb1 EQ 'X'.
READ TABLE lt_month_names INTO DATA(ls_month_names) WITH KEY mnr = s_monat-high.
IF sy-subrc EQ 0.
ls_list_commentary-typ = 'S'.
IF s_gjahr-high IS INITIAL.
CONCATENATE 'AS OF' ls_month_names-ltx ',' s_gjahr-low INTO ls_list_commentary-info SEPARATED BY ''.
ELSE.
CONCATENATE 'AS OF' ls_month_names-ltx ',' s_gjahr-high INTO ls_list_commentary-info SEPARATED BY ''.
ENDIF.
APPEND ls_list_commentary TO lt_list_commentary.
ENDIF.
ELSE.
READ TABLE lt_month_names INTO ls_month_names WITH KEY mnr = s_monat-low.
IF sy-subrc EQ 0.
ls_list_commentary-typ = 'S'.
ls_list_commentary-info = ls_month_names-ltx.
READ TABLE lt_month_names INTO ls_month_names WITH KEY mnr = s_monat-high.
IF sy-subrc EQ 0.
ls_list_commentary-typ = 'S'.
ls_list_commentary-info = ls_list_commentary-info && '-' && ls_month_names-ltx.
ENDIF.
IF NOT s_gjahr-high IS INITIAL.
ls_list_commentary-info = ls_list_commentary-info && ',' && s_gjahr-low && '-' && s_gjahr-high.
ELSE.
ls_list_commentary-info = ls_list_commentary-info && ',' && s_gjahr-low.
ENDIF.
APPEND ls_list_commentary TO lt_list_commentary.
ENDIF.
ENDIF.
CALL FUNCTION 'REUSE_ALV_COMMENTARY_WRITE'
EXPORTING
it_list_commentary = lt_list_commentary
* I_LOGO = 'HMLG'
* I_END_OF_LIST_GRID =
* I_ALV_FORM =
.
ENDFORM.
* &---------------------------------------------------------------------*
* & Form FRM_DISPLAY_ALV_ASSETS
* &---------------------------------------------------------------------*
* & text
* &---------------------------------------------------------------------*
* & --> p1 text
* & <-- p2 text
* &---------------------------------------------------------------------*
FORM frm_display_alv.
CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY_LVC'
EXPORTING
i_callback_program = sy-repid
i_callback_pf_status_set = 'FRM_SET_PF_STATUS'
i_callback_user_command = 'FRM_USER_COMMAND'
i_callback_top_of_page = 'FRM_TOP_OF_PAGE'
is_layout_lvc = gs_layout
it_fieldcat_lvc = gt_fieldcat
i_save = 'A'
TABLES
t_outtab = <gf_table>
EXCEPTIONS
program_error = 1
OTHERS = 2.
ENDFORM.
三、Configure
P&L
B&S
三、Rewiew
重新梳理了下基于国际会计准则与中国会计准则在三大报表中的区别。