Calling RFCs from a Personas script
You can achieve a lot with Personas scripting, but ultimately it is just driving existing SAPgui transactions. And that limits how much you can do with Personas. Or so I thought, until I discovered that you can call WebRFC functions from a Personas script. Here is the example that motivated me to investigate WebRFCs.
Sometimes the task you want to achieve is very simple, like looking up a user’s real name or the description of a cost centre, using the “transaction free lookup” technique described in this document: Personas idioms. This technique is much quicker than running the transactions manually, but it is still running the transactions behind the scenes. Because the user interface is now much simpler, the overall response time can feel much longer. One way to make things more responsive is to call a Web RFC to do the lookup instead of calling a transaction. A Web RFC is an ABAP function called via HTTP and returning its results in the same way. WebRFCs are described in general in this blog by Sebastian Steinhauer – WebRFC – simply calling an RFC from javascript. From Personas, calling a WebRFC is an action you can add to a script. You can pass values to it via the URL and values returned are put into Personas variables, from where they can be pasted into screen fields or otherwise manipulated as normal. Here is a simple example of looking up a user’s name via both techniques, first the traditional method of calling SU01 (described in this blog – Personas scripting overview) and second by calling a WebRFC.
Notice how the second, WebRFC based lookup, feels so much faster.
I won’t go into the detail of writing a WebRFC function and how it interacts with the HTML protocol – Sebastian’s blog does that perfectly. I started with his example from that blog and wrote this function that simply looks up a user in USR03 and returns the corresponding name. This is a demo and not intended to be an example of good code 😉
FUNCTION ZPERSO_TEST. *"---------------------------------------------------------------------- *" *"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: name TYPE STRING. Â SORT QUERY_STRING DESCENDING. Â READ TABLE QUERY_STRING WITH KEY NAME = '_Name'. Â name = QUERY_STRING-VALUE. Â translate name to upper case. Â data: first like usr03-name1, last like usr03-name2. Â data: fullname(60) type c. Â select single name1 name2 from usr03 into (first, last) where bname = name. Â concatenate first last into fullname separated by space. Â DATA: htmldoc LIKE LINE OF HTML. Â CONCATENATE '{"results": [ {"key": "fullname", "value": "' fullname '"}]}' INTO htmldoc-line. Â INSERT htmldoc INTO TABLE HTML. ENDFUNCTION.
I then call this function from a simple Personas script like this:
Step 2 in that script doesn’t fit in the screenshot. The complete URL is:
https://wfs-ci.warwick.ac.uk/sap/bc/webrfc?_FUNCTION=ZPERSO_TEST&_Name={name}
Obviously you can use this technique to lookup anything, including data you might not be able to get easily from an SAP transaction. More intriguingly, a WebRFC can perform updates as well as lookups. I’ve always viewed Personas as just a way to “reskin” SAPgui, and perhaps use scripting for a bit of automation. However, it is also a way to build user interfaces to ABAP functions and so can be used to add completely new functionality. Would you build functionality that can only be used through a Personas interface? I’m not sure, but it is certainly an interesting idea and a technique I hadn’t anticipated when I first started looking at Personas.
If you have suggestions for interesting things to use this technique for, do add them in the comments below!
Â
Update: You’ll notice that the “Call WebRFC” action in the script above has the server name hard-wired. That’s obviously not ideal if you want to do your flavour development in a dev system and transport them. You can use a little bit of JavaScript to solve this problem, extracting the server & protocol details from the URL for the current page and using that to build the URL for the WebRFC call. Tamas Hoznek has written the details here: Keeping the WebRFC URL dynamic in Personas.
Thanks for sharing.
In the above script step.2, when I pass something like _Name=name as URL parameter, literal string 'name' is passed. I'm expecting to pass the value stored in variable name from step.1.
Did you experience anything like this? Thanks.
Sorry, that isn't clear from the screenshot in the blog - I must fix that. Enclose the variable name in curly brackets - _Name={name}.
Thanks Steve for sharing.
I am using it to fetch some system variables and passing it further in Reports. All under one script button. Works well.
Regards,
Manu
Good to hear! I am certainly finding contexts where the current Personas scripting is just not capable of doing what I need, and so using WebRFCs is the only way to go. If you are able, do please share your examples. I'm sure others would find that helpful.
Steve.
Thanks also for sharing this. I've created a call to retrieve the material type (MARA-MTART) that I was after which works like a charm. Now I shall extend it it to pass back multiple values.
Cheers
Ian
Hi Steve,
While programming RFC's how do we clear the browser cache?
I am trying to release and cancel a PO with the help of an Webrfc. If I don't clear the browser cache after the operation, and click on the same button, nothing happens, neither the message changes. I checked the PO in the backend. PO Status is same.
If I execute the RFC in the browser, it works.
Have you come across something similar?
Regards,
Manu
If you look at the video in this blog - Using WebRFC for update in a Personas script - you'll see I do something similar. In that case I'm locking and unlocking a user. The script button calls the same WebRFC for lock and unlock, but the parameters are different. If you're using the same URL, including parameters, for both release and cancel operations,maybe you could try my approach and use a different parameter for each.
I confess it didn't occur to me that browser caching would be relevant, and so I didn't design it this way deliberately. It may be a fortunate choice, though!
Steve.
Hi Steve,
It worked, I tried it with a different browser and it worked. In my default browser, i.e. IE, I changed a setting and it worked in it too.
In the Browsing history Settings> Check for newer versions of stored pages:
changed the setting to Everytime I visit the webpage.
It works now. Thanks a lot.
It's a learning!!! 🙂
Regards,
Manu
So maybe the default behaviour for IE is different from that for different browsers?
Since I develop on a Mac, I haven't tried my flavors in Internet Explorer much. Now that you've pointed this out I must go and do that to make sure they work properly. Thank goodness for Virtual Machines - I have a Windows 7 VM that is going to see a little bit of use tomorrow, I think:-)
Steve.
Hi Manu,
I usually add a dummy parameter to my call e.g. seed={seed} and assign it a random value that I generate in JavaScript: args.seed = Math.Random();
Cheers,
Tobias.
hello can please elaborate how you are calling webRFC and is there any ABAP Logic is written for that ?
Hi Steve,
I made a WebRFC to get the description of one material, with your guide and works great. 🙂
Next I change the WebRFC to return more information of the material as quantity, price and location with the description.
The function works fine if few data, but if not (long description) fails because don't enter on one line of the table HTML.
I try returning the data in multiple lines but in that case fails on SSP.
What else can I do to get all the information.
Thanks
Mariano Saccol
That's a really good question! I've just tried doing the obvious things and get the same behaviour as you. I'm going to need to find some time to play more seriously with this. I'll do that over the next few days. I wonder if Sebastian Steinhauer has any ideas?
Steve.
I almost missed this question for the second time.
I has already been answered here:
WebRFC - simply calling an RFC from javascript
I hope that answer works for you.
Hello,
For the any ABAP logic you wrote ?
Hi All,
I am using WebRFCs to update address data in PA30. Now if I paste the url, it either works fine or gives error "Employee/applicant is not locked yet".
However if I paste same url in a script button and call WebRFC, nothing happens.Neither I can see any message on my screen nor see data updated in PA30.
I don't understand what is wrong and so I am clueless. Request you to help.
Regards
Abhi
Hi Abhijit,
May be your browser is caching it.
Before calling the webrfc, can you include a
1. a step "calculate in javascript" --> args.rand = Math.random();
2, in next step, use this in your webrfc URL:
http://..........webrfc/?_FUNCTION=YourWebRfc&_rand={rand}
Tamas has also included this step in his blog here:
http://scn.sap.com/community/gui/blog/2014/01/17/search-help-for-a-custom-field-in-personas
Let us know.
Best Regards,
Sushant
Hi Sudhant,
Thanks for your reply.
After posting this message, with some fighting, I found it working.I could not update as I was still getting "Yet to be locked" message. The soution, was to use ENQUE,/ DEQUUE FMs. That sorted the issue. However a new issue has creeped up. A message that states Call to WebRFC failed.
I will implement your suggestions and update.
Thanks
Abhi
Hi Sudhant,
Still no luck.
I implemented your suggestion but no luck.
I will check if I have done something wrong.Now I am back to stage 1 where it worked only by pasting url in browser address bar.
Hi Sushant,
Apologies for my typo above. I should have been careful.
This is the url I am using to call RFC. This is static url. I have generated for testing.
http://myserver:myport/sap/bc/webrfc&_FUNCTION=Z_HR_PERS_0006_CREATE&SUBTYPE=1&FROM=20140120&PNO=526773&PERMADDRESSL1=addr uPDATE tESTING&PERMADDRESSL2=uSING WEBRFC&PERMCITY=PERTH&PERMPOSTCODE=6008&PERMREGION=WA&PERMMOBILE=0400000000
The error message I am getting is Calling the given WebRFC failed.
Hope this might help Regards Abhi
Hi Abhijit,
In You TEST URL, wherever there is "space",can you replace with "%20"?
Just encode it and see?
Regards,
Sushant
Hi,
Tried it. No luck. I am 100% sure that it was working previously. Even now, it works from browser, but if I copy paste the same thing in Persona Script, I get the error.
Regards
Abhi
Hi,
It seems like no call to the webrfc is working now. Even my call to a simple WebRFC to display name is also not working.
Regards
Abhi
Hello ,
Can you please tell me how yu called the WEB RFC ?? i have see the option in the Screen person on button there is option callWEBRFC but what parameters s i have to pass
Have you read the blog you are commenting on?
Steve.
HI Abhijit,
My two cents to this,
Try clearing the browser cache. If you are using IE,
In the Browsing history Settings> Check for newer versions of stored pages:
changed the setting to Everytime I visit the webpage.
Webrfc from browser will work, if everything is okay from the back end. Also when you pass from personas using JavaScript, make sure the variables you are passing are not blank. Check the values in the variables if possible.
You can also write in a line in your FM to check if the variables are populated or not.
We normally get the 'Call to webrfc failed error' when the variables are not populated correctly.
I hope this helps.
Regards,
Manu
Hi Manu,
Thanks for the insight.
I have already done the settings you mentioned in IE. However, I think I did not re-start IE. Will do it now and check.
The url is static i.e. I am generating it in notepad for testing.
Regards
Abhi
Hi Abhijit,
Can you please start a separate discussion and provide link here?
Would be better to continue discussion over there as it can get long!!
In your new discussion thread, can you provide more details on your Personas Script and probably post your rfc code too...
Regards,
Sushant
As suggested by Sushant, I have started another discussion. http://scn.sap.com/thread/3487106
Hi Abhijit,
i am posting here for others since I think the new discussion is deleted.
I was able to get into your flavor. Your webrfc was absolutely correct, the only issue was when you were copying from an element which was "empty" and using this value in your final URL.
So, below from step 9 to 12, i am handling that.
Well, you can be more creative and instead of doing these steps, you can check for "empty" all at once in javascript and put the final URL in the "Call WebRFC" as a variable in curly braces.
lastly, your WebRfc was returning a variable "Message" and after step 14, you were doign "Copy Value" from Message. Not needed.
Since "Message" is already a variable, you can directly use "Paste Value" on it.
Best Regards,
Sushant
Hi Sushant,
Thanks for your help. The issue is resolved. Now the WebRFC is working good in other scenarios as well. I have a question though in same context.
Now I am using WebRFC to read the data. I am reading 5 fields from bank data and I have inserted 5 entries in HTML table. Below screen shot shows them in debug mode.
I am getting call to WebRFC failed error. I could debug the WebRFC and it's execution is withouot any error. I am capturing all 5 keys in my Script . This scenario works if I pass only 1 key, but fails if more than one keys are passed. Is it not supported or (most likely) I am doing something wrong(again).
Regards
Abhi
Hi Abhi,
In your webRfc, you are returning back 5 result set which is wrong.
Just return ONE, and with any number of key value pair.
Regards,
Sushant
Hi Sushant,
Super fast response 🙂
Thanks.
Regards
Abhi
Hi Sushant,
Two Question 🙂
the HTML table has line length of 255. My response will be certainly bigger than that. How can I handle it?
Do I need to pass the entire, string starting from results:? Just {"Key" : "Payee", "value": "Payee for Bank"} is enough?
Regards
Abhi
Hi Sushant,
I found a very helpful statement in WebRFC - simply calling an RFC from javascript. I have formatted my return values and now it is working fine. For reference, this is how the multiple values can be passed back to Personas.
CONCATENATE '{"results": [ {"key": "name", "value": "' name '"}, {"key": "phone", "value": "911"}]}' INTO htmldoc-line.
From your response, I understand that there should be ONLY one occurance of RESULT and thus I can break my single result into multiple lines. Is that correct? Of course I am trying it out so I'll find out soon 🙂
Regards
Abhi
Hi,
Yup..it worked. Single occurrence of results and passing data in 2 lines. Worked beautifully.
Regards
Abhi
I think the problem comes from the multiple "results" blocks. If I'm not mistaken, there should be only one such block. Although I never tried to return more than one row in the html result table, so not sure how will Personas handle that.
Edit: darn, Sushant, you're too fast 😀
I was just wondering how do you handle special characters like "ÆØÅøæåÖÜÄ"
If these characters are used in JSON result string, it gives an error in Personas. If you encode the value in the string you will just receive the encoded result.
Ex.(URL encoded)
JSON string (only a part of it) : {"key": "address", "value": "Dampf%C3%A6rgevej+17,2100"}
When pasting the result into a field in personas it shows like this:
"Dampf%C3%A6rgevej+17,2100"
Wanted result:
"Damfærgevej+17,2100"
Regards
Henrik
Solution
Hi Tamas/Steve,
I have a FM created in se37 which works on a single import parameter and has 4 export parameters and it works perfect as per my requirement.The problem is with the my data getting populated when i call my FM using webRFC.Below is the scenario:
INITIALS-to be entered by the user, based on which the following fields are displayed
Field1-to be fetched from the FM
Field2-to be fetched from the FM
Field3-to be fetched from the FM
Field4-to be fetched from the FM
When i call my FM using webRFC, i can't find my data getting populated in Field-1,2,3,4.
I have been following Tamas's Blog and i have even entered the server:port no successfully.Still i am not able to figure out my problem.Can you help me outwith the same.
😕 😕
Regards,
Roshan.
My guess would be that there is a problem with proper data formatting when you build the returned JSON response.
It would be helpful to see the response when you are running the WebRFC call directly in the browser. Post a screen shot of the result of the returned JSON string as the first step.
Hello Tamas,
I have tried to paste the url into web browser and seems it is calling web-rfc. The challenge, i am facing is to pass dynamic value into web-rfc ( user will enter initials - and web-rfc will populate certain fields from FM)
The second challenge is, i need to pass the populated fields onto personas screen along with SAP error messages if any.
Any example in this regard would be helpful.
Thanks in advance. 🙂
Regards,
Roshan
Hello,
Can we delete the Table entries through the ABAP Logic by calling the Web RFC from the personas screen ??
if yes can you please demonstrate how to do it ?
You just need to modify the body of the function above to do what you need. But be careful deleting entries from a table directly. If you are talking about standard SAP tables, then manipulating them directly is almost always wrong. And even if not wrong, is certainly not advised.
Steve.
I want to delete the entries from Z table Not the standard table
That's OK then! So long as you understand how the table is used there should be no problem.
Steve.
Hi ABAPER P,
PFB the attached snapshot of the scripting steps first and after that i have explained you how you can delete your Z* table entries:
1) First i am copying my customer initials(on the basis of which the entries are to be deleted as in your case) from PERSONAS text-box .
2) Secondly i am calculating my server address(dynamic pattern, but before that try out with the hardcoded server address part refer the blog for further info)Use the following for hard-coding-http(s)://<your system>:<your port>/sap/bc/webrfc?_FUNCTION=Z_SAMPLERFC&_Name=<your name>
3) Calling webRFC where the copied variable in step-1, passing the same to webRFC(ABAP code) where i am doing the required validations and where i have incorporated the logic for deleting entries from the Z* table. Here the webRFC(FM in abap) has to be internet released and also release FM using SMW0 open padlock.
4) In the FM where i have incorporated the logic of deleting entries, after i commit the deleting task successfully , i am passing a success message as follows(Keep a track of the space and double quotes ):
CONCATENATE '{"results": [ {"key": "Var1", "value": "' Var1'"}]}' INTO g_returnvals.
5) Check in your debug mode for the FM what values are getting populated in your g_returnvals string variable paste that same varialbe onto your personas screen.
Reward if you find it usefull ..!
Thanks and Regards,
Roshan.
Eh?
Begging for "reward" is against the SCN rules if I'm not mistaken... besides, he cannot "reward" you anyway because this is not his thread.
Hi Tamas,
1) My sincere apologizes i am new to SCN so i wasn't aware of SCN rules.
2) I have just collated the points which @Steve ,@You etc. had written in your original blog as the user@ABAP ER had so many queries and i just added a shared my experience while i had implemented.
3) I read so many threads and posts which do follow a practice of "Reward if you find it usefull" so i just followed under similar line , won't be following that hence. 😎 .
I do read your posts and blogs and really your posts have been a great learning for me 🙂 ,Thanks a ton..!
My sincere apologizes once again..!
Regards,
Roshan.
Hi Roshan, thanks for the tip
Hello Steve,
I created a RFC for a Personas 2 Flavor, too.
I tested the RFC in SE37 - everything is working fine.
When I start the RFC via scripting in my Flavor for the first time-> everthing is working fine.
When I start the RFC for a second time, nothing happens!?
The RFC select the number of created PM-Messages.
The results will be displayed in text-fields (Personas-Flavors) as a user-information.
Do you have any ideas to solve this problem?
Regards Matthias
refresh the browser history and try again.
copy pasting from my own post above... 🙂 :
May be your browser is caching it.
Before calling the webrfc, can you include a
1. a step "calculate in javascript" --> args.rand = Math.random();
2, in next step, use this in your webrfc URL:
http://..........webrfc/?_FUNCTION=YourWebRfc&_rand={rand}
Hi Matthias,
I guess it's a browser related issue where-in you can just check:
a) if all the cache/cookies have been cleared.
b) If you are using IE-->setting-->internet options-->website data settings->check for newer versions of stored pages-->select radio button(every time i visit the webpage).
Regards,
Roshan.
Hi Roshan,
thanks for your support.
I changed the IE settings (topic b).
Everything is working fine now.
Regards Matthias