Skip to Content
Technical Articles
Author's profile photo Jigang Zhang 张吉刚

how Print-relevant purchasing document changes trigger printout

After Purchase Order been created at the system, the relevant users should get notice email if any important fields been changed like net price, delivery address, items, etc. SAP System already provides an excellent solution with transaction OMFS, where you can maintain a combination of table name and table fields along with control flags to control whether PO printout should be triggered or not.


But customer demand never stops: what if some organization wants to get email notifications for specific changes while other organizations don’t? This article will try to introduce the mechanism of print-relevant PO document changes and some tips when extending it to the organization level.

SAP Standard: Fields Relevant to Printouts of Changes (TCODE: OMFS)

Customized settings of Fields Relevant to Printouts of Changes are stored at the T166C table.

T166C is the key table to control print-relevant PO changes, it’s been used to check changes at field level include header level/item level/schedule line item level against table EKKO/EKPO/EKET, etc. accordingly, as well as address table ADRC. And field XBEST is the indicator of whether active this field for printout.

Besides, there’re several aspects that determine whether to trigger PO printout (include email been send out).

  1. The first thing is the mode of Print Operation of PO: new PO creation, PO changes or PO display/preview will function differently. Obviously, new PO creation, PO display/print preview shouldn’t trigger printout.
  2. Second is whether the changes of PO been regards as PO changes or not (for example, PO items field changes are captured using change document object EINKBELEG).
  3. Except for the T166C control PO header/item field level, table T166A/T166K/T166P table is been used to validate the changes of header/item at text level based on the combination of Print Operation, Purchasing Document Category, Purchasing Document Type.

One example of how print-relevant PO document changes been triggered

First, look up why the output for PO 5504023487 at PO messages was triggered at 02-14-2019 22:06:03.

Check the PO header/item changes at the triggered time inside ME23N, which change document object is EINKBELEG.

Goto TCODE: SCDO with this object name: EINKBELEG. Here PO important tables like EKKO/EKPO/EKET been assigned to this object. This means changes in those tables will be saved linked to this object.

Get the changer number 0716567251 by using PO number, change date/time, and object EINKBELEG at Change document header table CDHDR:

Then go to Change document items table CDPOS using key: object EINKBELEG, PO number plus changer number 0716567251 fetched from the above step.

At the T166C entry list, we can see the Item Delivery Date(EKET-EINDT) is a print-relevant field with XBEST = ‘X’. That’s why the print-relevant output been triggered.

  • PO header/item fields have been changed which will be saved at history table CDHDR/CDPOS with object EINKBELEG. And if those changed fields belong to T166C, it’ll trigger print-relevant printout.
  • For PO text changes, usually, the driver program will use FUNCTION ‘SELECT_TEXT’ to get all the text objects and compared with entries maintained at T166A/T166K/T166P table. If matched, will trigger printout.
  • For PO header/item fields been changed which not belong to object EINKBELEG will not trigger printout. Especially for object ‘ADRESSE’ which relevant to address texts changes (not the same as ADRC! ADRC table field can be maintained at T166C table)


Make ‘Fields Relevant to Printouts of Changes’ works at Organization level

If we need to let some organizations get email notifications for specific field changes while others don’t, have to extend T166C to the organization level. The idea is simple, just insert purchasing organization as key fields and create new customized table Z166C, then replace all validation depends on table T166C with this new Z166C. Sounds quite straight forward, but still some points need to pay attention to.

This new table Z166C will be checked &used only at PO printout driver programs and no usage at any other places so no impact for all other standard processing. As purchase order form is highly customized, most of the company will use their own forms and driver programs for PO printout, but SAP provided driver program SAPLMEDRUCK is a good reference (SAPFM06P is the previous version).

Key Field: DRUVO

It’s a local variable for Print Operation which comes from NAST-AENDE, could be different name per driver program which refer to T166K-DRUVO. If it’s ‘1’ means the PO has no changes; if it’s ‘2’ means the PO has changed. Here the change means PO been changed including but not limited to print-relevant changes.

Key Function Module: ‘ME_READ_PO_FOR_PRINTING’

It is used to read the relevant purchasing document data during the print preparation of purchasing documents (The subsequent printout takes place with the help of the function module ‘ME_PRINT_PO’). This FM will check using T166C and return deep structure DOC which mandatory for the following processing. As we’re going to replace T166C by Z166C with a purchase organization and don’t want to enhance this standard FM or create a new one, so use DRUVO = ‘1’ to skip T166C’s impacts. The return code of this FM must be set back to 0, otherwise, further printout process will be skipped as well. And the standard error message ME140 here for ‘No print-relevant changes to document & exist’ must be checked and skipped if exists.

‘ME_CHANGES_PRINTOUT’ is the standard function module to collect PO changes at text level by check table T166A/ T166K/ T166P and at field level by check table T166C. Find the subroutine which read change document headers and fetch those 4 indicators and text number of change text from T166C, we need replacing with Z166C to make it run at the purchase organization level.

Still use the standard ME140 if no print-relevant changes to document exist to avoid unnecessary queries. NAST and message logs are clear as well.



Possible scenarios relevant to PO field-relevant printout:

  1. At creation mode, PO has no regard as changes at all, so no need to trigger field-relevant printout.
  2. At change mode, PO has been updated, and pass print relevant field check at either Z166C or T166A/ T166K/ T166P. It’ll trigger field-relevant printout.
  3. At change mode, PO updated and cannot pass print relevant field check at both Z166C and T166A/ T166K/ T166P, then no need to trigger field-relevant printout.
  4. At display mode, no matter can pass print relevant field check or not, no need to trigger field-relevant printout.


Tips: Debug PO output (First processing)

  • Transaction me22n -> make changes-> go to Message(will show new output type with yellow status even haven’t SAVE) -> choose entry and click on further data -> change in dispatch time as 3 ‘Send with application own transaction’ ;
  • Transaction ME9F with document no. and message -> choose the document and process it.

Added at 2022/April

  • The standard output process will ignore all ‘I’ insert entries for sure, which means insert will not be regarded as change for sure!
  • The latest change history has been fetched at LESEN_AENDERUNGEN and transfer to ANALYSE_AENDERUNGEN, and it will skip EKKN/EKES entry!


Assigned Tags

      You must be Logged on to comment or reply to a post.
      Author's profile photo Pablo Casado
      Pablo Casado

      Hi Jigang ,
      thanks for sharing.
      It is possible to send this information automatically in a segment through IDOC ORDERS05 ?

      Author's profile photo Jigang Zhang 张吉刚
      Jigang Zhang 张吉刚
      Blog Post Author
      as ORDERS05 is standard and doesn't exist segment for this information, I don't think there're exist an automatic way, maybe have to customize.
      Author's profile photo Doncy Toms
      Doncy Toms

      Should be Multiple Issuing field unflag at the output type level in the NACE transaction?

      Author's profile photo Jigang Zhang 张吉刚
      Jigang Zhang 张吉刚
      Blog Post Author

      if multiply issuing not been ticked then can't send same output to the same partner more than once. No need to monitor changes as well :  )

      Author's profile photo Sandeep Yashwant Dixit
      Sandeep Yashwant Dixit

      Hi Jigang ,

      Thanks for sharing this.

      How is field ROUNR used  for custom functionality . I understand we can configure custom routines 90 to 99 here  .

      We have a requirement to control triggering of print/idoc outputs  in S4 hana based on custom requirement .We are exploring if this table can be used to achieve this.

      Author's profile photo Jigang Zhang 张吉刚
      Jigang Zhang 张吉刚
      Blog Post Author

      hi Sandeep Yashwant Dixit

      Field ROUNR belongs to T166C, it includes in the newly created Z166C table for my case. It works like a check table and does not perform a different routine from Z166C compared with standard T166C.


      Author's profile photo Boris Dimitrov
      Boris Dimitrov

      Dear Jigang,

      Thank you for the great blog post!

      I would higly appriciate your expertise on the below case.

      I did the necessary customizing settings in T166C and new message is generated sucessfully after save.
      In my case scenario: a PO is created -> approved via releasy strategy -> Initial create message is triggered.
      After that fields, not relevant for triggering a new approval workflow, are changed -> new message is triggered with flag CHANGE_INDICATOR flagged.

      Basically if a user opens the pdf form for this new message it will display only the changed items.

      I am struggling to find the other way around
      If line item(s) are deleted, the users would like to have a new message generated automatically, which will display only the line items which are not flagged for deletion, as those will be send to vendor.
      Is there a way with standard customizing to automatically generate new message after chagnge, where the Change indicator flag is not ticked for this message? So that it would display the whole document. In this particular case only the line items which are not deleted.

      Best Regards,

      Author's profile photo Jigang Zhang 张吉刚
      Jigang Zhang 张吉刚
      Blog Post Author

      Boris Dimitrov

      From my understanding, your message output can be controlled totally customized as all the below details had been recorded at the time PO had been saved. For ECC at least.

      • Whether the Change indicator flag has been ticked or not by monitoring the indicator NAST-AENDE at your driver program; you may change it by force if someplace using this field to determine whether trigger the output if not ticked.
      • Debug before and after FM 'ME_READ_PO_FOR_PRINTING', keep eyes on returns of parameter cx_druvo and table DOC. Modify it if required!
      • For detailed items change check T166C, doc-xekpo[] will be deleted accordingly iusing T166C check and if no print relevant fields. Check along with EKPO-LOEKZ.
      Author's profile photo Erdem Tireli
      Erdem Tireli

      Hi Jigang,

      Thank you for this insightful article.

      I'm currently working on a requirement where I need to print a canceled PO.
      Every time when I try to print a PO where all the order items are deleted/trash-canned via ME9F, I am having the "ME140 - no print relevant changes to documents exists" message. I also have the same message when I click on "Display Message Preview".

      How can I overcome this issue and print a canceled PO?

      Thank you for your help in advance.
      Best regards,

      Author's profile photo Jigang Zhang 张吉刚
      Jigang Zhang 张吉刚
      Blog Post Author

      Erdem Tireli

      The canceled items have been fetched through 'ME_READ_PO_FOR_PRINTING' and stored in the internal table gt_doc-xekpo[].

      Cause the PO driver program is totally customized, you can control the output process by setting the flag (which refers to T166K-DRUVO) when all items have been rejected.

      Author's profile photo Erdem Tireli
      Erdem Tireli

      Thank you very much for your help Jigang.

      This will help us a lot.

      Best regards,


      Author's profile photo Joshua Cu
      Joshua Cu

      Did you encounter a problem with a method that removes line without changes, only items with changes are in the form. CALL METHOD me->remove_unchanged_item. Found under the method COMPLETE_DATA under method READ in object type SE24: CL_PURCHASE_DOC_OUTPUT. We found that this method remove_unchanged_item, kept on removing items that has no change on them. Is there a way to also include all items even if items has no change on them? We are using NAST output. Program SAPFM06P form routine ADOBE_ENTRY_NEU

      Thank you very much for your advice.

      Author's profile photo Jigang Zhang 张吉刚
      Jigang Zhang 张吉刚
      Blog Post Author

      Adding them back after deletion will not be a good option.

      Maybe you can try monitoring those fields and make them not match this condition check, to SKIP CALL METHOD me->remove_unchanged_item.

      Then you can keep those items even if it's not been changed.


      Author's profile photo syed hussaini
      syed hussaini


      I am working on similar requirement to print the both changed / unchanged items along with the change text at the end of changed items. We still use sap script. After the function module call 'ME_READ_CHANGES_EINKBELEG'  in function module ME_READ_PO_FOR_PRINTING for fetching changed items. It deleted the unchanged items. Any suggestions to skip the deletion of unchanged line items.

      Thank You


      Author's profile photo Jigang Zhang 张吉刚
      Jigang Zhang 张吉刚
      Blog Post Author

      syed hussaini  I've been struggling with the SAP community logon issue recently..

      I don't have a suitable case to test right now, i remember that the canceled items have been fetched through 'ME_READ_PO_FOR_PRINTING' and stored in the internal table gt_doc-xekpo[].

      So you can try just add them back to gt_doc-xekpo[]  by yourself like below after FM:'ME_READ_PO_FOR_PRINTING' :

        SELECT * FROM ekpo APPENDING TABLE gt_doc-xekpo[]
          WHERE ebeln = nast-objky
            AND loekz = 'L'.