logo

Are you need IT Support Engineer? Free Consultant

Troubleshooting the NACE/NAST Output Determination…

  • By Sanjay
  • 26/05/2026
  • 6 Views


The BRF+ output determination framework is available for Inventory Management in S/4HANA. However, the traditional NACE/NAST output determination process still fully works and can be used in the same way as in ECC systems. When troubleshooting issues related to this output determination technology, SAP Note 426554 is an essential reference for analysis.

This blog is divided into two parts. The first part demonstrates, through a practical example, how to review and complete Checklist 1 from SAP Note 426554 to ensure that all required configurations are correctly maintained. The second part provides a detailed explanation of the system process flow, including debugging points that can help troubleshoot issues related to the classic output determination process.

Image/data in this Blog Post is from SAP internal systems, sample data, or demo systems. Any resemblance to real data is purely coincidental.

The example used here was executed on an old SAP ERP system running SAP_APPL package level 605. It consists of an initial entry of stock post on MIGO transaction using movement type 561 with an individual slip for output type WE01.

The MM-IM customizing can be reached using SPRO transaction, IMG path: ‘Materials Management' → ‘Inventory Management and Physical Inventory', but for short, transaction OLMB will be used to access the subfolders of that path.

1. Output type to be generated

For this example we want to use a WE01 output type with Individual Slip.

2. Form and Print program

The Form, Print Program and Form Routine assigned to the output type to be used can be checked on path OMLB → ‘Output Determination' → ‘Assign Forms and Programs':

Gabriel_Kunz_9-1778696972385.Png

  • Program: SAPM07DR
  • Form Routine: ENTRY_WE01
  • Form: WESCHEINVERS1

Transaction M706 or transaction NACE + Application ‘ME', selecting the output type and then clicking on ‘Processing Routines' will show the same result and can also be used as alternate paths for further information such as access sequences, condition tables, condition record key fields, etc.

3. Access Sequence and Condition Table

The standard Access Sequence range is from 0001 to 0007 and can be consulted using path OMLB → ‘Output Determination'  → ‘Maintain Output Types'  or transaction M706 and then double-click on the output type that you wish to check, in this case output type WE01:

Gabriel_Kunz_1-1778697866539.Png

Double-click on the Access Sequence number will lead us to a screen where double-clicking the folder ‘Accesses' will show us our condition table (standard range from 070 to 075):

Gabriel_Kunz_4-1778698022117.Png

Inventory management uses B tables for the condition records, so table 72 corresponds to database table B072.

The subfolder ‘Fields' corresponds to the key fields that will be used on the condition table (item 6.) and will be mapped into the communication structures KOMKBME and KOMPBME:

Gabriel_Kunz_8-1778696896751.Png

  • Access Sequence: 0003
  • Condition table: 72 (B072 in SE16)
  • Key fields:
    • VGART – KOMKBME – Trans./Event Type
    • WEVER – KOMKBME – Print Version
    • KZDRU – KOMPBME – Print item

4. Transaction used

We are using transaction MIGO to post the 561, on the MIGO screen we are selecting the print version 1 for the ‘Individual Slip' (according to the F1 – Help for the field in MIGO):

Gabriel_Kunz_6-1778698228055.Png

The operation ‘Goods Receipt' + ‘Others' with movement type 561 assigns the transaction code ‘MIGO_GI' for the header of the material document and in table T158, the transaction event type ‘WA' is assigned to that transaction.

  • Transaction: MIGO_GI
  • Print Version (WEVER): 1 (Individual Slip)
  • Transaction Event Type (VGART): WA

5. Movement Type

Under the path OLMB → ‘Print Control' → ‘Maintain Print Indicator for Goods Receipt Documents' we can see the print item (KZDRU) assigned to the movement type 561:

Gabriel_Kunz_1-1778696426139.Png

This indicator can also be checked on OMJJ transaction:

Gabriel_Kunz_1-1778698499277.Png

  • Movement type: 561
  • Print Item (KZDRU): 1

6. Condition Record key fields

On Item 3. we found the key fields for the condition record select:

  • VGART – KOMKBME – Trans./Event Type
  • WEVER – KOMKBME – Print Version
  • KZDRU – KOMPBME – Print item

On Itens 4. and 5. we found the values for those fields:

  • VGART – KOMKBME – Trans./Event Type = WA
  • WEVER – KOMKBME – Print Version = 1
  • KZDRU – KOMPBME – Print item = 1

Now we need to check if there is a Condition Record for those values based on the Condition Table. To do this, we can use transaction NACE or path OLMB → ‘Output Determination' → ‘Maintain Conditions' → ‘Display Condition: Inventory Mgmt' with the output type WE01:

Gabriel_Kunz_1-1779130506684.Png

If a condition record is found, the information we need from it is the Transmission time-spot (VSZTP) or Dispatch Time under the field ‘Date/Time'.

Alternatively, this information can be found using the B table for the condition number found and then using the condition record number (KNUMH) in table NACH.

  • Transmission time-spot of the condition record (VSZTP) = 4 (Send immediately (when saving the application)).

7. Print Indicator

For the print indicator, since we are posting the movement on MIGO, the flag is marked on the header:

Gabriel_Kunz_2-1779140532242.Png

8. Output Record

To check the output record status, we have to open the material document posted in MIGO using the operation ‘Display' → ‘Material Document'  and then click on ‘Display outputs':

Gabriel_Kunz_4-1779141605563.Png

9. Printer

When displaying the output created in MIGO transaction, you can check the communication method for the printer selected:

Gabriel_Kunz_6-1779142314193.Png

1. Form DRUCK_PRUEFEN (MM07MFD0)

In this form, we check the RM07M structure for the Print Indicator (XNAPR) to confirm if  the Print Version set on MIGO (WVERS1, WVERS2 or WVERS3) needs to be saved on MKPF.  The version is updated on MKPF-WEVER field.

  IF NOT RM07M-WVERS1 IS INITIAL. 
    MKPF-WEVER = 1.
    T158-WEVER = 1.
  ENDIF.
  IF NOT RM07M-WVERS2 IS INITIAL.
    MKPF-WEVER = 2.
    T158-WEVER = 2.
  ENDIF.
[...]

In this form we also set the XNAPR flag based on the NDR parameter of the user in case the goods movement was posted via BAPI/Idoc:

* Nachlesen Parameter NDR, wenn Verarbeitung über MB_CREATE -----------*
  IF NOT XMBWL IS INITIAL.
    IF NOT PR_UNAME IS INITIAL.
      PRINT_UNAME = PR_UNAME.
    ENDIF.
    IF PR_PRINT IS INITIAL.
      SELECT SINGLE * FROM USR05 WHERE BNAME = PRINT_UNAME
                                 AND   PARID = 'NDR'.
      IF SY-SUBRC IS INITIAL.
        RM07M-XNAPR = USR05-PARVA.
      ELSE.
        CLEAR RM07M-XNAPR.
      ENDIF.
    ELSEIF PR_PRINT = 1.
      RM07M-XNAPR = X.
    ELSEIF PR_PRINT = 2.
      CLEAR RM07M-XNAPR.
    ENDIF.
  ENDIF.
*---------

If the Print Indicator is not set, we clear the default print version so the system don't find any condition, not generating any slip. But the whole process for its determination is executed. It's not possible to skip the output determination, only to make sure it will not yield any results if not needed.

  IF RM07M-XNAPR IS INITIAL.
    CLEAR T158-WEVER.
  ENDIF.
ENDFORM.

For the example we are running, RM07M-XNAPR is set to X since we marked the flag in MIGO and the version is defined as 1 for both MKPF-WEVER and T158-WEVER because RM07M-WVERS1 is X, corresponding to version 1 (Individual Slip).

2. Form BUCHEN_NUMMERNVERGABE (MM07MFB9)

Here's where the call for the forms KOPFDIALOGSTRUKTUR_FUELLEN, POSIDIALOGSTRUKTUR_FUELLEN and MESSAGING occurs to build the communication structure for the header, item and then trigger the actual output determination, respectively:

 PERFORM kopfdialogstruktur_fuellen USING space. "<<< Build KOMKBME 

  LOOP AT xmseg.
    xindex = sy-tabix.
    xmseg-mblnr = xmkpf-mblnr.
    IF xmseg-lgpla IS INITIAL AND NOT xmseg-xblvs IS INITIAL.
      xmseg-lgpla = xmkpf-mblnr.
    ENDIF.
    IF xmseg-lfbnr IS INITIAL AND ( xmseg-kzbew = b OR t158-kzbew = b ).
      LOOP AT lfbnr WHERE zeile = xmseg-zeile.
        xmseg-lfbnr = xmkpf-mblnr.
      ENDLOOP.
    ENDIF.
    MODIFY xmseg INDEX xindex.
    READ TABLE xvm07m INDEX xmseg-zeile.
    PERFORM posidialogstruktur_fuellen USING space. "<<< Build KOMPBME
    PERFORM messaging USING space. "<<< Output determination

3. Form KOPFDIALOGSTRUKTUR_FUELLEN (MM07MFN0)

Here we have the call to the function COMMUNICATION_AREA_KOMKBME from SD area to fill the communication structure KOMKMBME with the information from the header of the material document (MKPF) like the Transaction Event Type (MKPF-VGART) and the Print Version (MKPF-WEVER).

This structure is used along with KOMPBME to define the condition table based on the access sequence on SD_COND_ACCESS function later in the process.

  CALL FUNCTION 'COMMUNICATION_AREA_KOMKBME'
       EXPORTING
            MSG_MKPF     = NMKPF
            MSG_T158     = T158
            MSG_PR_UNAME = PRINT_UNAME
       TABLES
            TAB_PART = PART.

Inside the function we can check the data returned to the imported structure KOMKBME:

Gabriel_Kunz_0-1779727654924.Png

4. Form POSIDIALOGSTRUKTUR_FUELLEN (MM07MFN0)

Like the previous form, we call the function COMMUNICATION_AREA_KOMPBME to fill the communication structure KOMPBME with the information of the items for the material document (MSEG) like the Print Item (T156-KZDRU) from Movement Type (MSEG-BWART), Plant (MSEG-WERKS), Storage Location (MSEG-LGORT), etc.

CALL FUNCTION 'COMMUNICATION_AREA_KOMPBME'
    EXPORTING
        MSG_MSEG   = NMSEG
        MSG_T156   = T156
        MSG_VM07M  = NVM07M
        MSG_MKPF   = MKPF
    TABLES
        TAB_PART = PART.

	

Inside of it we can check also check the return on structure KOMPBME:

Gabriel_Kunz_2-1779728816302.Png

5. Form MESSAGING (MM07MFN0)

This is where the actual output determination occurs based on all the information gathered previously and stored in KOMKBME and KOMPBME structures.

The condition technique from SD area is used for the determination of the condition table based on the access sequence determined by the key fields of the selected output.

The function MESSAGING starts the process by calling Form Routine COND_ACCESS_ME (LV61BMES) since the NACE application for the inventory management output is ME.

* do condition access if form already exists
    PERFORM (L_CONDITION_FORM) IN PROGRAM SAPLV61B USING APPLIKATION
                                                        SCHEMA
                                                    IF FOUND.
* L_CONDITION_FORM = COND_ACCESS_ME

6. Form COND_ACCESS_ME (LV61BMES)

The internal tables KOMT1 e KOMT2 are filled in Form KONDITIONSVORSTEP(SAPLV61B).

KOMT1 will be filled with the output types configured for Inventory Management (KAPPL = ‘ME'). The column KOZGF corresponds to the access sequence linked to the output types in column KSCHL:

Gabriel_Kunz_4-1779730654695.Png

KOMT2 will be filled with the condition tables for each access sequence. The correspondence in MM-IM is 1:1.

Gabriel_Kunz_6-1779730880950.Png

When both tables are filled, we start a nested loop on them by calling the forms XNAST_AUFBAUEN_AUS_KOMT1 (LV61BF0X) and NACHRICHTENSTATUS_SCHREIBEN (LV61BF0N).

7. Form NACHRICHTENSTATUS_SCHREIBEN (LV61BF0N)

In this form we execute the call to the condition technique function SD_COND_ACCESS:

*    start condition technique - find message type
        CALL FUNCTION 'SD_COND_ACCESS'
        EXPORTING
            application                = komt1-kappl
            condition_type             = komt1-kschl
            header_comm_area           = header_comm
            position_comm_area         = item_comm
            prestep                    = ' '
            protocol_access            = protocol_access
            read_only_one_record       = 'X'
            t682i_i                    = t682i
            koprt_i                    = koprt
            sdprothead_i               = g_sdprothead
        IMPORTING
            condition_is_purely_header = headkz
        TABLES
            condition_records          = kondtab
        EXCEPTIONS
            field_is_initial           = 8
            not_read_unqualified       = 2
            read_but_not_found         = 4.

8. Function SD_COND_ACCESS

Inside this function, we will run the form SEL_KONDTAB:

* do access
    PERFORM sel_kondtab TABLES condition_records
                        USING  t682i_i
                                application
                                condition_type
                                date
                                prestep
                                read_only_one_record
                                protocol_access
                                protocol_date
                                sdprothead_i
                                koprt_i
                                condition_in_memory_internal
                                call_modus
                                read_all_prestep
                    CHANGING condition_is_purely_header
                                condition_is_in_memory.

On that form, we loop through the key fields of the access sequence to check if they are filled. With that information, we perform a dynamic select on the condition table inside T681-KOTAB together with the key field values inside CODING_TAB internal table.

Since the select is dynamic, we do not know the exact point where it will be executed in SEL_KONDTAB form, so in order to check it we can place a breakpoint in the statement below and go from there:

IF se_memory_internal EQ no OR se_t682i-gzugr NE 'B'. "<<< Breakpoint here
    h_subrc = 4.
    IF se_prestep              = yes OR
        se_read_only_one_record = yes.
        IF t681-ksdat IS INITIAL.
        IF se_read_all_prestep IS INITIAL.
            SELECT * FROM (t681-kotab) APPENDING TABLE 
                    UP TO 1 ROWS
                    WHERE kappl  = se_kappl
                    AND   kschl  = se_kschl
                    AND   (coding_tab).
            h_subrc = sy-subrc.
        ELSE.
            SELECT * FROM (t681-kotab) APPENDING TABLE 
                    WHERE kappl  = se_kappl
                    AND   kschl  = se_kschl
                    AND   (coding_tab).
        ENDIF.

The statement below in form NACHRICHTENSTATUS_SCHREIBEN checks if the condition record number (XKNUMH) was found by the SEL_KONDTAB select (sy-subrc = 0 returned):

IF xknumh NE space.
     *nach-kschl = space.
    xsubrc = 1.
    READ TABLE xnach WITH KEY key-knumh = xknumh BINARY SEARCH.
    IF sy-subrc NE 0.

If the system found the record number, an entry is added to internal table XNAST.

9. Form BUCHEN_AUSFUEHREN (MM07MFB9)

In this form we can check XNAST table to confirm the entries built into it before the system starts the update tasks.

Gabriel_Kunz_0-1779735564521.Png

10.  Form PROGRAMM_AUFRUFEN (RSNAST00) (UPDATE MODE)

It is not possible to debug the print program SAPM07DR because the same is executed in update task by the call below in Form PROGRAMM_AUFRUFEN (RSNAST00), also executed in update task:

perform (tnapr-ronam) in program (tnapr-pgnam) using returncode
                                                     us_screen
                                                     if found.

For our example, TNAPR-RONAM = ENTRY_WE01 and TNAPR-PGNAM = SAPM07DR.

Those are the main points of the old output determination process run by Inventory Management, if the output is not triggered for some reason when the document is posted, those points can be useful to find out what information was missing and adjust the customizing accordingly.



Source link

Leave a Reply

Your email address will not be published. Required fields are marked *