Application Development Blog Posts
Learn and share on deeper, cross technology development topics such as integration and connectivity, automation, cloud extensibility, developing at scale, and security.
Showing results for 
Search instead for 
Did you mean: 
Active Participant
Sometimes for planning purposes we need to get logistics stocks by plant/storage location/material for the specific date. In the blog I will describe some ways to solve the problem depending on version of SAP NetWeaver.


Manual approach via tcode MB5B

Transaction MB5B could help us to read stocks. Tcode could be find via menu path Logistics -> Materials Management -> Inventory Management -> Environment -> Stock -> MB5B - Stock for Posting Date. As we could see from the screenshot below there are also some others useful transactions in the menu path.

Pict1. Path to MB5B in standard menu

Transaction MB5B launches report RM07MLBD. The report collects the stocks according to selection criteria, where among others we could specify Material, Plant, Storage Location.

The MB5B shows zero-stocks by default. If we do not need zero-stocks we should uncheck checkbox Without Opening Stock; Without Closing Stock.

Pict.2 Exclude zero stocks

As a result the system provides us with abap list with several columns with important and accurate data.

Pict.3 ABAP list resutl in MB5B


So, to get stock on the specific date we need to fill in selection criteria and launch the report. In the table below I have provided short description with technical names for the selection criteria.

Parameter's name Comment
Material Number
MATNR If not specified - no restriction by the field.
Company Code
BUKRS For the sake of efficient launch it is recommended to specify.
Storage Location
Selection Date
Radiobutton group Stock type LGBST
I will choose option Storage Loc/Batch Stock (field LGBST)

List Scope

uncheck option
Without Opening Stock; Without Closing Stock

Fields PA_NDZER иand PA_NDZER I will uncheck.

For more details about the report we can use F1 or help inside the report.

Pict.4 Documentation in MB5B from the selection screen

Also there are plenty of comments inside the report (thanks to the authors 🙂 )

Pict.5 Comments inside MB5B

So we can get stocks on the specific date (or period) via transaction MB5B manually. The report works in the following way: system reads quantity on the closing moment of the previous logistic period and then reads all material movements according to selection criteria; after that calculates total quantity with pluses and minuses. And of course the system takes into account different batches, stock types and different movement types.

But could we get the stocks programmatically? Yes. of course 🙂

Solution#1. Reading stocks via custom report as copy of RM07MLBD

The easiest way to read stock - is to copy RM07MLBD  into custom report and export data to memory. The custom class (which will launch the report) should import from memory the result and the stocks on the specific posting date are received accurately.

Advantage of the solution: we avoid doing any changes or enhancement inside standard code and we could add custom logic without any risk to impact standard report.

Disadvantage: in case of upgrade of report RM07MLBD  we need to replicate the changes also manually.

My realization of the solution could be found here. However I will highlight some moments:

  1. the report RM07MLBD  uses locally defined structure inside. But for export/import to/from memory it is more convenient to use global structure. So we need to move data from internal table bestand (here is the result list of the report) to internal table with global type.

  2. We need to add parameter to the report, that was the signal to report to export to memory. The report-copy could be like that.

  3. SUBMIT REPORT is in the separate class which is also validate the selection criteria. The report is dealing with material movements and usually there are many movements - validation will helps to avoid unnecessary system's overloading. In my realization export/import is doing by class in the following way.


Solution#2. Reading stocks via RM07MLBD directly (modern system versions)

In more modern versions the report RM07MLBD  was upgraded (among many others reports) and it already does have the parameter to export data into memory. So we have standard solution just like solution#1 (see above). However the option was done not for business needs but for unit test needs (I do not know, but maybe somebody has plan to remove it, but please do not do that 🙂 )

Let us see some parts of the report.

  1. Parameter P_AUT in report RM07MLBD (=transaction MB5B). The parameter is primary for unit testing but it gives us possibility to export the result data to memory.

  2. The exporting to memory and memory id.
    If the parameter P_AUT is checked - the system will not show the result by will export the data to memory.

  3. Global table type STOCK_INVENTORY_TT and global structure STOCK_INVENTORY_S which are used for memory exporting/importing.

So, we could use standard approach for export to memory as we have done that in Solution #2. Example of code for solution #2 I have provided here.

Solution#3. Reading stocks RM07MLBD via EXPORT TO SPOOL

Any report which is using ABAP-list we could forward to spool and after that read data from spool. We could send data to spool via construction below

With parameters it would look like that
WITH bukrs IN lt_rng_bukrs
WITH werks IN is_sel_criteria-werks_rng
WITH lgort IN is_sel_criteria-lgort_rng
WITH matnr IN is_sel_criteria-matnr_rng
WITH budat IN is_sel_criteria-budat_rng
WITH bwbst EQ abap_true " valuated stock
WITH pa_sumfl EQ abap_true " Non-Hierarchical
WITH pa_wdzer EQ abap_true " without opening stock; without closing stock (mat withno movemetns)

To read the result we need to use functions LIST_FROM_MEMORY, LIST_TO_ASCI и LIST_FREE_MEMORY. They are standard functions but inside themselves using memory ID %_LIST . This kind of solution I have provided here.

Disadvantage of the solution is additional parsing from string types into target types. It could take some time.

Advantages of the solution are cross-versions and the fact that the solution could be applied to ANY report that using ABAP list.

Solution#4. Using enhancement inside MB5B (report RM07MLBD)

The report RM07MLBD consists from subroutines and it gives the possibility to use enhancements technique. We should pay attention to the following parts of the report for enhancement

Pict.11 Subroutine listumfang where it is possible to add enhancement

Pict.12 Enhancement SPOT inside MB5B

Enhancements are widely described on sap wiki and here (author: Oleg Tochenyuk).

Advantage: you could avoid report copy.

Disadvantage: you should use enhancement carefully; as Linux-CLI says: with great power comes great responsibility.


Solution#5. Read stocks data via CDS (S/4 HANA version)

In S/4 HANA version we have CDS C_MaterialStockByKeyDate. For the solution I have also provided sample on github.
    SELECT *
FROM C_MaterialStockByKeyDate( P_Language = @sy-langu, P_KeyDate = @lv_key_date )
WHERE Plant IN @is_sel_criteria-werks_rng
AND StorageLocation IN @is_sel_criteria-lgort_rng
AND Material IN @is_sel_criteria-matnr_rng
INTO TABLE @lt_stock_on_date


I also would like to highlight:

  1. the CDS C_MaterialStockByKeyDate works like MB5B: all documents are read and then system sum up and groups values.

  2. In MB5B we could read stocks for period, but in CDS on the specific date only. Of course we could create some custom CDS above the C_MaterialStockByKeyDate but with help of the CDS only by date not by period.

  3. MB5B shows quantity and amount of the stock; in CDS - quantity only.

Useful logistics' CDS are in table below and also could be checked here.

Техн.имя CDS Description
I_MaterialDocumentItem_2 Material Document Item
I_MaterialStock Material Stock
I_MaterialStock_2 Material Stock
C_MaterialStockActual Total Actual Stock Quantity
C_MaterialStockByKeyDate Material Stock at posting date



In the blog I have provided some solutions how to read stocks in SAP ERP / S4 HANA system. Any feedback is appreciated.
Active Contributor
Top compilation for a typical logistics requirement 👍
Active Participant
0 Kudos
Thank you very much, Michael!
Merry Christmas and Happy New Year!
Active Contributor
With MB52 one could also suppress ALV output, invoke the transaction and later fetch the complete ALV table, very cleanly and no report copying / second-guessing of data. Would such an approach also be applicable here?
Active Participant

Thank you very much indeed, c5e08e0478aa4727abc4482f5be390b2

The approach seems to be applicable.

The deal is: in MB5B there is a parameter P_GRID which allow to output into ALV. However, inside the report function REUSE_ALV_GRID_DISPLAY but it seems the function could work with offline mode.

I will try to provide sample as soon as I can (not this week, but hope this month 🙂 ) (and add a separate solution for full picture)

Active Participant

actually, I found three more ways of extraction:

  1. as you described with help of class/method: cl_salv_bs_runtime_info=>set/get


  2. with help of standard memory parameters: ALV_EXTRACT_MODE and ALV_EXTRACT_TABLE.

    in (almost begin)  CL_GUI_ALV_GRID > SET_TABLE_FOR_FIRST_DISPLAY we have

    *Infoset(Runtime) Extraction
    import l_mode to l_mode from memory id 'ALV_EXTRACT_MODE'.
    if l_mode eq 'E'.
    export it_outtab from it_outtab[]
    to memory id 'ALV_EXTRACT_TABLE'.
    set screen 0.
    leave screen.
  3. run report as job, save to  spool from alv / read job spool as ALV-result output tab.

all three options are available for this report.

Nevertheless, I will try to add info into the blog also about them, but later 🙂

Thank you again!

Labels in this area