Search help for a custom field in Personas 1.0 / 2.0
When creating flavors with custom fields on the screen, it is often requested that a standard search help feature be available for a new field. For instance, an input field is needed which is in fact for a cost center number, and as such, the user would like to take advantage of the usual search help for cost centers. The same request can come for fields that are part of the standard transaction and don’t have a search help assigned but the company is using them for specific purposes so searching is a nice-to-have.
Standard Personas doesn’t offer this functionality, but this can be done (although my solution is arguably a little convoluted). The process requires some ABAP programming knowledge as it involves coding a couple of WebRFCs and also an enhancement, so the assumption is that you know how to handle these. For performing a WebRFC from Personas there are excellent guides and blog posts available on SCN. Apart from this, only Personas scripting is necessary, there is no need to modify anything.
Below I will explain how to do this in a flavor for the Easy Access Menu (transaction SMEN), although this method should be reusable for most other screens as well.
The basic idea is to somehow activate the necessary search help processing on the backend screen. One way to do this is calling a standard function module that‘s used when we test a search help from the Data Dictionary. This function module is F4_SHLP_SIMULATION. With this, we can call up whichever search help we want. Like for cost centers, it looks like this:
This serves our purpose well, because we only have to script skipping over the first popup screen to get to the Restrictions. From here the user can see the list of available cost centers and pick the desired one just like in a regular transaction.
To call this function module, we need to enhance the command field handling of the underlying screen (in our example, this is the SMEN 100 screen). We will enter a custom command (such as ZZ_PERS_SH) into the command field and then intercept the processing of this command to call the search help test function module.
The intercepted command processing has to know which search help should be passed on to function module F4_SHLP_SIMULATION. Since the backend has no way to access information in our Personas flavor, we need to store the search help name (and any additional information) in a backend table where the ECC process can read it from. This can be accomplished with performing a WebRFC from the flavor.
So let’s see how this looks in our use case. We define a flavor for the Easy Access Menu screen, with new input fields like one for a cost center (and another one for a material number so we will have multiple search help calls in our screen).
Pressing the script button next to our cost center field will do a WebRFC to tell the backend what search help we want to use plus initiates the search help processing by entering a specific command into the command field. The WebRFC code is the following:
FUNCTION z_webrfc_store_data_sh.
*"----------------------------------------------------------------------
*"*"Local Interface:
*" TABLES
*" QUERY_STRING STRUCTURE W3QUERY
*" HTML STRUCTURE W3HTML
*" MIME STRUCTURE W3MIME
*" CHANGING
*" REFERENCE(CONTENT_TYPE) LIKE W3PARAM-CONT_TYPE DEFAULT
*" 'application/json'
*" REFERENCE(CONTENT_LENGTH) LIKE W3PARAM-CONT_LEN
*" REFERENCE(RETURN_CODE) LIKE W3PARAM-RET_CODE
*"----------------------------------------------------------------------
DATA: l_shlp TYPE shlpname,
l_field TYPE char30,
l_shlpkey TYPE indx_srtfd.
DATA: htmldoc LIKE LINE OF html.
READ TABLE query_string WITH KEY name = '_shlp'.
CHECK sy-subrc = 0.
l_shlp = query_string-value.
CONCATENATE 'SHLP_' sy-uname INTO l_shlpkey.
READ TABLE query_string WITH KEY name = '_field'.
IF sy-subrc = 0.
l_field = query_string-value.
ENDIF.
EXPORT shlpname FROM l_shlp
fieldname FROM l_field
TO DATABASE indx(zz) ID l_shlpkey.
IF sy-subrc = 0.
CONCATENATE '{"results":[{"key": "shlpname", "value": "' l_shlp '"}]}' INTO htmldoc-line.
INSERT htmldoc INTO TABLE html.
ENDIF.
ENDFUNCTION.
This code takes two parameters: one of them is the actual search help name (_shlp) and the other one is an indicator for the target field (_field). Since we can have multiple fields with associated search helps (but use the same way to call up the search help dialog), our process needs to know where the user-selected value should be pasted to. This field indicator will be used for that purpose. In our example, CC indicates the cost center target. We’d use a different one (like MAT) for the material master search.
The script for the search help button is like this:
The first step is just to clear out our work field storing the target field indicator. In case we only have a single custom field with our search help process, this can be omitted.
The next thing is to perform our WebRFC above. Step 2 is needed because Personas caches a lot of things, including WebRFCs and if we happen to request the same search help multiple times, it will not actually do the WebRFC but supply the result of the previous call. This is a problem because storing of the desired search help name doesn’t happen then and we may end up getting the search help dialog for another field if in the meantime a second such search help process was also used. In order to make each WebRFC unique to Personas (and thereby force the call), we just pass a random number – generated by a javascript command – to the function module which will be ignored, but then the call will be always different from any previous one.
The complete WebRFC (Step 3) looks like this:
http://server:port/sap/bc/webrfc?_FUNCTION=Z_WEBRFC_STORE_DATA_SH&_shlp=KOSTN&_field=CC&_rand={rand}
Step 4 will enter our custom command in the OK_CODE field. This will be processed by the backend and the result is to call the requested search help dialog, via some additional coding (detailed at the end of this guide, under “Handling the search help call command“). Step 5 is just to press ENTER on the first screen of the search help so that we immediately get to the Restrict Value Range window. Then it is regular search help processing where the user will pick and choose the desired cost center by double-clicking on this screen:
From here, we will get back to the popup window showing the selected cost center value and several other things we don’t really need.
In a regular SAP transaction, the selected value is written immediately into the target field, but in our case, this intermediate screen actually helps because it allows us to have a script that will place the selected value into the intended target field. We have our cost center (2420) so we’ll customize this screen in our flavor to show only what we are interested in, plus add a script button that will paste 2420 into our custom cost center field. The result can be something like this:
Edit 11-Aug-2014: If you have the latest Pesonas client patch applied, you could attach the ‘Continue’ script button to the OnCreateHandler event of the popup window’s UserArea, thereby this screen wouldn’t appear at all, and the user doesn’t have to click on the button to get the selected value. At the time this blog post was written, this was not possible due to a bug in the Silverlight client which has been corrected since. This means that then there is no need to customize this popup window either.
The ‘Continue’ script button’s definition:
The first step grabs the cost center from the screen, the second step presses the ‘Cancel’ button so that we get out of the search help simulation and back to our Easy Access Menu.
Then, we have to figure out what our target field is. Again, if we only have a single custom field in our flavor with a search help, then this is easy, the value from step 1 can be directly pasted into the target. However if we have more than one possible targets (like in our example), then we need to know where the search help process was initiated from. This is where a second WebRFC is necessary, because during our previous WebRFC, we stored this target
identifier in the backend, along with the search help name.
In step 4, we do the same ‘randomization’ to ensure that our WebRFC is always called (instead of getting a cached result), and step 5 calls a second function module that retrieves the target field ID:
http://server:port/sap/bc/webrfc?_FUNCTION=Z_WEBRFC_READ_DATA_SH&_rand={rand}
The function module code:
FUNCTION z_webrfc_read_data_sh.
*"----------------------------------------------------------------------
*"*"Local Interface:
*" TABLES
*" QUERY_STRING STRUCTURE W3QUERY
*" HTML STRUCTURE W3HTML
*" MIME STRUCTURE W3MIME
*" CHANGING
*" REFERENCE(CONTENT_TYPE) LIKE W3PARAM-CONT_TYPE DEFAULT
*" 'application/json'
*" REFERENCE(CONTENT_LENGTH) LIKE W3PARAM-CONT_LEN
*" REFERENCE(RETURN_CODE) LIKE W3PARAM-RET_CODE
*"----------------------------------------------------------------------
DATA: l_shlp TYPE shlpname,
l_field TYPE char30,
l_shlpkey TYPE indx_srtfd.
DATA: htmldoc LIKE LINE OF html.
CONCATENATE 'SHLP_' sy-uname INTO l_shlpkey.
IMPORT shlpname TO l_shlp
fieldname TO l_field
FROM DATABASE indx(zz) ID l_shlpkey.
CONCATENATE '{"results":[{"key": "shlpname", "value": "' l_shlp '"},{"key": "fieldname", "value": "' l_field '"}]}' INTO htmldoc-line.
INSERT htmldoc INTO TABLE html.
ENDFUNCTION.
Then in step 6 we write this field ID into our work field on the screen. This is used in IF statements to decide where the selected cost center should go:
And the result is:
Handling the search help call command
The only thing remaining is the process that takes place in the backend, which actually calls up the search help dialog. Remember that in the script which initiated the search help process, we entered a custom string into the command field? Obviously, this has to be handled somehow and this is where an enhancement comes in.
Essentially we need to intercept this command before the standard OK code processing kicks in because we would likely end up with an error message that such a command doesn’t exist, or in our case (SMEN) the system would try to execute transaction ZZ_PERS_SH. Since every screen can have a different process handling OK codes, we have to analyze the actual screen we are on and find out how to intervene in the command field processing before anything else happens. In our test case with the Easy Access Menu, this is very simple since there is an easy-to-locate subroutine where this is done. In some other cases this may be a bit more complicated to accomplish, depending on the technique used.
For SMEN, the command field processing is in subroutine UCOMM_USER_COMMAND of module pool SAPLSMTR_NAVIGATION. Here, we are going to implement our code using the implicit enhancement point at the beginning of the subroutine.
The actual code to be implemented is:
data: zz_SHLPNAME type SHLPNAME,
zz_shlpkey TYPE indx_srtfd.
if okcode = 'ZZ_PERS_SH'. "Personas search help was selected
clear okcode. "Delete custom command value
CONCATENATE 'SHLP_' sy-uname INTO zz_shlpkey. "build key for INDX access
IMPORT shlpname TO zz_shlpname "find out which search help to call
FROM DATABASE indx(zz) ID zz_shlpkey.
IF sy-subrc = 0 AND zz_shlpname IS NOT INITIAL.
CALL FUNCTION 'F4_SHLP_SIMULATION' "call selected search help in test mode
EXPORTING
shlpname = zz_SHLPNAME.
ENDIF.
EXIT. "no further user command processing needed
endif.
And that’s pretty much it.
Again, this last piece may have to be tailored according to how the actual screen logic is coded, but the principle remains the same.
Hello Tamas! We met with you at Freescale not too long ago, and search functionality was one of the things we had talked about. It is great to see that you have figured out a solution!
I am following this example and trying out your solution, but I would like to implement it in the F-65 transaction instead of SMEN.
Like you say in your post, we need to analyze the actual F-65 screen and find out how to intervene in the command field processing. Do you have any advice on how to do this? We are having trouble pinpointing exactly where to add the code enhancement.
Any advice or guidance would be much appreciated!
Thank you,
Cheryl Sutton
Hi Cheryl,
it really depends on which screen we are talking about. Where do you need the search help?
For instance, in case of the very first screen (100), I'd do it in subroutine fcode_bearbeitung of the main program SAPLF040. Other screens may need a different location.
Tamas.
Hey Tamas,
So, we got this solution to work great within the F-65 transaction, and now we are trying to implement within SMEN as you have done in this example. However, It looks like there is some sort of lock on the code where the enhancement should be added. Have you seen this before? Maybe you have super user access that allowed you to add code here? Any ideas how we should proceed?
Thanks for any suggestions!
~ Cheryl
Hi Cheryl,
are you saying that when you click on 'Create Implementation' for the implicit enhancement point Form UCOMM_USER_COMMAND, Start in this subroutine, you get this message?
Strange... i don't think my access would be that special but I haven't seen this message yet.
Tamas.
Yes, that is precisely what happens. Should I open a ticket with SAP?
Hm... interesting.
I investigated this and it appears that depending on the system release level, this message may indeed appear for objects that are designated as central basis components. I wasn't aware of such a restriction until now and I tested this method in two different systems, without any issue. One of the systems is on a fairly new release, the other one is a bit older though.
Well, I guess you could always defeat the error message via debugging or as an alternative, do a core modification... I'd go for the former since I just cannot see how this enhancement would hurt anything.
What release, ehancement pack, basis SP level is your system on?
730 Final Release
7300.1.2.1078
1377184
Patch Level 2
Those are for SAPGUI... what I meant is the SAP Basis component release / SP level.
Oh sorry - 701 SP 10
SAPKB70110
Well, both systems where I have this scenario set up are on a higher release... one of them is 731 SP 07, the other one 740 SP 03. Upon checking customer messages, it appears that similar errors popped up in older versions similar to yours, so it's possble this restriction was eliminated in a later release.
Hello,
I try to implement a search help. What is your structure of your internal table html ?
Dominique
Hi Dominique,
It references the DDIC structure W3HTML.
For details regarding Personas & WebRFC, refer to the excellent blog from Steve Rumsby: Calling RFCs from a Personas script
Hi Tamas,
Your blog is excellent & appreciated by many of them. But to me its difficult to understand.
I have created the function module & kept text boxes in the flavor for CC & material. I am not understanding how to do the script. Like you have given the screen shot of script. But each step i need to assign which text box. As well you have given a work field to store value. Is this a label or text box. Can you please share a video on this. It will be good learning & great help for me as i am doing a POC on Cj01. Also i have multiple search help fields in my custom screen which i need to update from my main screen.please help.
Kind Regards,
Kalyan
Hi Tamas!
Great explanation of an easy to use but complex to implement solution!
As an ABAP developer going in-depth into Personas your ideas make lots of sense and I'll implement it here on SMEN. I was thinking about putting some fields on SMEN as a startup screen but thought that missing search helps would be difficult for the user to accept. Now I'll do it!
Thank you for sharing, good and great work!
Best regards,
Douglas
Great example, and I realize I am late to the party, but once you place a script under the onCreateHandler of the Search Help result, how can you go back and edit the script? That window is not accessible anymore from edit, and in processing the screen pops up for a second not allowing edit.
This does fill a large hole in Personas 2.0, can't wait to use it!
Thanks! Christian
Hi Christian,
you can temporarily disable all OnCreateHandler scripts by adding a parameter to the Personas URL, like this:
…/index.html#RenderingDisableOnLoad
Huge! Just found your other post with additional URL parameters, great things to know! Your prompt response was greatly appreciated!
Christian
Hi Tamas,
I was new to Personas, your blog helped me a lot for creating F4 help.
Do you have any Idea about how to create a dropdown box with filling values dynamically.
Regards,
Arun Krishna
Unfortunately that's currently not possible. I don't know if there is a plan to include this feature in the product.
I could imagine a rather complicated way to have some function module call in the above logic instead of F4_SHLP_SIMULATION which would take care of populating a temporary table with the dynamic values and then call a piece of code to display this content... or something along the line of this. The key would be finding a way on the backend to handle the injected command and provide the necessary action.
You know what, now that I'm thinking of this, it sounds like a neat little side project 🙂
Greetings Tamas,
Regarding the method shown above it's applicable only when a flavor is created on the main screen (smen). In a more practical approach if I am trying to customize a process and add f4 help say for t-code mm01 then passing zz_pers_sh as the t-code will not help as its not the initial SAP screen and nor will /o as the control will be passed to a new tab.
Can you suggest any workaround ?
As mentioned in the blog post, while the example is based on the SMEN transaction, the same method can also be used in other screens. However you need to analyze the transaction's code to figure out how / where to insert the necessary enhancement to handle the custom command which activates the search help dialog.
In case of the MM01 selection screen, I'd probably use the enhancement spot ES_SAPLMGMM and enhancement point LMGMMI31_01 which gets called in module CLEAR_BILDFLAG, and after successful search help processing, clear out the ok-code field then re-process the current screen SY-DYNNR.
In some cases, you may need to get creative to figure out a way to inject your extra processing. Each screen is unique. There is no way to provide a uniform guide on how to implement this.
Hi Tamas,
I'm trying to achieve entering data and saving from the initial screen. Hence it saves the user's time rather than entering data in the next set of screens where there are multiple tabs.
In order to achieve that I have given custom fields on the initial screen. I am able to attach the standard search help by calling a z transaction I created but by doing this the values initially entered on the creating material screen get cleared out (as for returning back to the screen I have a recording for calling /nmm01).
The issues I'm facing now are retaining values and validation. For retaining values I am trying to copy paste the entered values in variables and copy pasting them.
Regards
This latest question of yours goes beyond the topic of this blog post since it is not related to search helps.
Data caching / retaining for custom fields is a different topic. You can find suggestions for this here on SCN. One method involves Personas scripting, the other one uses JavaScript.
Hi Tamas,
The Step 3 url you have posted does not work. Is it possible to paste the code?
Thanks,
Salil
Of course it won't work because it refers to the system I used to create the prototype. You have to replace it with the server name and port of your system.
Or better yet, define it in a dynamic way like this.
Thanks Tamas. I will try it out.
Hi Tamas,
Is there a way to suppress the F4 search for standard text boxes? I see that even in Personas 2.0 SP03, the IsLookupSupported field is grayed out.
Regards,
Abhijeet
Hi Tamas,
Your blog is excellent and I already succeed creating search help in my flavor by following step by step process from this blog.
But now I am facing a problem after I add OnCreateHandler event. I Want to redesign Test Search Help screen, but I don't know how to stop this event.
I already try by adding in the URL RenderingDisableOnLoad or DisableonCreatehandler=true. But still the screen still skip by the process.
Do you have any suggestion on this matter.
Thank in Advance
Regards,
Indra
Hi Indra,
RenderingDisableOnLoad should work. Make sure you're adding it to the URL as this KBA describes.
Tamas.
Thank you Tamas, problem is solved.
In my case I should add the additional RenderingDisableOnLoad on URL after my flavor is show and not on login screen URL.
Regards,
Indra