Opening and closing stock for a material
Dear All,
For a long time I have been searching for a function module or any other component which will provide me the opening stock and closing stock for a material by a specific period . The period could be a any month or date . And finally I am satisfied by the below methods .
We will get the stock from MARD table by clubbing all stock quantity , or from MMBE transaction .
Also there are several approaches which will provide the stock for a particular period . And also I found MB5B tcode which exactly does the same . So what we can do is we can take the output of MMBE and use inside our object .
WAY 1 : When you go through MB5B source code (RM07MLBD) , you will see “g_t_totals_flat” internal table which holds all the output data which contains your opening and closing stock .
So here you can do an import and export it wherever you need it .
IMPORT g_t_totals_flat TO g_t_totals_t FROM MEMORY ID ‘MB5B’ .
WAY 2 : Please go thorough the below code and get your opening and closing stock balance .
REPORT zam_demo1.
TABLES: t001w, mard, mkpf .
TYPES : BEGIN OF ty_stype_totals_flat,
matnr LIKE mbew-matnr,
maktx LIKE makt-maktx,
bwkey LIKE mbew-bwkey,
werks LIKE mseg-werks,
charg LIKE mseg-charg,
sobkz LIKE mslb-sobkz,
name1 LIKE t001w-name1, "n999530
start_date LIKE sy-datlo,
end_date LIKE sy-datlo,
anfmenge(09) TYPE p DECIMALS 3,
meins LIKE mara-meins,
soll(09) TYPE p DECIMALS 3,
haben(09) TYPE p DECIMALS 3,
endmenge(09) TYPE p DECIMALS 3.
TYPES: anfwert(09) TYPE p DECIMALS 2,
waers LIKE t001-waers, "Währungsschlüssel
sollwert(09) TYPE p DECIMALS 2,
habenwert(09) TYPE p DECIMALS 2,
endwert(09) TYPE p DECIMALS 2,
color TYPE slis_t_specialcol_alv,
END OF ty_stype_totals_flat.
SELECTION-SCREEN: BEGIN OF BLOCK database-selection
WITH FRAME TITLE text-001.
SELECT-OPTIONS: s_werks FOR t001w-werks MEMORY ID wrk .
SELECT-OPTIONS: s_matnr FOR mard-matnr MEMORY ID mat
MATCHCODE OBJECT mat1.
SELECT-OPTIONS: s_datum FOR mkpf-budat NO-EXTENSION.
SELECTION-SCREEN END OF BLOCK database-selection.
DATA: lt_posting_stock TYPE zty_posting_stock,
lt_rspar TYPE TABLE OF rsparams,
ls_rspar TYPE rsparams,
lr_data TYPE REF TO data,
lt_data TYPE TABLE OF ty_stype_totals_flat,
ls_data TYPE ty_stype_totals_flat,
ls_posting_stock TYPE zst_posting_stock.
FIELD-SYMBOLS: <lt_data> TYPE ANY TABLE .
CLEAR : ls_rspar .
"Material
LOOP AT s_matnr .
ls_rspar-selname = 'MATNR'.
ls_rspar-kind = 'S'.
ls_rspar-low = s_matnr-low.
ls_rspar-high = s_matnr-high.
ls_rspar-sign = s_matnr-sign.
ls_rspar-option = s_matnr-option .
APPEND ls_rspar TO lt_rspar.
CLEAR ls_rspar.
ENDLOOP.
"Plant
LOOP AT s_werks .
ls_rspar-selname = 'WERKS'.
ls_rspar-kind = 'S'.
ls_rspar-low = s_werks-low.
ls_rspar-high = s_werks-high.
ls_rspar-sign = s_werks-sign.
ls_rspar-option = s_werks-option.
APPEND ls_rspar TO lt_rspar.
CLEAR ls_rspar.
ENDLOOP.
"Date
LOOP AT s_datum .
ls_rspar-selname = 'DATUM'.
ls_rspar-kind = 'S'.
ls_rspar-low = s_datum-low.
ls_rspar-high = s_datum-high.
ls_rspar-sign = s_datum-sign .
ls_rspar-option = s_datum-option .
APPEND ls_rspar TO lt_rspar.
CLEAR ls_rspar.
ENDLOOP.
IF lt_rspar IS NOT INITIAL.
cl_salv_bs_runtime_info=>set(
EXPORTING
display = abap_false
metadata = abap_false
data = abap_true
).
SUBMIT rm07mlbd WITH SELECTION-TABLE lt_rspar
WITH lgbst EQ ' '
WITH bwbst EQ 'X'
WITH sbbst EQ ' '
WITH pa_sumfl EQ 'X'
AND RETURN . "#EC CI_SUBMIT
* WAIT UP TO 2 SECONDS .
TRY .
cl_salv_bs_runtime_info=>get_data_ref(
IMPORTING
r_data = lr_data
).
ASSIGN lr_data->* TO <lt_data>.
IF <lt_data> IS ASSIGNED.
CLEAR lt_data.
lt_data = <lt_data>.
ENDIF.
CATCH cx_salv_bs_sc_runtime_info .
MESSAGE e034(zcl_zn_msg).
ENDTRY.
cl_salv_bs_runtime_info=>clear_all( ).
ENDIF.
IF lt_data IS NOT INITIAL.
LOOP AT lt_data INTO ls_data.
ls_posting_stock-werks = ls_data-bwkey.
ls_posting_stock-matnr = ls_data-matnr.
ls_posting_stock-start_date = ls_data-start_date.
ls_posting_stock-end_date = ls_data-end_date.
ls_posting_stock-opening_stock = ls_data-anfmenge.
ls_posting_stock-unit = ls_data-meins.
ls_posting_stock-receipts = ls_data-soll.
ls_posting_stock-issues = ls_data-haben.
ls_posting_stock-closing_stock = ls_data-endmenge.
APPEND ls_posting_stock TO lt_posting_stock.
CLEAR ls_posting_stock .
ENDLOOP.
ENDIF.
Please check lt_posting_stock for the opening and closing stock balance where
anfmenge -> Opening stock
endmenge -> Closing Stock .
MB5B reference :
Output:
Regards,
Amaresh
It is worth mentioning that there was a similar Blog from 2012 by Sijin Chandran that uses an Enhancement in "MB5B" to achieve Similar Results : link
So this is no Critique, I just want to point out another Resource that might have helped you to achieve the Requirement faster ...
Kind regards
Nic T.
If you are aware of some existing content I feel it'd be beneficial to the readers if you've noted that there is such-and-such blog/question about it but this-and-that is not covered (or is not clear) in it. This providers the readers with additional reference and gives credit to other SCN members who shared their information before.
Thanks for posting. Just a few notes about the ABAP code:
I'm sure others will chime in with how this can be done even better with OOP and TDD and what's not. 🙂
Also if this information is needed frequently this can be solved by using LIS. I've done it long time ago and suggested to others on multiple occasions. All you need is to define an info structure for goods movements with Plant / material / quantity / whatever other criteria is needed and configure the update not as cumulative but as Data Transfer (B). And make it a monthly. With this configuration, whenever any GM happens, the info structure will be updated with the current stock. And because it's monthly, when month ends, there will be no more updates to that record. So this will be your end of month balance. Beginning of month balance would be the previous month's record (you'd need to fill in the initial values once, of course).
The only drawback here is that when there are no GMs at all then no record is created. So we need to go back not just to the previous month but keep reading back till we find a record. This can be remedied by a custom update program though, if necessary.
Hope this helps.