要点
- 基于FAGLFLEXT获取数据
- 支持交易货币和公司代码本位币
- 双击跳转到 FAGLB03
定义会计科目余额显示的结构 ZGLBALANCES
abap
@EndUserText.label : '总账科目余额结构'
@AbapCatalog.enhancement.category : #NOT_EXTENSIBLE
define structure zglbalances {
companycode : bukrs;
gl_account : hkont;
txt20 : txt20_skat;
fis_year : gjahr;
fis_period : monat;
lis_period : monat;
@Semantics.amount.currencyCode : 'acdoca.rhcur'
yr_begin_bal : fins_vhcur12;
@Semantics.amount.currencyCode : 'acdoca.rhcur'
per_begin_bal : fins_vhcur12;
@Semantics.amount.currencyCode : 'acdoca.rhcur'
per_debit_amt : fins_vhcur12;
@Semantics.amount.currencyCode : 'acdoca.rhcur'
per_credit_amt : fins_vhcur12;
@Semantics.amount.currencyCode : 'acdoca.rhcur'
per_amt : fins_vhcur12;
@Semantics.amount.currencyCode : 'acdoca.rhcur'
balance : fins_vhcur12;
currency : waers;
@Semantics.amount.currencyCode : 'acdoca.rwcur'
yr_begin_bal_w : fins_vwcur12;
@Semantics.amount.currencyCode : 'acdoca.rwcur'
per_begin_bal_w : fins_vwcur12;
@Semantics.amount.currencyCode : 'acdoca.rwcur'
per_debit_amt_w : fins_vwcur12;
@Semantics.amount.currencyCode : 'acdoca.rwcur'
per_credit_amt_w : fins_vwcur12;
@Semantics.amount.currencyCode : 'acdoca.rwcur'
per_amt_w : fins_vwcur12;
@Semantics.amount.currencyCode : 'acdoca.rwcur'
balance_w : fins_vwcur12;
currency_w : waers;
}
编写获取科目余额的函数
因为可能在多个场合获取会计科目余额,所以将功能封装到函数中。
abap
function zfm_acc_per_balances
importing
value(companycode) type zglbalances-companycode optional
value(fiscalyear) type zglbalances-fis_year optional
value(period1) type zglbalances-fis_period optional
value(period2) type zglbalances-lis_period optional
tables
account_balances like zglbalances optional.
data: lt_return like table of zglbalances . " 返回值
data: ls_return like line of lt_return.
data: lv_hslxx like faglflext-hslvt.
data: lv_tslxx like faglflext-hslvt.
data: lv_times type i. " 根据期间,计算需要循环的次数
data: lv_times0 type i. " 计算期初余额循环的次数
data:lv_period like zglbalances-fis_period.
field-symbols: <field>.
data: lv_fieldname type string,
lv_waers like t001-waers.
lv_times = period1.
lv_times0 = lv_times - 1.
* ----公司本位币----
select single waers
into lv_waers
from t001
where bukrs = companycode.
* ---科目名称----
select saknr, txt20
from skat
where spras = @sy-langu
and ktopl = 'XXXX'
order by saknr
into table @data(lt_skat) .
* ----从FAGLFLEXT获取数据----
select rbukrs , " 公司代码
rldnr, " ledger
racct, " 科目
drcrk, " 借贷方
rtcur, " 原币
sum( hslvt ) as hslvt, " 年初余额合计
sum( hsl01 ) as hsl01, " 期间1合计
sum( hsl02 ) as hsl02, " 期间2合计
sum( hsl03 ) as hsl03, " 期间3合计
sum( hsl04 ) as hsl04, " 期间4合计
sum( hsl05 ) as hsl05, " 期间5合计
sum( hsl06 ) as hsl06, " 期间6合计
sum( hsl07 ) as hsl07, " 期间7合计
sum( hsl08 ) as hsl08, " 期间8合计
sum( hsl09 ) as hsl09, " 期间9合计
sum( hsl10 ) as hsl10, " 期间10合计
sum( hsl11 ) as hsl11, " 期间11合计
sum( hsl12 ) as hsl12, " 期间12合计
sum( hsl13 ) as hsl13, " 期间13合计
sum( hsl14 ) as hsl14, " 期间14合计
sum( hsl15 ) as hsl15, " 期间15合计
sum( hsl16 ) as hsl16, " 期间16合计
sum( tslvt ) as tslvt, " 年初余额合计
sum( tsl01 ) as tsl01, " 期间1合计
sum( tsl02 ) as tsl02, " 期间2合计
sum( tsl03 ) as tsl03, " 期间3合计
sum( tsl04 ) as tsl04, " 期间4合计
sum( tsl05 ) as tsl05, " 期间5合计
sum( tsl06 ) as tsl06, " 期间6合计
sum( tsl07 ) as tsl07, " 期间7合计
sum( tsl08 ) as tsl08, " 期间8合计
sum( tsl09 ) as tsl09, " 期间9合计
sum( tsl10 ) as tsl10, " 期间10合计
sum( tsl11 ) as tsl11, " 期间11合计
sum( tsl12 ) as tsl12, " 期间12合计
sum( tsl13 ) as tsl13, " 期间13合计
sum( tsl14 ) as tsl14, " 期间14合计
sum( tsl15 ) as tsl15, " 期间15合计
sum( tsl16 ) as tsl16 " 期间16合计
from v_faglflext_view
where rbukrs = @companycode
and ryear = @fiscalyear
and rldnr = '0L'
group by rbukrs, rldnr, racct, drcrk,rtcur
into table @data(lt_faglflext).
sort lt_faglflext by rbukrs racct drcrk .
data: begin of ls_key,
companycode like faglflext-rbukrs,
gl_account like faglflext-racct,
fis_year like zglbalances-fis_year,
fis_period like zglbalances-fis_period,
lis_period like zglbalances-lis_period,
currency like zglbalances-currency,
currency_w like zglbalances-currency_w,
end of ls_key.
data: lt_key like standard table of ls_key.
loop at lt_faglflext into data(ls_faglflext).
clear ls_key.
ls_key-companycode = ls_faglflext-rbukrs.
ls_key-gl_account = ls_faglflext-racct.
ls_key-fis_year = fiscalyear.
ls_key-fis_period = period1.
ls_key-lis_period = period2.
ls_key-currency = lv_waers.
ls_key-currency_w = ls_faglflext-rtcur.
append ls_key to lt_key.
endloop.
sort lt_key by companycode gl_account fis_year fis_period currency_w.
delete adjacent duplicates from lt_key comparing companycode gl_account fis_year fis_period currency_w.
move-corresponding lt_key to lt_return.
" ----年初余额----
select rbukrs,
racct,
rtcur,
sum( hslvt ) as hslvt,
sum( tslvt ) as tslvt
from @lt_faglflext as fagl
group by rbukrs, racct,rtcur
into table @data(lt_open1). " 年初余额
" ----期初余额----
select rbukrs , " 公司代码
racct, " 科目
rtcur, "
sum( hslvt ) as hslvt, " 年初余额合计
sum( hsl01 ) as hsl01, " 期间1合计
sum( hsl02 ) as hsl02, " 期间2合计
sum( hsl03 ) as hsl03, " 期间3合计
sum( hsl04 ) as hsl04, " 期间4合计
sum( hsl05 ) as hsl05, " 期间5合计
sum( hsl06 ) as hsl06, " 期间6合计
sum( hsl07 ) as hsl07, " 期间7合计
sum( hsl08 ) as hsl08, " 期间8合计
sum( hsl09 ) as hsl09, " 期间9合计
sum( hsl10 ) as hsl10, " 期间10合计
sum( hsl11 ) as hsl11, " 期间11合计
sum( hsl12 ) as hsl12, " 期间12合计
sum( hsl13 ) as hsl13, " 期间13合计
sum( hsl14 ) as hsl14, " 期间14合计
sum( hsl15 ) as hsl15, " 期间15合计
sum( hsl16 ) as hsl16, " 期间16合计
sum( tslvt ) as tslvt, " 年初余额合计
sum( tsl01 ) as tsl01, " 期间1合计
sum( tsl02 ) as tsl02, " 期间2合计
sum( tsl03 ) as tsl03, " 期间3合计
sum( tsl04 ) as tsl04, " 期间4合计
sum( tsl05 ) as tsl05, " 期间5合计
sum( tsl06 ) as tsl06, " 期间6合计
sum( tsl07 ) as tsl07, " 期间7合计
sum( tsl08 ) as tsl08, " 期间8合计
sum( tsl09 ) as tsl09, " 期间9合计
sum( tsl10 ) as tsl10, " 期间10合计
sum( tsl11 ) as tsl11, " 期间11合计
sum( tsl12 ) as tsl12, " 期间12合计
sum( tsl13 ) as tsl13, " 期间13合计
sum( tsl14 ) as tsl14, " 期间14合计
sum( tsl15 ) as tsl15, " 期间15合计
sum( tsl16 ) as tsl16 " 期间16合计
from @lt_faglflext as lt
group by rbukrs, racct,rtcur
into table @data(lt_open2).
loop at lt_return into ls_return.
" 年初余额
read table lt_open1 into data(ls_open1) with key rbukrs = ls_return-companycode
racct = ls_return-gl_account
rtcur = ls_return-currency_w.
if sy-subrc = 0.
ls_return-yr_begin_bal = ls_open1-hslvt.
ls_return-yr_begin_bal_w = ls_open1-tslvt.
endif.
" 期初余额
read table lt_open2 into data(ls_open2) with key rbukrs = ls_return-companycode
racct = ls_return-gl_account
rtcur = ls_return-currency_w.
if sy-subrc = 0.
ls_return-per_begin_bal = ls_open2-hslvt.
do lv_times0 times.
lv_fieldname = 'HSL' && |{ sy-index align = right width = 2 pad = '0' }| .
assign component lv_fieldname of structure ls_open2 to <field>.
move <field> to lv_hslxx.
ls_return-per_begin_bal += lv_hslxx. " 期初余额累计
enddo.
ls_return-per_begin_bal_w = ls_open2-tslvt.
do lv_times0 times.
lv_fieldname = 'TSL' && |{ sy-index align = right width = 2 pad = '0' }| .
assign component lv_fieldname of structure ls_open2 to <field>.
move <field> to lv_tslxx.
ls_return-per_begin_bal_w += lv_tslxx. " 期初余额累计
enddo.
endif.
" 期间借方
read table lt_faglflext into data(ls_debit) with key rbukrs = ls_return-companycode
racct = ls_return-gl_account
rtcur = ls_return-currency_w
drcrk = 'S'.
if sy-subrc = 0.
clear lv_period.
lv_period = period1.
do .
lv_fieldname = 'HSL' && |{ lv_period align = right width = 2 pad = '0' }| .
assign component lv_fieldname of structure ls_debit to <field>.
ls_return-per_debit_amt += <field> . " 期初余额累计
lv_fieldname = 'TSL' && |{ lv_period align = right width = 2 pad = '0' }| .
assign component lv_fieldname of structure ls_debit to <field>.
ls_return-per_debit_amt_w += <field> . " 期初余额累计
lv_period = lv_period + 1.
if lv_period > period2.
exit.
endif.
enddo.
endif.
" 期间贷方
read table lt_faglflext into data(ls_credit) with key rbukrs = ls_return-companycode
racct = ls_return-gl_account
rtcur = ls_return-currency_w
drcrk = 'H'.
if sy-subrc = 0.
clear lv_period.
lv_period = period1.
do .
lv_fieldname = 'HSL' && |{ lv_period align = right width = 2 pad = '0' }| .
assign component lv_fieldname of structure ls_credit to <field>.
ls_return-per_credit_amt += <field> . " 期初余额累计
lv_fieldname = 'TSL' && |{ lv_period align = right width = 2 pad = '0' }| .
assign component lv_fieldname of structure ls_credit to <field>.
ls_return-per_credit_amt_w += <field> . " 期初余额累计
lv_period = lv_period + 1.
if lv_period > period2.
exit.
endif.
enddo.
endif.
" 期间发生额(借方+贷方)
ls_return-per_amt = ls_return-per_debit_amt + ls_return-per_credit_amt.
ls_return-per_amt_w = ls_return-per_debit_amt_w + ls_return-per_credit_amt_w.
" 期末余额
ls_return-balance = ls_return-per_begin_bal + ls_return-per_amt.
ls_return-balance_w = ls_return-per_begin_bal_w + ls_return-per_amt_w.
" 科目名称
read table lt_skat into data(ls_skat) with key saknr = ls_return-gl_account binary search.
if sy-subrc = 0.
ls_return-txt20 = ls_skat-txt20.
endif.
" 修改内表
modify lt_return from ls_return.
clear ls_return.
endloop.
delete lt_return where yr_begin_bal = 0
and per_begin_bal = 0
and per_debit_amt = 0
and per_credit_amt = 0
and yr_begin_bal_w = 0
and per_begin_bal_w = 0
and per_debit_amt_w = 0
and per_credit_amt_w = 0
.
sort lt_return by companycode gl_account.
account_balances[] = lt_return[].
endfunction.
会计科目余额报表
abap
*&---------------------------------------------------------------------*
*& Report ZFI001
*&---------------------------------------------------------------------*
*& 会计科目余额表
*&---------------------------------------------------------------------*
report zfi001.
tables: ska1,rfsdo.
data: gt_balances like standard table of zglbalances.
data: gs_balances like line of gt_balances.
*---------------------
* 双击事件处理类
*---------------------
class lcl_handlers definition.
public section.
class-methods:
handle_double_click for event double_click of cl_salv_events_table
importing row column.
endclass.
class lcl_handlers implementation.
method handle_double_click.
data: gs_data like gs_balances,
lv_bukrs type bukrs,
lv_saknr type saknr,
lv_gjahr type gjahr.
" 获取双击行数据
read table gt_balances into gs_data index row.
if sy-subrc <> 0.
return.
endif.
" 提取基础信息
lv_bukrs = gs_data-companycode.
lv_saknr = gs_data-gl_account.
lv_gjahr = gs_data-fis_year.
" 仅处理物料编码字段的双击事件
if column = 'PER_DEBIT_AMT' or column = 'PER_CREDIT_AMT'
or column = 'YR_BEGIN_BAL' or column = 'PER_BEGIN_BAL'
or column = 'PER_AMT' or column = 'BALANCE'.
set parameter id 'ACC' field lv_saknr.
set parameter id 'BUK' field lv_bukrs.
set parameter id 'GJR' field lv_gjahr.
call transaction 'FAGLB03' and skip first screen.
return.
endif.
endmethod.
endclass.
*********************************
* Selection screen
*********************************
selection-screen begin of block b1 with frame title text-001.
parameters: p_bukrs like t001-bukrs default '1000' obligatory.
parameters: p_year like acdoca-ryear default sy-datum+0(4) obligatory.
select-options:s_monat for rfsdo-allgbmon no-extension obligatory.
select-options s_saknr for ska1-saknr.
selection-screen end of block b1.
start-of-selection.
perform frm_get_data.
perform frm_alv_show using gt_balances.
*------------------------------------
* 获取数据
*------------------------------------
form frm_get_data.
if s_monat-high is initial.
s_monat-high = s_monat-low.
endif.
call function 'ZFM_ACC_PER_BALANCES'
exporting
companycode = p_bukrs
fiscalyear = p_year
period1 = s_monat-low
period2 = s_monat-high
tables
account_balances = gt_balances.
delete gt_balances where gl_account not in s_saknr.
endform.
*------------------------------------
* ALV显示数据
*------------------------------------
form frm_alv_show using itab type any table.
define macro_setcol.
lo_column ?= lo_columns->get_column( &1 ).
lo_column->set_short_text( &2 ).
lo_column->set_medium_text( &2 ).
lo_column->set_long_text( &2 ).
end-of-definition.
data gr_alv type ref to cl_salv_table.
data: gr_fnlist type ref to cl_salv_functions_list.
data: lo_columns type ref to cl_salv_columns_table,
lo_column type ref to cl_salv_column_table.
data lo_events type ref to cl_salv_events_table.
if lines( itab ) = 0.
message '没有会计科目的余额数据!' type 'S'.
exit.
endif.
try.
call method cl_salv_table=>factory
importing
r_salv_table = gr_alv
changing
t_table = itab[].
catch cx_salv_msg .
endtry.
" 设置所有列自动调整为最佳宽度
lo_columns = gr_alv->get_columns( ).
lo_columns->set_optimize( abap_true ).
gr_fnlist = gr_alv->get_functions( ).
gr_fnlist->set_all( ).
" 设置列名
macro_setcol 'TXT20' '科目名称'.
macro_setcol 'YR_BEGIN_BAL' '年初余额'.
macro_setcol 'PER_BEGIN_BAL' '期初余额'.
macro_setcol 'PER_DEBIT_AMT' '期间借方'.
macro_setcol 'PER_CREDIT_AMT' '期间贷方'.
macro_setcol 'PER_AMT' '期间发生额'.
macro_setcol 'BALANCE' '期末余额'.
macro_setcol 'YR_BEGIN_BAL_W' '年初余额(原币)'.
macro_setcol 'PER_BEGIN_BAL_W' '期初余额(原币)'.
macro_setcol 'PER_DEBIT_AMT_W' '期间借方(原币)'.
macro_setcol 'PER_CREDIT_AMT_W' '期间贷方(原币)'.
macro_setcol 'PER_AMT_W' '期间发生额(原币)'.
macro_setcol 'BALANCE_W' '期末余额(原币)'.
macro_setcol 'CURRENCY_W' '交易货币'.
macro_setcol 'FIS_PERIOD' '起始期间'.
macro_setcol 'LIS_PERIOD' '结束期间'.
" 获取事件对象并注册双击事件
lo_events = gr_alv->get_event( ).
set handler lcl_handlers=>handle_double_click for lo_events.
gr_alv->display( ).
endform.