When you're used to create buttons in ALV Grid dynamically then you think why SAP doesn't allow create dynamically buttons on GUI STATUS. You can change icon or text if you defined that function has dynamic text but you cannot create buttons at runtime and you always have to create GUI STATUS and GUI TITLE in SE41, which personally I don't like, as in most small reports you have to create usually one to five buttons.
So what I want to present to you today is a way to create buttons dynamically at program runtime without a need to create GUI STATUS and GUI TITLE for each program. In fact whole trick is to create firstly a GUI STATUS in empty program which will contain only functions with dynamic texts, and then to fill properly static class attribute.
So let's begin with creating our program to keep GUI STATUS and GUI TITLE. I will call it ZAB_DYNAMIC_GUI_STATUS. In the source code you do not need to put anything beside report keyword.
"! Dummy program for keeping GUI STATUS and TITLE "! Used by ZCA_AB_DYNAMIC_GUI "! Do not delete it!!! report zab_dynamic_gui_status.
Yes, that's all from the code point of view in this program. As said it's only to keep GUI STATUS and GUI TITLE.
Lets create GUI STATUS firstly and call it DYNAMIC_STATUS. Items on application toolbar will have the same naming pattern Fxx, so F01, F02 etc. Each of this function code should have dynamic function text with pattern ZCA_AB_DYNAMIC_GUI=>BUTTONS-Fxx where Fxx you have to replace by current function code.
Additionally to application toolbar, fill also function keys for save, up, back, exit, print... etc so you can also use it in your programs.
When you open standard transaction you may be surprised sometimes that although you're able to attach standard attachments while creating document, you're not able to attach business document at this time. It's because business documents needs to have specified an object to which it is linked and in case of GOS for standard transactions it's always called without object id (in creation mode). When you develop own transaction and you use GOS for standard or Z object then there is a possibility to omit that restriction, as during creation of GOS manager you can assign temporary object name to it. At save (or after save) you can move attachments and business documents from temporary object to final one.
The question is what will happen when you'll attach business document to temporary object but you will not save the document at the end? The document itself will be kept so you have to be sure that it will be deleted next archiving run.
I will show you an example on Purchase Requisition object which is used in Z-tcode.
In article Link Attachments of Purchase Requisition to Purchase Order I've shown how to link standard attachments from purchase requisition to purchase orders, but to have full set of options we also need a a method to link business documents of PR to PO. This is not so hard as we have in disposition class cl_alink_connection which allows to do such operations. Of course the time when you're copying the link depends on you, you can do it during posting of PO (as I do, to be sure that I will copy only this documents and attachments which are linked to PR's used in the PO ), you can do it after the PO is save with your some background job or you can try to insert the object directly to the GOS of purchase order. I didn't do direct attachment to GOS of PO but as I mention in the comments of Attachments article you can connect to GOS from class CL_PO_HEADER_HANDLE_MM which contains method GET_GOS_MANAGER. You can do it for example in PROCESS_ITEM method of ME_PROCESS_PO_CUST . You'll need to get header object firstly (type ref to if_purchase_order_mm ) and then call GET_GOS_MANAGER method.
Anyway, I will present you the method which I used in POST method of ME_PROCESS_PO_CUST BADI. As I said, it's quite simple if you know class cl_alink_connection. Firstly we need to check if any business document is attached to PR, I will do it with method cl_alink_connection=>find. Then when we have list of all business documents we can insert link to it to PO with cl_alink_connection=>insert.
As we got a short description of ESDUS and ESRUO and connected FMs in previous parts, then now it's time for examples. Let's start with scenarios which I described in first part
1. When you open one of the MM t-codes like ME22N, ME51N or MIGO you see that always you got on the screen one of the latest open document there. Sometimes not last but one of the lasts and you want to make it always last.
To be sure you get last document you have to select data from ESRUO table directly, sort it by timestamp and get last object. Then update setting of default document for transaction, in my example for ME52N/53N/54N.
data: fs_esruo type esruo. data: ft_esruo type standard table of esruo. data: f_active type esdus-active. data: ft_esduscom type standard table of esduscom.
select * into corresponding fields of table ft_esruo from esruo where uname eq sy-uname and object_typ eq 'BUS2105'. sort ft_esruo by timestamp descending. read table ft_esruo index 1 into fs_esruo. concatenate fs_esruo-object_id'A' into f_active.
Let's discus following scenarios with MM standard transactions:
When you open one of the MM t-codes like ME22N, ME51N or MIGO you see that always you got on the screen one of the latest open document there. Sometimes not last but one of the lasts and you want to make it always last.
You create MM documents using BAPI and you want that next time you open MM t-code which is used to display/edit this document then your document appears on the screen (of course if in the meantime user haven't created anything new)
You have created your own transaction to handle standard process, like creation of purchase orders or purchase requisitions. This transaction is used only in some special occasion like only in case of account assignment category is equal to 'A'. In such case for all documents which are created by your Z-transaction you've set up in user-exit that when standard transaction is called, then you leave it to your Z-transaction. In this case often MM transactions remembers last opened document, which was created by Z-transaction and at each run it will leave to it, so you want to clear the info about last called document from standard t-code.
You want to clear some default settings for the user (or set them) for standard t-code. This could be default value for some fields or toggle status of the section (for example header always expanded, items always collapsed.
In all of this cases you'll want to look at tables:
ESRUO (MM: Recently Used Objects)
ESDUS (MM: Dynamic User Settings)
and to function group MLSO which provides you few nice FM to handle entries in this tables:
We have all needed methods and implicit enhancement is also created so we can create a program to call MB51. We have to create a structure for ALV and include in it type t_list from our class which I've called zab_mb51_call so you should be able to replace it with your own name fast. In my example I will add only few fields beside the one found in MB51, but you can choose as many as it's needed.
types: begin of t_alv. include type t_list. types: dispo like marc-dispo, ekgrp like marc-ekgrp, verid like blpk-verid, spart like mara-spart, bklas like mbew-bklas, rows type epsssrows, vendor_name type mepo_vendor, grtxt like t157e-grtxt, xabln like mkpf-xabln, bldat type mkpf-bldat, end of t_alv.
Selection-options which are the same as in MB51 should be coded with the same names so we can pass them to RM07DOCS by method call_mb51_static.
I used REUSE_ALV here just to be able to do it faster, but ALV OO can be used as well as SALV. If you copy the code bellow and you'll have problems with excel export, then you'll have ot remove it or install to your SAP abap2xlsx classes which I used in this function.
Program runs in following sequence:
If one of the additional select-options is used then it does preselection and manipulates select-options passed to MB51
Call of MB51
Import of results and additional selection done on a base of the result table
In attachments you'll find NUGG files for class and program.
I can already call MB51 from previously created method but still I need to add an implicit enhancement into RM07DOCS so I'll be able to export results from MB51 and leave the program without displaying them. Enhancement must be done at the end of form process_list.
I'll create a method to do the export inside MB51 with only one changing parameter, which will check if we're calling MB51 from our class and if yes then it will copy results of MB51 to memory and leave the program.