How-to enrich XI monitor’s output
I’ll try to give an answer here to a question which users tend to ask:
“Wouldn’t it be possible to display directly in the XI message monitor an additional field containing … whatever.“.
Here whatever could mean an idoc number, an order/delivery number, the message size, a more understandable error description, a dynamic configuration attribute and so on.
I’ll show how to insert an additional field to the output of the SXI_MONITOR transaction, containing the name of the file that originated the message, or, if possible, which the message is going to create (this of course will work in file scenarios only); minor changes can let you add other dynamic configuration values or other goodies, like an idoc number, to your enriched monitor.
We are basically going to do 3 things:
- Create an ABAP Function Module that, given an XI message, returns an attribute (of our choice) from the dynamic configuration of the message;
- Copy and extend the standard structure used to display the output of SXI_MONITOR;
- Copy and edit the standard programs responsible for the output.
1. This Function Module is quite involved: we have to get the XI message and extract the dynamic configuration’s data from it. Then we have to take the file name. We’ve got better chances to find the filename in the last version of the message, so we’ll consider only that one1. The result will be a Function Module taking a message GUID, a namespace and an attribute name as input parameters, and returning the dynamic configuration value for that combination of namespace/attribute of the message identified by the message GUID.
Here is the code of the FM, name it whatever you like, remember that you can create a function module using transaction se37, but first you have to create a package: I suggest to follow Alessandro Guarneri‘s weblog on The specified item was not found. for this part, which I won’t repeat here.
Set 3 input parameters as specified in the header of the function:
MSGID of type MPG_GUID – this will be the message GUID
NAMESPACE of type STRING – the attribute namespace
ATTR of type STRING – the attribute name
The output will be in the VALUE field, and will contain the value of the attribute we chose.
Save and activate when finished.
2. Now we have to copy the standard structure SXMSMSGDSP. Run transaction se11, insert SXMSMSGDSP as “Database Table” then click copy. Choose a different name for the structure (e.g. ZMONI_SXMSMSGDSP) and click the tick.
Insert the package you created in the previous step and click the tick again. Now that we’ve copied the structure let’s insert a new filed. This field is going to contain the filename attribute of each message. I called it DYNFIELD1. Click on the “Insert row” button and fill in the field name and type.
I used a CHAR100 which is surely large enough to contain a filename.
You can also add more fields here to show additional stuff as I said at the beginning of this blog. When you’re done, save and activate (when I did it, I got a package check error. If the same happens to you just ignore it and select yes to activate anyway).
3. Here comes the hard part, we have to edit the standard program which lies under transaction SXI_MONITOR. To do this we’ll again rely on The specified item was not found.. Use transaction se80 to copy the standard program, we don’t need either to copy every included program but only RSXMB_SEL_MSG_TOP and RSXMB_SEL_MSG_APPL (which contains the “core” part). Copy those two programs to a name of your choice starting with ‘Z’. I used the names ZENR_RSXMB_SEL_MSG_TOP and ZENR_RSXMB_SEL_MSG_APPL.
First edit ZENR_RSXMB_SEL_MSG_TOP changing just the following 2 lines:
Here we are basically telling XI to use our structure instead of his. Now we have to edit the program ZENR_RSXMB_SEL_MSG_APPL.
First of all change every occurrence of the data type SXMSMSGDSP to ZMONI_SXMSMSGDSP (just do a case insensitive “replace all”). Then add, at the end of the program, after the last line of code, the following form:
This form will fetch the filename attribute and fill our custom output field with that value for every message. We have to call the form twice. Add the following:
right before this line (line 983 of the original program):
and right after this line (line 1469 of the original program):
Now we’re almost done, but we have to modify the fieldcatalog in order to display the field we added. Find the line
and right after that add
We are almost there, just go to the menu and select “Goto > Text Elements > Text Symbols”.
Here we can add the description and a tooltip for our custom field. Insert the value “FileName” under for the key “Z01”, and “File Name” for the key “Z02”. Then save and activate as usual.
Ok, that’s it. Test your application by clicking F8. Enter a nonempty selection criterion and you should get something like:
Try it out and consider adding some more functionalities to this, surprisingly enough there is very little ABAP coding involved, but it depends on which kind of data you want to display 😉
1 Actually if the file is created after the message mapping, you’ve got almost no chances to know its name beforehand. But, sometimes, your source system could impose the name of the file to the target system, and in this case (which was my case), you can have it and use it as you like (for example you can put it in the dynamic configuration ;-D ). In this situation you won’t be able to see the file name in the first version of the message, but in the last one you can.
hope it will be helpful 😉
are the enrichments (new columns) viewable in sxmb_moni or do we have to set up a "zsxmb_moni"?
Can anybody suggest me how to do it? I am dealing with classes used in the programm but can not found the IDoc Number.
Thanks in advance.
for outgoing idocs (SAP --> PI) I think you can get the Idoc number from the payload.
In the function I've created in the blog (Z_ITBC_GET_MSG_REF) take the first version of the message instead of the last using
CALL METHOD persist->read_msg_pub
im_msgguid = msgid
im_pid = pid
im_version = 001
ex_message = li_ifmsg.
than after you've got the payload (search for this instruction)
li_pay = li_msg->get_payload_with_main_document( ).
you can play with li_pay->GETBINARYCONTENT( ), to manipulate the message content and find the DOCNUM tag, for exampple:
lv_payxstr = li_pay->GETbinarycontent( ).
* Convert from xstring to string
DATA: conv TYPE REF TO CL_ABAP_CONV_IN_CE,
content type string,
IDOC_NUMBER type string.
conv = CL_ABAP_CONV_IN_CE=>CREATE( input = lv_payxstr ).
conv->READ( importing data = content ).
* Use regular expressions to extract the idoc number
IDOC_NUMBER = replace( val = content
regex = '.*
with = '$1' ).
Here IDOC_NUMBER contains the idoc number.
On the other hand you cannot get the idoc number for the PI --> SAP case as that number is not yet assigned (it is assigned once the idoc is created in SAP).
Hope this helps,