Introduction
In SAP Materials Management, the Stock or Requirements List MD04 is one of the most frequently used transactions for planners and production teams. It provides a real-time view of current stock, incoming receipts, and outgoing requirements for a material at plant level. However, in real project scenarios, users often need a simplified, customized, or report-based version of MD04 that can be enhanced further or adapted to specific business needs.
During one such requirement, I worked on building a custom ABAP report that replicates the core functionality of MD04 while keeping the logic transparent and flexible. This blog explains how a custom Stock/Requirements Report can be built using standard SAP tables and function modules, without modifying standard SAP transactions.
Solution Review :
The custom report ZSTCOK_912 is designed to display stock and MRP elements for a given Material and Plant, closely mirroring the MD04 output.
1. Selection Screen
The report starts with a simple and user friendly selection screen:Material Number MATNRPlant WERKSBoth parameters are mandatory to ensure accurate stock evaluation.
2. Material Number Conversion
Since SAP stores material numbers with leading zeros, the report uses:
CONVERSION_EXIT_ALPHA_INPUT
This ensures the material number is in the correct internal format before database access.
3. Current Stock Determination
To calculate the opening balance:
Table MARD is readAll unrestricted stock LABST across storage locations is summedThis provides the current physical stock, which becomes the starting available quantity.
4. Fetching Stock or Requirements Data
The core of the solution uses the standard SAP function module:
MD_STOCK_REQUIREMENTS_LIST_API
This is the same API used by MD04 and returns:MRP elements receipts and requirements QuantitiesPlanning and control dataThe data is stored in internal tables such as MDPSX, MDEZX, and MDSUX.
5. Display Logic and Running Stock Calculation
Each MRP element is processed sequentially:Receipts increase available stockRequirements reduce available stockA running available quantity is calculated and displayed line by line, giving users a projected stock position over time.
6. Output Format
The report displays:
DateMRP element type Receipt, Requirement, Dependent Requirement, etc.Document numberReceipt quantityProjected available stockAdditionally, summary information such as total records processed and current stock is displayed at the end.
The Complete Solution Code
*&———————————————————————*
*& Report ZSTCOK_912
*&———————————————————————*
*& Custom Stock/Requirements Report
*& Purpose: Display stock and requirements similar to MD04 transaction
*&———————————————————————*
REPORT ZSTCOK_912.
*&———————————————————————*
*& DATA DECLARATIONS
*&———————————————————————*
” Reference to standard SAP tables for material master data
TABLES: mara, ” General Material Data
marc. ” Plant Data for Material
*&———————————————————————*
*& SELECTION SCREEN
*&———————————————————————*
” Input parameters for the report – both are mandatory
SELECTION-SCREEN BEGIN OF BLOCK b1 WITH FRAME TITLE TEXT-001.
PARAMETERS: p_matnr TYPE matnr OBLIGATORY, ” Material Number
p_werks TYPE werks_d OBLIGATORY. ” Plant
SELECTION-SCREEN END OF BLOCK b1.
*&———————————————————————*
*& INTERNAL TABLES AND WORK AREAS
*&———————————————————————*
” Internal tables to store data returned by the function module
DATA: gt_mdpsx TYPE TABLE OF mdps, ” MRP element data (dates, doc numbers)
gs_mdpsx TYPE mdps, ” Work area for MDPSX
gt_mdezx TYPE TABLE OF mdez, ” MRP element quantities
gs_mdezx TYPE mdez, ” Work area for MDEZX
gt_mdsux TYPE TABLE OF mdsu, ” Summary data
gs_mdsux TYPE mdsu. ” Work area for MDSUX
” Structures for exporting parameters from function module
DATA: gs_mt61d TYPE mt61d, ” Material requirements planning data
gs_mdkp TYPE mdkp, ” MRP controller and configuration
gs_cm61m TYPE cm61m, ” MRP list control data
gs_mdsta TYPE mdsta, ” MRP statistics
gv_ergbz TYPE ergbz. ” Result indicator
” Variables for processing and display
DATA: gv_labst TYPE labst, ” Unrestricted stock quantity
gv_available TYPE labst, ” Available quantity (opening stock)
lv_running_stock TYPE mng01, ” Running available stock
lv_matnr TYPE matnr, ” Material number with leading zeros
lv_txt TYPE char30, ” Text for MRP element description
lv_count TYPE i. ” Counter for total records
*&———————————————————————*
*& START-OF-SELECTION
*&———————————————————————*
START-OF-SELECTION.
“*——————————————————————*
“* Step 1: Convert Material Number with Leading Zeros
“*——————————————————————*
” SAP stores material numbers with leading zeros in database
” This conversion ensures proper format for database queries
CALL FUNCTION ‘CONVERSION_EXIT_ALPHA_INPUT’
EXPORTING
input = p_matnr
IMPORTING
output = lv_matnr.
“*——————————————————————*
“* Step 2: Get Current Stock from MARD Table
“*——————————————————————*
” MARD contains storage location data for materials
” We sum all unrestricted stock (LABST) across storage locations
SELECT SINGLE SUM( labst )
INTO gv_labst
FROM mard
WHERE matnr = lv_matnr
AND werks = p_werks.
” Initialize available quantity based on query result
IF sy-subrc = 0.
gv_available = gv_labst. ” Stock found
ELSE.
gv_available = 0. ” No stock found
ENDIF.
“*——————————————————————*
“* Step 3: Call Function Module to Get Stock Requirements List
“*——————————————————————*
” MD_STOCK_REQUIREMENTS_LIST_API is SAP standard FM used by MD04
” It returns all MRP elements (receipts and requirements)
CALL FUNCTION ‘MD_STOCK_REQUIREMENTS_LIST_API’
EXPORTING
matnr = lv_matnr ” Material number
werks = p_werks ” Plant
IMPORTING
e_mt61d = gs_mt61d ” Planning data
e_mdkp = gs_mdkp ” MRP configuration
e_cm61m = gs_cm61m ” Control data
e_mdsta = gs_mdsta ” Statistics
e_ergbz = gv_ergbz ” Result indicator
TABLES
mdpsx = gt_mdpsx ” MRP element master data
mdezx = gt_mdezx ” MRP element quantities
mdsux = gt_mdsux ” Summary data
EXCEPTIONS
material_plant_not_found = 1 ” Material doesn’t exist
plant_not_found = 2 ” Plant doesn’t exist
OTHERS = 3. ” Other errors
” Error handling for function module call
IF sy-subrc <> 0.
WRITE: / ‘Error getting stock requirements data’.
WRITE: / ‘Return Code:’, sy-subrc.
EXIT.
ENDIF.
” Check if any data was returned
IF gt_mdpsx IS INITIAL AND gt_mdezx IS INITIAL.
WRITE: / ‘No stock requirements data found for Material:’, p_matnr,
‘Plant:’, p_werks.
EXIT.
ENDIF.
“*——————————————————————*
“* Step 4: Display Report Header Information
“*——————————————————————*
WRITE: / ‘Stock/Requirements List as of’, sy-datum, sy-uzeit.
WRITE: / sy-uline(155).
WRITE: / ‘Material:’, p_matnr, ‘ Plant:’, p_werks.
WRITE: / sy-uline(155).
SKIP 1.
” Display MRP configuration details if available
IF gs_mdkp IS NOT INITIAL.
WRITE: / ‘MRP Controller:’, gs_mdkp-dispo. ” Person responsible
WRITE: / ‘MRP Type:’, gs_mdkp-dismm. ” Planning strategy
WRITE: / ‘Lot Size:’, gs_mdkp-disls. ” Lot sizing procedure
SKIP 1.
ENDIF.
“*——————————————————————*
“* Step 5: Display Column Headers
“*——————————————————————*
” Column positions are carefully aligned for readability
WRITE: / ‘Date’, ” Date of MRP element
15 ‘MRP Element data’, ” Type of element (receipt/requirement)
45 ‘Doc Number’, ” Document number reference
70 ‘Receipt Qty’, ” Quantity of receipt
90 ‘Available Qty’. ” Running available stock
WRITE: / sy-uline(155).
” Initialize running stock with opening balance
lv_running_stock = gv_available.
“*——————————————————————*
“* Step 6: Display Opening Stock
“*——————————————————————*
” Show current available stock as starting point
WRITE: / sy-datum USING EDIT MASK ‘__/______’, ” Today’s date formatted
90 gv_available. ” Opening stock quantity
WRITE: / sy-uline(155).
“*——————————————————————*
“* Step 7: Process and Display MRP Elements
“*——————————————————————*
” Loop through all MRP elements (receipts and requirements)
LOOP AT gt_mdpsx INTO gs_mdpsx.
” Get corresponding quantity data for this MRP element
” Match by date (dat00) and planning number (plumi)
READ TABLE gt_mdezx INTO gs_mdezx
WITH KEY dat00 = gs_mdpsx-dat00
plumi = gs_mdpsx-plumi.
IF sy-subrc = 0.
“*—————————————————————-*
“* Determine MRP Element Type Description
“*—————————————————————-*
” DELKZ field indicates whether element is receipt or requirement
CASE gs_mdpsx-delkz.
WHEN ‘V’.
lv_txt = ‘Receipt’. ” Incoming material
WHEN ‘B’.
lv_txt = ‘Requirement’. ” Outgoing material demand
WHEN ‘L’.
lv_txt = ‘Delivery Schedule’. ” Scheduled delivery
WHEN ‘A’.
lv_txt = ‘Dependent Reqmt’. ” From BOM explosion
WHEN ‘U’.
lv_txt = ‘Stock Transfer’. ” Between storage locations
WHEN OTHERS.
lv_txt = gs_mdpsx-delkz. ” Display code if unknown
ENDCASE.
“*—————————————————————-*
“* Calculate Running Available Stock
“*—————————————————————-*
” Receipts (+) increase stock, Requirements (-) decrease stock
IF gs_mdpsx-delkz = ‘V’.
” Receipt: Add to available stock
lv_running_stock = lv_running_stock + gs_mdezx-mng03.
ELSE.
” Requirement: Subtract from available stock
lv_running_stock = lv_running_stock – gs_mdezx-mng02.
ENDIF.
“*—————————————————————-*
“* Display MRP Element Line
“*—————————————————————-*
” Show each element with aligned columns
WRITE: / gs_mdpsx-dat00 USING EDIT MASK ‘__/______’, ” Date formatted
15 lv_txt, ” Element type description
45 gs_mdpsx-delnr, ” Document number
70 gs_mdezx-mng03, ” Receipt quantity
90 lv_running_stock. ” Projected available stock
” Increment record counter
lv_count = lv_count + 1.
ENDIF.
ENDLOOP.
“*——————————————————————*
“* Step 8: Display Summary Information
“*——————————————————————*
WRITE: / sy-uline(155).
SKIP 1.
” Show total number of MRP elements processed
WRITE: / ‘Total Records:’, lv_count.
” Show current physical stock
WRITE: / ‘Current Stock:’, gv_labst.
” Display summary data count if available
IF gt_mdsux IS NOT INITIAL.
SKIP 2.
WRITE: / ‘Summary Data Available – Total Entries:’, lines( gt_mdsux ).
ENDIF.
*&———————————————————————*
*& END OF REPORT
*&———————————————————————*
Output for standard MD04 real stock view:
Output for custom Report output:
Conclusion :
This custom ABAP report demonstrates how standard SAP functionality like MD04 can be replicated and customized using clean ABAP logic and standard APIs. By leveraging MD_STOCK_REQUIREMENTS_LIST_API and combining it with stock data from MARD, the report provides a clear and reliable view of stock movements and future requirements.
From my experience, building such custom reports not only helps meet specific business requirements but also improves understanding of SAP’s internal MRP data flow. This approach offers flexibility for further enhancements such as ALV output, additional filters, or integration with planning dashboards, making it a practical alternative to standard transactions when customization is required.
Thanks for Reading My Blog..
.
IntroductionIn SAP Materials Management, the Stock or Requirements List MD04 is one of the most frequently used transactions for planners and production teams. It provides a real-time view of current stock, incoming receipts, and outgoing requirements for a material at plant level. However, in real project scenarios, users often need a simplified, customized, or report-based version of MD04 that can be enhanced further or adapted to specific business needs. During one such requirement, I worked on building a custom ABAP report that replicates the core functionality of MD04 while keeping the logic transparent and flexible. This blog explains how a custom Stock/Requirements Report can be built using standard SAP tables and function modules, without modifying standard SAP transactions.Solution Review :The custom report ZSTCOK_912 is designed to display stock and MRP elements for a given Material and Plant, closely mirroring the MD04 output.1. Selection ScreenThe report starts with a simple and user friendly selection screen:Material Number MATNRPlant WERKSBoth parameters are mandatory to ensure accurate stock evaluation.2. Material Number ConversionSince SAP stores material numbers with leading zeros, the report uses:CONVERSION_EXIT_ALPHA_INPUTThis ensures the material number is in the correct internal format before database access.3. Current Stock DeterminationTo calculate the opening balance:Table MARD is readAll unrestricted stock LABST across storage locations is summedThis provides the current physical stock, which becomes the starting available quantity.4. Fetching Stock or Requirements DataThe core of the solution uses the standard SAP function module:MD_STOCK_REQUIREMENTS_LIST_APIThis is the same API used by MD04 and returns:MRP elements receipts and requirements QuantitiesPlanning and control dataThe data is stored in internal tables such as MDPSX, MDEZX, and MDSUX.5. Display Logic and Running Stock CalculationEach MRP element is processed sequentially:Receipts increase available stockRequirements reduce available stockA running available quantity is calculated and displayed line by line, giving users a projected stock position over time.6. Output FormatThe report displays:DateMRP element type Receipt, Requirement, Dependent Requirement, etc.Document numberReceipt quantityProjected available stockAdditionally, summary information such as total records processed and current stock is displayed at the end.The Complete Solution Code*&———————————————————————*
*& Report ZSTCOK_912
*&———————————————————————*
*& Custom Stock/Requirements Report
*& Purpose: Display stock and requirements similar to MD04 transaction
*&———————————————————————*
REPORT ZSTCOK_912.
*&———————————————————————*
*& DATA DECLARATIONS
*&———————————————————————*
” Reference to standard SAP tables for material master data
TABLES: mara, ” General Material Data
marc. ” Plant Data for Material
*&———————————————————————*
*& SELECTION SCREEN
*&———————————————————————*
” Input parameters for the report – both are mandatory
SELECTION-SCREEN BEGIN OF BLOCK b1 WITH FRAME TITLE TEXT-001.
PARAMETERS: p_matnr TYPE matnr OBLIGATORY, ” Material Number
p_werks TYPE werks_d OBLIGATORY. ” Plant
SELECTION-SCREEN END OF BLOCK b1.
*&———————————————————————*
*& INTERNAL TABLES AND WORK AREAS
*&———————————————————————*
” Internal tables to store data returned by the function module
DATA: gt_mdpsx TYPE TABLE OF mdps, ” MRP element data (dates, doc numbers)
gs_mdpsx TYPE mdps, ” Work area for MDPSX
gt_mdezx TYPE TABLE OF mdez, ” MRP element quantities
gs_mdezx TYPE mdez, ” Work area for MDEZX
gt_mdsux TYPE TABLE OF mdsu, ” Summary data
gs_mdsux TYPE mdsu. ” Work area for MDSUX
” Structures for exporting parameters from function module
DATA: gs_mt61d TYPE mt61d, ” Material requirements planning data
gs_mdkp TYPE mdkp, ” MRP controller and configuration
gs_cm61m TYPE cm61m, ” MRP list control data
gs_mdsta TYPE mdsta, ” MRP statistics
gv_ergbz TYPE ergbz. ” Result indicator
” Variables for processing and display
DATA: gv_labst TYPE labst, ” Unrestricted stock quantity
gv_available TYPE labst, ” Available quantity (opening stock)
lv_running_stock TYPE mng01, ” Running available stock
lv_matnr TYPE matnr, ” Material number with leading zeros
lv_txt TYPE char30, ” Text for MRP element description
lv_count TYPE i. ” Counter for total records
*&———————————————————————*
*& START-OF-SELECTION
*&———————————————————————*
START-OF-SELECTION.
“*——————————————————————*
“* Step 1: Convert Material Number with Leading Zeros
“*——————————————————————*
” SAP stores material numbers with leading zeros in database
” This conversion ensures proper format for database queries
CALL FUNCTION ‘CONVERSION_EXIT_ALPHA_INPUT’
EXPORTING
input = p_matnr
IMPORTING
output = lv_matnr.
“*——————————————————————*
“* Step 2: Get Current Stock from MARD Table
“*——————————————————————*
” MARD contains storage location data for materials
” We sum all unrestricted stock (LABST) across storage locations
SELECT SINGLE SUM( labst )
INTO gv_labst
FROM mard
WHERE matnr = lv_matnr
AND werks = p_werks.
” Initialize available quantity based on query result
IF sy-subrc = 0.
gv_available = gv_labst. ” Stock found
ELSE.
gv_available = 0. ” No stock found
ENDIF.
“*——————————————————————*
“* Step 3: Call Function Module to Get Stock Requirements List
“*——————————————————————*
” MD_STOCK_REQUIREMENTS_LIST_API is SAP standard FM used by MD04
” It returns all MRP elements (receipts and requirements)
CALL FUNCTION ‘MD_STOCK_REQUIREMENTS_LIST_API’
EXPORTING
matnr = lv_matnr ” Material number
werks = p_werks ” Plant
IMPORTING
e_mt61d = gs_mt61d ” Planning data
e_mdkp = gs_mdkp ” MRP configuration
e_cm61m = gs_cm61m ” Control data
e_mdsta = gs_mdsta ” Statistics
e_ergbz = gv_ergbz ” Result indicator
TABLES
mdpsx = gt_mdpsx ” MRP element master data
mdezx = gt_mdezx ” MRP element quantities
mdsux = gt_mdsux ” Summary data
EXCEPTIONS
material_plant_not_found = 1 ” Material doesn’t exist
plant_not_found = 2 ” Plant doesn’t exist
OTHERS = 3. ” Other errors
” Error handling for function module call
IF sy-subrc <> 0.
WRITE: / ‘Error getting stock requirements data’.
WRITE: / ‘Return Code:’, sy-subrc.
EXIT.
ENDIF.
” Check if any data was returned
IF gt_mdpsx IS INITIAL AND gt_mdezx IS INITIAL.
WRITE: / ‘No stock requirements data found for Material:’, p_matnr,
‘Plant:’, p_werks.
EXIT.
ENDIF.
“*——————————————————————*
“* Step 4: Display Report Header Information
“*——————————————————————*
WRITE: / ‘Stock/Requirements List as of’, sy-datum, sy-uzeit.
WRITE: / sy-uline(155).
WRITE: / ‘Material:’, p_matnr, ‘ Plant:’, p_werks.
WRITE: / sy-uline(155).
SKIP 1.
” Display MRP configuration details if available
IF gs_mdkp IS NOT INITIAL.
WRITE: / ‘MRP Controller:’, gs_mdkp-dispo. ” Person responsible
WRITE: / ‘MRP Type:’, gs_mdkp-dismm. ” Planning strategy
WRITE: / ‘Lot Size:’, gs_mdkp-disls. ” Lot sizing procedure
SKIP 1.
ENDIF.
“*——————————————————————*
“* Step 5: Display Column Headers
“*——————————————————————*
” Column positions are carefully aligned for readability
WRITE: / ‘Date’, ” Date of MRP element
15 ‘MRP Element data’, ” Type of element (receipt/requirement)
45 ‘Doc Number’, ” Document number reference
70 ‘Receipt Qty’, ” Quantity of receipt
90 ‘Available Qty’. ” Running available stock
WRITE: / sy-uline(155).
” Initialize running stock with opening balance
lv_running_stock = gv_available.
“*——————————————————————*
“* Step 6: Display Opening Stock
“*——————————————————————*
” Show current available stock as starting point
WRITE: / sy-datum USING EDIT MASK ‘__/______’, ” Today’s date formatted
90 gv_available. ” Opening stock quantity
WRITE: / sy-uline(155).
“*——————————————————————*
“* Step 7: Process and Display MRP Elements
“*——————————————————————*
” Loop through all MRP elements (receipts and requirements)
LOOP AT gt_mdpsx INTO gs_mdpsx.
” Get corresponding quantity data for this MRP element
” Match by date (dat00) and planning number (plumi)
READ TABLE gt_mdezx INTO gs_mdezx
WITH KEY dat00 = gs_mdpsx-dat00
plumi = gs_mdpsx-plumi.
IF sy-subrc = 0.
“*—————————————————————-*
“* Determine MRP Element Type Description
“*—————————————————————-*
” DELKZ field indicates whether element is receipt or requirement
CASE gs_mdpsx-delkz.
WHEN ‘V’.
lv_txt = ‘Receipt’. ” Incoming material
WHEN ‘B’.
lv_txt = ‘Requirement’. ” Outgoing material demand
WHEN ‘L’.
lv_txt = ‘Delivery Schedule’. ” Scheduled delivery
WHEN ‘A’.
lv_txt = ‘Dependent Reqmt’. ” From BOM explosion
WHEN ‘U’.
lv_txt = ‘Stock Transfer’. ” Between storage locations
WHEN OTHERS.
lv_txt = gs_mdpsx-delkz. ” Display code if unknown
ENDCASE.
“*—————————————————————-*
“* Calculate Running Available Stock
“*—————————————————————-*
” Receipts (+) increase stock, Requirements (-) decrease stock
IF gs_mdpsx-delkz = ‘V’.
” Receipt: Add to available stock
lv_running_stock = lv_running_stock + gs_mdezx-mng03.
ELSE.
” Requirement: Subtract from available stock
lv_running_stock = lv_running_stock – gs_mdezx-mng02.
ENDIF.
“*—————————————————————-*
“* Display MRP Element Line
“*—————————————————————-*
” Show each element with aligned columns
WRITE: / gs_mdpsx-dat00 USING EDIT MASK ‘__/______’, ” Date formatted
15 lv_txt, ” Element type description
45 gs_mdpsx-delnr, ” Document number
70 gs_mdezx-mng03, ” Receipt quantity
90 lv_running_stock. ” Projected available stock
” Increment record counter
lv_count = lv_count + 1.
ENDIF.
ENDLOOP.
“*——————————————————————*
“* Step 8: Display Summary Information
“*——————————————————————*
WRITE: / sy-uline(155).
SKIP 1.
” Show total number of MRP elements processed
WRITE: / ‘Total Records:’, lv_count.
” Show current physical stock
WRITE: / ‘Current Stock:’, gv_labst.
” Display summary data count if available
IF gt_mdsux IS NOT INITIAL.
SKIP 2.
WRITE: / ‘Summary Data Available – Total Entries:’, lines( gt_mdsux ).
ENDIF.
*&———————————————————————*
*& END OF REPORT
*&———————————————————————*Output for standard MD04 real stock view:Output for custom Report output: Conclusion :This custom ABAP report demonstrates how standard SAP functionality like MD04 can be replicated and customized using clean ABAP logic and standard APIs. By leveraging MD_STOCK_REQUIREMENTS_LIST_API and combining it with stock data from MARD, the report provides a clear and reliable view of stock movements and future requirements.From my experience, building such custom reports not only helps meet specific business requirements but also improves understanding of SAP’s internal MRP data flow. This approach offers flexibility for further enhancements such as ALV output, additional filters, or integration with planning dashboards, making it a practical alternative to standard transactions when customization is required.Thanks for Reading My Blog.. . Read More Technology Blog Posts by Members articles
#SAP
#SAPTechnologyblog