Today I've got a question from Custodio de Oliveira (hope you don't mind mentioning) about Dark Eclipse settings which I'm using. As I know that settings colors in Eclipse for ADT is a pain, then I want to share with you my settings and the steps to achieve the same look like I have on my installation. Of course you can update it by your own, but at least you have a starting point.
Probably this is how your Eclipse looks like, or if not then the default settings for ADT. White and eye-killing.
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.
Many people still asks how to create field catalog for CL_GUI_ALV_GRID or REUSE_ALV_GRID_DISPLAY on a base of internal table. This is very easy since we have SALV classes, you could see it in my article Create XLSX/MHTML file from internal table in background and probably also somewhere in the net. To make it easier here are ready methods to create LVC and SLIS field catalogs from internal table using CL_SALV_CONTROLLER_METADATA and CL_SALV_TABLE. Both methods are created with new ABAP 7.40 SP05 syntax.
LVC Field catalog definition
class-methods lvc_fcat_from_internal_table importing
it_table type any table returningvalue(rt_fcat) type lvc_t_fcat.
LVC field catalog implementation
method lvc_fcat_from_internal_table. data: table type ref to data. create data table like it_table. assign table->* to field-symbol(<table>). try.
r_salv_table = data(salv_table) changing
t_table = <table> ).
rt_fcat = cl_salv_controller_metadata=>get_lvc_fieldcatalog(
r_columns = salv_table->get_columns( ) " ALV Filter
r_aggregations = salv_table->get_aggregations( ) " ALV Aggregations ). catch cx_root. endtry. endmethod.
I know that many times showing any progress information isn't something that developer likes to have in his program, especially when it's so fast that progress indicator only slows it down horribly, but often we're putting it into code, when program runtime is quite long ( more than 1 minute) and we want to show the users that program is running and we're currently at step m of n. Since I remember I was always using SAPGUI_PROGRESS_INDICATOR FM to display such messages on the screen. When used inside loops I often was manually dividing current tabix by selected variable (for example 1000) and if there was no rest from such division then I was running this FM, just to avoid calling this FM to often. The problem of this FM is that when used in background it hasn't show any info in job log. So if you wanted to have also entries in job log, then additional lines with checks if this is foreground or background mode were needed, and if we were in bg mode then messages instead of progress indicator had to be used.
I was playing a bit with CL_GUI_TIMER some time ago and I thought that this would be good to use it somewhere to have idea how it works. So I've created then a small game Battleships, which you for sure know from analog version.
Game is very simple, firstly you have to build your own map with ships. Just to remind you, there are 2 submarines, 2 destroyers, 1 cruiser, 1 battleship and 1 aircraft carrier. Map is created with CL_GUI_ALV_GRID. Once you click on status button to add one of the ships, map will show you in which place you can start ship. When you'll select position of the start it will show you possible fields for end.
After you build your map hit Join Game button and wait for second player to join you.
If you imported NUGG file from previous article you could be surprised that there is one additional FM available called Z_AB_POPUP_GRID_MULTI_SEL. This FM can be used to call a popup with ALV grid which allows multiple row selects.
1) In order to prepare such popup you'll need to firstly define some global variables in FG which you can find bellow:
constants: c_ccname_grid_popup type scrfname value 'CC_GRID_POPUP'. data: go_popup_custom_cont type ref to cl_gui_custom_container. data: go_popup_grid type ref to cl_gui_alv_grid. data: gs_popup_layout type lvc_s_layo. data: gs_popup_variant type disvariant. data: gt_popup_fcat type lvc_t_fcat. data: g_popup_question type char70. field-symbols: <gt_popup_outtab> type standard table.
2) Then you need to create GUI status with Cancel and Enter Buttons
When using editable ALV mass replace function is needed very often, but when it comes to creating it you have to choose which from the not so perfect possibilities you should use. You can create a screen or selection-screen with all possible fields which can be used in the function (not good when you have a lot of editable fields), you can create dynamic program and submit it (not good as then you switch to the screen of generated) or you can create a FM to call selection-screen in separate task (disadvantage is that user can click on original window and hide your popup). I've used all of these possibilities but when you'd like to reuse them then third one (FM to call dynamic selection-screen in separate task) seems the best.
First of all the question is why do we need separate task to call it? Well, when you call dynamic selection-screen (with parameters like (variable) ) for the first time the output is ok, but the second time you do it in the same runtime of transaction or program then the length, type and F4 help are just like for the field generated for the firs time. This is because the generated selection screen is kept in memory an called each time with same parameters, nevertheless the change of "variable". The way to omit it is to call this selection-screen in new task. This will force SAP to regenerate selection-screen each time.
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.
This topic was raised many times, I always found it's not possible to (or at least to hard to try) to update components allocation for routing operations. Fortunately I had to do it somehow and I manage to do it in two ways :
1) with BDC (yeah I know, creepy but possible)
2) using EWB FM's basing on the SAP note 488765 - "Do it yourself EWB programming".
Today I will present program which is using EWB, in future I will post an example of doing this by BDC.
This program reads data from Excel file with proper structure (you can find Excel template in attachment). After reading data it collects all routings which needs to be updated to be sure that each routing is updated only once. Then the most important part is done in following way:
1) We need to load each routing and connected BOM to memory with CP_CC_S_LOAD_COMPLEX_BY_TSK and CP_CC_S_LOAD_COMPLEX_BY_BOM,
2) Next step is to get the BOM into internal table using CP_CC_S_PROVIDE_ITM_BY_AS_PATH. BOM table contains also a explosion of sub-assemblies which are not phantoms which at the beginning seem to be useless, but after a while you'll notice that we need all levels of multilevel BOM in order to calculate Path (PLMZ-KANTE) and order level (PLMZ-STLST). If you have to do components allocation for single level BOM then reworking the table is not needed, but in my example I did it as I needed to allocate components from multi-level BOM. You'll find here a form ITEM_CHECK which do the manipulation of the table.
3) After it's done we need load operation data (CP_CC_S_PROVIDE_COM_BY_OPR) and current allocation of components (CP_CL_P_OPR_ALLOCATION_PROVIDE). We need to do it in order to delete current allocation.
4) Deletion is done with CM_CL_P_COM_DELETE and saved with CP_CC_S_SAVE. Deletion is committed as in other case there is no possibility to create new allocation.
5) Allocation is deleted, so we can now recreate it with new values. Firstly we need to reload again operation data to memory with CP_CC_S_OPR_PROVIDE_BY_MTK and then create allocation with CP_CC_S_CREATE_COM. Again we need to save allocation with CP_CC_S_SAVE.
Bellow you'll find the code of the program. You can download also NUGG file for it!.
Program works in two steps, firstly it displays reading log, if it is ok you have to press first button on the toolbar to create allocation.