HCM Processes & Forms: HELP! … drop downs, search helps, F4 and more explained
This is another one of those “I have been putting this off for a long time” kind of blogs. It is a pretty basic concept of HCM P&F, but it does tend to trip up those that are new to it. Even those experienced with HCM P&F might at times “scratch their head” wondering why it is not working as expected at times. I thought someone else might have discussed this by now, but to my knowledge, no one has yet blogged about the “how’s” and “why’s” of “help” values in HCM P&F…..so I guess, much like cleaning up my office, it is just time for me to get it out of the way. haha
So first off, what the heck are we even talking about?!?!?! This is about the “help” values we present to the user on our forms to make their life (and data entry) easier. This is most often visualized on our forms as a drop-down list control as follows:
For the longest time, this was our only option. However, this has been extended a bit to allows us to use an input box control that will “pop up” a window in which we can run more complex “help” searches (such as showing more than just one values or even using a standard or custom ABAP Webdynpro application…which I have covered in previous blogs as well).
How “help” is configured?
I guess the first place to start is “where” we tell our form “for THIS field, we want help values to come from WHERE“. This can be done in one of two ways.
(1) We can set this in our form scenario’s “form fields” configuration as “input help”.
We set whether the “help” values will come from manually entered entries (ie. you config a list of value/text pairs), a standard service (like SAP_PA), from a custom generic service (one we write which I will discuss later) or from a Web Dynpro application (standard or custom).
(2) We can set it in our FPM form layout configuration in FLUID as a “search help”. This can be a standard or custom (“Z”) search help.
Where “help” is triggered?
I have covered help values from Webdynpro applications in previous blogs, so I will not rehash that here. If you help comes from search helps, that is outside what we will cover here (search helps have been around for ages, so plenty of information already out there…no need for me to add to the “noise”….for once. haha). However if your help values come from a “generic service” (standard or custom), the way in which it is done (ie. “how the magic happens”) is pretty straightforward. For our custom services, you can actually populate your “help” values from pretty much any of the “runtime” methods of your generic service (Initialize, do_operations and get_help_values). However, if you read the documentation from the IMG for the IF_HRASR00GEN_SERVICE (basic generic service), you will see that it notes:
“We recommend that you always us the GET_HELP_VALUES method to provide input help. Note that errors occur if you provide input help with the methods DO_OPERTATIONS or INITIALIZE as well as with the GET_HELP_VALUES method.”
So what does that mean? (1) choose ONE place to populate your help values from….problems do occur if you “mix and match” them (2) they say “always” use the GET_HELP_VALUES method to do this, but I disagree and will tell you why by way of “pros vs. cons” of each.
As you see, we have full control over the SERVICE_DATASETS (ie. the values of our form fields). This means that we can “adjust” our form field value related to our help values. This is useful if we want to set some default dynamically for the form field based on the help values, and the much more common scenario of “clearing” the form field if it’s value is not in our help values. For example, suppose we have the following option for something like:
form field value help values
…and then somewhere on the form, something changes so that the help values now change….
form field value help values
So as you can see, “chicken” is no longer a valid value (and will throw an error if we tried to use it). However, because we are doing this in “do operations”, we can now check the form field value against our help value list and either (1) clear the form field value since it does not exist in the help list or (2) add it to our help list as a valid value. This might sound like a very small difference but it is THE determining factor for me always when deciding whether to use either method. In some cases, you might even handle it in a “hybrid” way such as set/clear your form field in your “do operations” but then let the “get help values” actually build the list. However, this often will require a duplication of code, so I avoid it unless absolutely necessary.
Because we are now trying to control our help values via “do operations”, the downside of this approach is that we must have an “operation” defined for our help value population (which means we must do all the extra work of defining an operation, defining field for the operation, blah blah blah).
Secondly, it only gets triggered/called when the “check” event issued by the framework. This is important to note as the “order” of your backend services will very much dictate how this occurs.
Not to be a spoiler, but you should be able to guess that these are almost directly opposite of “do operations” above.
Since our help values are always “built” in this method, we do not have to define and build any specific “operations” for them. It is typical that in this method, we simply loop through all fields set/configured for us to build the help list, and we handle each one. If you are sticking to good OO programming habits, this still means that we should be doing “pass through”/handoff of the key method parameter values and calling our own methods for each help list (ie. modularized code). I mentioned this only because I have seen others attempt to place ALL of their code directly in this method to build their help values, and it becomes a mess.
Secondly, this method always gets called by the framework both after the “initialize” event and the “check” event. This means that we know exactly when/where it will happen.
Notice one glaring thing with this method’s signature? SERVICE_FIELD_VALUES (our “service dataset”) is an “import only” parameter. This means that we can read our form field values but we cannot change them. Why is this important? Please refer to the “pros” for “do operations” above. This means that we can not dynamically set/clear our form field values based on the values of our help list. This may not be an issue if you have a rather stagnant help list (ie. it does not dynamically change based on other form field value selections)
How it works behind the scenes?
Now, let us talk about how our form fields gets the help values assigned to it (ie. the “binding”). Because we configured our field to have input help, it will be added to the HELP_DATASETS structure. We should be able to see all of our fields configured to have “help” in this dataset, but here, we are looking at one particular entry. As it first “goes into” our “get help values” method, we can see it initialized as:
After being “set”, we can see the main fields have been populated. These are FIELD_CATALOG, KEYCOLUMNNAME, VALUECOLUMNNAME and DATA.
The Field Catalog, as the name suggests, is our way of being able to define dynamically what the “fields” of our help list are. The FIELDNAME column defines the data “type” of our “data” values. The first entry/row is our “value” field (ie. when the user makes a selection from the help list, this is the actual value that is stored), so here, we are defining what the data type/element of that “value” will be. Our second entry/row is our “text” field (ie. this is the one that is displayed in the help list to the user). Therefore since it is just our “display” field, I will typically set it to some long string data element. The column HEADERTITLE can really be anything you like, but I just name them the same to keep it consistent.
One very important thing to note here is that the whatever is used as our “key column” FIELDNAME value must be the same data element as the one assigned to the form field that our help is attached too.For example, if our form field “Employee Number” has data type “PERNR”, but here in our help list field catalog, we assign row 1 FIELDNAME as “CHAR8”, we will get an error/no help list created. We should have the row 1 FIELDNAME assigned as “PERNR” to match our form field’s data type. This has cause MANY people more than a few headaches before! hahaha
As our help lists are simply “key/value” pairs, you can guess what KEYCOLUMNNAME and VALUECOLUMNNAME are used for. These names tell us WHERE/WHAT are “key/value” pairs are based on our FIELD_CATALOG definition. As you might guess, these must match exactly the values used in our “field catalog”. So for example, we might have a field catalog defined with many fields…
row fieldname headertitle
1 pernr employee number
2 ename employee name
3 plans employee position
4 descr employee name+position
But from this, we might only define our “key/value” pair as …..
KEYCOLUMNNAME = pernr (matches row 1 of field catalog)
VALUECOLUMNNAME = descr (matches row 4 of field catalog)
So then our “help list” would display “descr” in the dropdown and assign key “pernr” when the user makes a selection. The cool thing here though is that if we use this in an “input control”, the pop-up window would actually show the whole “field catalog” (ie. it shows much more information that what a “drop down” list constrains us to).
Finally, we have our Data structure. Now hold on to your seat because this just might blow your mind! (haha) THIS is our actual help values/data!!!! Crazy eh?!?!?! haha As you might notice, it’s column layout is exactly what we defined in our “field catalog” (and we actually have a 3rd column for “SACHN” that we did not define in the field catalog because we want to ignore it as we know this is for a drop down and only needs 2 columns).
So we collect our data….then we build our field catalog to tell the framework how our data is laid out (ie. we tell it what data type each column of our Data is)…and finally, we tell it from the field catalog, which columns are our “key” and “value” values. See how it all ties together now? 🙂
If you spend enough time with HCM P&F, you will notice how every “get help” chunk of code all starts to look the same. Whether standard or checking out someone’s previous “custom” work, you will notice they follow a very similar pattern. Read/get data…..define field catalog….set data to “help” field….set key/value column names….wash….rinse….repeat. Here as a “standard” service with a help value being defined….
First off, we normally will the code “collect” our data (or “Data” from above). We can see this below around line 18 and onward.
Next, you will often see a “loop” through the HELP_DATASETS “looking” for our particular “help” form field. I do not like this way as we already know what field we want, so I prefer a “read” on that dataset looking for specific field…but anyways….so we find our “help dataset” field, and then you will normally define/attach the “field catalog” to it. You can see this in lines 35 through 41. Lines 43 through 51 show an example (as mentioned above) where the actual form field value is being set/cleared directly…which tells us this is called from “do operations” because “get help values” does not allows us to change the “service field values” values. From line 54 onward, you can see how it is assigning the “data” to the “help dataset” field.
Lastly, you can see how it defines/sets what the “key” and “value” columns will be based on the “field catalog”. This could be done right after defining the field catalog, but you will often see it done last as well.
How to make it easier?
Having done my share of HCM P&F projects and written my fair share of generic services, I thought there must be an easier way to do this. Now, I am not saying this is the “best” way….it is just my way of handling populating help values (most often for simple drop down lists).
As always, it starts in our “standard” HCM P&F method. In this case, this is the “get help values” method. I start by simply looping through all of my “help” fields and setting them to a field symbol to handle directly using a “case” statement.
For each of my “help fields”, a case will “catch” them to handle (nothing new or groundbreaking here)…
To keep my code easy to manage and follow good OO habits, I keep the actually “handling” of the “help” field assignment in it’s own method. I simply “pass through” the values from the “standard” method that I need. Again, nothing out of the ordinary here. However, within each of my “help” methods is where I kind of “do my own thing”…
The only “work” my specific help methods do is the data gathering/reading (and even then, if used in several process, I create another class/method for that). Lines 4 and 5 are important as they reference what my actual help data structure will look like. This might be a standard type or possibly a public type I have defined here or elsewhere….but we will be using it again later when setting our “data” to our help list field.
Remember when I said line 4 and 5 would come up again later? Well, line 27 is where this happens. We have to set what our “data” structure of our help dataset field is going to be. From here onward, actually creating/building the whole help list is handled by a “common” class that I created. In this way, it handles my help list creation across all of my process (which is nice in keeping them consistent).
In my “common” help class, I have a public “Create” method. It actually calls two other public methods. Having these other methods public allows me some flexibility if I need to set up my help list differently (for example, for use with an “input box” versus a “drop down” list control).
You can see how basic this public “initialize helplist” method is, but it does save us from a lot of redundant code in our services. Seems simple enough, but its the little things. haha You can see that I also set my field catalog columns here too, but you should be able to figure out the internals of that one too.
After “initialize” of the helplist (which just sets our “key column name”, “value column name” and field catalog), we are just assigning our “data” to our help field via some good old “dereferencing”. This code always happens and always in this order, so why not make it into a simple, reusable method call!?!?!? I did. 😛
Again, I am not gone to pat myself on the back and say that this is the “best” way to do it, but I will say it has saved me a lot of time from having to duplicate code. Saving time directly translates into money I have saved my clients, and for that, I do feel pretty proud of myself.
That is really about it. I know the blog might have seemed lengthy for such a basic topic, but I wanted to make sure I covered it well (as I could). As always, I hope it helps others and saves you some time/headaches down the road. Feel free to leave your own take on this below in the comments. For more info on HCM Processes and Forms, you can read through my other blogs ( HCM Processes & Forms: My Blogs ). I also recommend HIGHLY that you buy and read the HCM Processes & Forms book by Brandon Toombs and Justin Morgalis (rumor has it, a new edition is just around the corner covering all the “new” stuff!) With that, I am outta here! Till next time…
Nice.. very 'help'ful!
Hi Chris...you rightly said, even though I have worked for many years on this, I am still scratching my head.
I am using a custom wda help in FPM HCMPF form, the value gets passed to the field, but as soon as any even happens the value disappears. Weirdly the value never gets captured as I can see in the feeder class while debugging, would you know why? because of this the WDA help is totally useless.
If you are using "events", make sure that in your "user event" configuration that the field is selected to be passed. If not, it will be "reset"/blank on the round trip. Another "fun" side effect of "user events". haha That is likely why you see no value for it in debugging (because it is not being passed).
Personally, I have become accustomed to passing ALL form fields in my events (I just create one field group with all fields assigned/checked to it and then use that field group for all of my "user events) and then I handle the events myself in my services (*using the FPM "event listener" method I described in other blogs) and use "rules" creatively to keep my updates and standard services (ie. SAP_PA) from being called until I really want them too. It requires a good bit of technical knowledge and work, but works MUCH better in the end. I don't have to hunt around trying to figure out what event uses what fields or why some are passed for one event and not another. But then my "loathing" of HCM P&F "user events" is pretty well documented. hahaha
As always thanks for your response. I was able to overcome the problem, there was a SAP note which informed to add an additional piece of code in my custom WDA and it got solved.
In the search help where you can assign the standard one in the FLUID, for example the KOST for cost center, how do you transfer the cost center text back to the form. I see that only the cost center number is getting transferred and not the text eventhough I specify at the field level in design time which is the text. Any clue is appreciate or else I need to develop custom WDA help I guess.
Coming to the F4 help functionality.
I have one question, can you please help..?
I have two fields, lets say A and B.
A - Had input help option to select values for it.
B - Normal form field - No input help function.
What I need:
If I select any value in the form field "A" from F4 option, Can I default the same value in form field "B" as soon as I have made the selection from form field "A".
If yes, Can you please guide me so that I will implement it.
Depends. haha If you do it in the "get help" method, then no....you can NOT change the contents of the service dataset (form fields). However, if you handle you "help"/drop down values in your "do operations" method, then yes...you can set values in the dataset.
Thanks Chris. I am using FPM framework and I am handling F4 option from Get help method.
I will do the below process:
I will handle the F4 option for form field "A" from "Do operations" method and try to set a form field "B" with the same value that I have chosen for form field "A".
Doing it in "get help" will NOT allow you to set any service dataset fields....only the help value fields....so only if field B is a "help" field, would you be able to set/default it. Otherwise, as I said, you would need to handle this in "do operations"......also, "do operations" is called BEFORE "get help", so you can not for example, set a value in "get help", then read that value in "do operations" and set your field B there. Make sense?
Yeah it won't work. Thanks for your valuable suggestions, I will implement your solution.
I do have another challenging task to create two records for Infotype IT0001. I will post it in SCN tomorrow, if you have time you can have a look. 🙂
Few details below regarding the challenging task:
I want to achieve this scenario like backend SAP system works. In backend, if we create 1st record then the 2nd record will be created automatically with default position (99999999). But when I try with HCM PF its not happening, it is only creating ONE record with the dates 01/24/2016 to 12/31/9999.
What I wanted to be see in SAP after HCM PF test:
1st record: 01/24/2016 to 03/31/2016 (With valid position (PLANS field) - 40026178 )
2nd record: 04/01/2016 to 12/31/9999 (With default position (PLANS field) - 99999999)
Bad experiences with the framework make me look for easier ways to do it 😀
Ah got you.....nothing comes easy with the framework...you just have to learn how to work with and around it at times. haha
I am facing one issue with F4 help values. I have mapped the standard search helps for fields Personnel Area and Personnel Subarea in FPM field attributes level.
For Personal Area search help HRPAD_PERSA
For Personal subarea search help HRPAD_BTRTL
Now when I am selecting personal area from F4 list it's fine. Value is getting filled in PA field.
But when I select Personal subarea from F4 list values, PSA field getting filled with Personnel Area instead of selected personnel subarea.
Hey Chris! This is really helpful and thanks so much for the effort. I have a query around the HELP here. I have a dropdown list HELP on the form. I would need to default a value to it from the dropdown list that I build for it. Would you happen to know how this can be done. I have built the help data for the dropdown field in the GET_HELP method and on an event trigger, tried to set a default key value to it from the DO_OPERATIONS method but the field is empty. Thanks in advance!
a "default" value and "input help" (ie. dropdown) are two different things for your same ONE "form field". By configuring a "default" value, you actually tell it which "service" will provide the value and then this is done in the "initialize" method (which is why you didn't see it in DO_OPERATIONS). Now, aside from that, if for example you wanted to change the "default" after the fact....say some even happened on your form.....you could set your form field value in do_operations to say "MY_NEW_VALUE".....and then the "get help" method will be called again after do_operations and you will again set your "possible options" for your help values....but just make sure you add "MY_NEW_VALUE" in there two so that the value you assigned to the form field matches what is actually possible. Make sense?
Thanks for the kind words and for keeping this "old" blog alive! haha
I am new to SAP P&F, and I have a scenario where I need your expert advice.
I have created a webdynpro application and integrated it into SAP P&F by enhancing QISR_UI and HR_ISR_COMMON_COMPONENT.
How can I skip all validations written in the method: WDDOBEFOREACTION of my webdynpro View, when SAVE DRAFT & PREVIOUS button is clicked?
Application used is : ASR_PROCESS_EXECUTE_FPM
Config ID: ASR_EXECUTE_4_STEP_PA_CE
Wrong place to ask this. Please ask it as a question in the HCM P&F forum/space/place/community/tag or whatever they are calling it this week.
Coming to the F4 help functionality.
I have one question, can you please help..?
how to fill the <Text_view> based on the search help .
For that kind of thing, I usually put an "event" on the input/selection box ....when triggered, I "catch" the event in a custom generic service where I then set the "text view" based on the selection.
First of all thank you very much for your post This is really helpful.
I am new to HR ABAP. i am struggling with one requirement.
There is one drop down list, i have to grayed out value 'White' from the list based on the condition in in HCM P&F.
i found the method but how to do it,. Requesting you to please provide the solution for the same.
please find below sample screenshot.
Thanks in Advance.
By "grayed out", I think you mean make it non-selectable. The drop-down list used in FPM forms is not that advanced. You would have to remove it all together from the "help list" based on a condition. I would do this in the GET_HELP_VALUES method and not in DO_OPERATIONS.
Thanks for your quick reply. i will try and let you know.