1.4 new features: Getting familiar with the Global Script Function
Intro
Now I got my hands on the 1.4 version I off course want to try the new features. Over the coming weeks I will take new features and write about my first tries to use them. The first item in this series is the Global Script Function.
You will not find the component in the Components Panel. You can add them by right clicking on the new “Technical Components” folder in the Outline panel and create a child of the type “Global Scripts Object”.
You can create multiple instances of this type of object and in this object you can create as many functions you want.
When you add a function you will see this screen. You can set the input parameters and you can set the return type. There are two main types :
- Void : just do things
- All others: return a value to the caller
As you can see there are many types. Including the components. Even SDK components will show up here as a type that you can return.
The Script Editor is the script editor that we know already. What you will find when you press <CTRL><SPACE> is a method “return” . This is needed when you set the return type to anything but void. With this keyword you can send the final result on its way to the caller.
Getting my feet wet
For a start I made three functions :
- setMenu type void: A function that sets all elements to disabled and the one passed in parameter to enabled
- updateButtons type button: A function that returns a component type to see how you can work with it
- presentValue type string: A complex calculation function that calculates the net present value for an amount you get in 1,2,3 and 4 years.
setMenu
This is the basic menu function. You have a number of buttons and you want them all to reset. Only the current button has to be enabled. This off course can also be a CSS function where the current button gets a special CSS layout.
This works easy enough. It is a void so you basically have a central script here. What I didn’t like at all was that renaming components in design studio does not lead to renaming in the function. This was always there from the start. Something I really appreciate. I really expect that this will be available as soon as SP1 as this does hamper the advantage of a central function. Now I would continue using buttons for this as I don’t want to unintentionally break the script.
updateButton
I was curious what I could do when I returned a component type. That’s why I also tried this function.
What I can do is either pick up a button as an input parameter or refer to a button in the internal var statement. For example to a template button?
I can set some properties and return the button object with the new properties.
In the scripts I cannot suffice with
BUTTON_2 = GLOBAL_SCRIPTS_1.updateButtons();
I have to assign the result to a variable and then copy those properties to my own button.
What I can do is use this function as input for another function. You run into the same issue as above. But if you create multiple void functions and want to refer to a standard button from all those functions you can use this.
Net Present Value
The final function is a financial calculation. This is mainly used in investment decisions. If I invest 100 now and get 105 back in 3 years. Is that good or bad? The present value will calculate the 105 in three years back to present value by using some kind of inverse intrest.
The formula is Amount / (1+intrest rate) ^ number of years.
In this example it was my goal to produce a list of values for each year.
As you can see instead of using a power function I used an elaborate way by multiplying. Normally I would create an SDK to do this as this is a bit too clumsy. But now my goal is to get to know the global function.
Additionally I cannot use an array as a return type. I could circumvent that by using a dropdown box for example and use additem and return that.
Instead I chose to return a string and separate the values by pipes (|).
In this script you see how I split the values up again and pass them to a listbox. In a next installment I will look at the constant datasource. I think using addcell as a method will result in me being able to create a graph visualizing the next present value amounts.
Conclusion
All in all I am happy that this function is added but I do think it still needs more flexibility and it doesn’t feel completed yet. The number one thing that is needed is making sure that renaming objects won’t break any script lines.
Isn't it better for your update buttons to create an input parameter with type button,
and then do this:
BUTTON_2 = GLOBAL_SCRIPTS_1.updateButtons(BUTTON_2);
Seems more logical. Or I might not understand the thing that you trying to accomplish.
Hi Niels,
My goal in this blog was to get to know the new function. That's all.
So I just did three different scenario's.
I agree that your way is the most efficient. But that will run into and
"You can only assign variables that have a simple type. BUTTON_1 does not have a simple type."
error in your script.
You are right, I did not have Design Studio with me at the time. After testing for a few seconds this seems to work:
followed by code:
GLOBAL_SCRIPTS_1.ButtonTest(BUTTON_1);
Isn't this what you were trying to accomplish?
Hi Jeroen,
thanks for testing.
Could you please be a little bit more detailed in what you consider to be missing? I understand that supporting (typed) arrays as parameter and result type would make sense.
About refactoring: If a global script function is free of syntax errors, any renaming of components should be automatically applied to global functions as well. We had this feature already before for any other script.
On your usecase to do some changes on some buttons, I agree to Niels:
Simply pass in the button(s) as input parameter into the function, e.g.
GLOBAL_SCRIPT_1.updateButton(BUTTON_1);
GLOBAL_SCRIPT_1.updateButton(BUTTON_2); ...
Inside of updateButton you can access to concrete button by a parameter, e.g. currentButton.
We also think to provide some "superclasses" as possible parameter type, e.g. "Component". If you would use such a type, you could write a function that supports all components that inherit from this class.
Do you think this would be useful?
Regards,
Reiner.
Hi Reiner,
when I try to rename MENU_1 component i get this error :
Could not bind a reference of component com.sap.ip.bi.base.application.DeclaredServiceActivator. The reference is: Reference[name = IActivatorBase, interface = com.sap.ip.bi.base.bundle.IActivatorBase, policy = dynamic, cardinality = 0..n, target = null, bind = addRICActivator, unbind = removeRICActivator]
The component that holds a reference to MENU_1 is Globalscript_1.setMenu
I have no script errors.
I've attached the application to the blog, maybe I overlooked something?
The superclass component type is a nice idea for when you want to create a function that supports multiple types of component. It simplifies things so that you don't have to create a method for each component type for example setButtonCSS and setPanelCSS (just an example)
What Also would be beneficial is if I can reference a component by Name. Something
van myButton = APPLICATION.getComponent("BUTTON_1")
this would allow me to pass a list of names and loop through them and doing things to each one of them.
best regards.
Jeroen
Update : I added global.txt : rename to global.zip and extract.
Hi Jeroen,
the refactoring bug is known and already fixed in 1.4 SP1. The error in the log is not related to this, you can safely ignore it.
Regards,
Stefan
thanks 🙂 looking forward to SP1 already 😉
HI Jeroen
Is it possible to save the global script (function) to BIP? 😐
I would create a global funktion for all Design studio Reports, if I have a change I should only change the script one time and all reports are updated. 🙂
Best Regards
Gabriel Motor
Hi Gabriel,
The Global Script Function is for application level, it cannot be saved to BIP. You can off course copy/paste it across applications. But if you change something you have to redo that.
If you really want a reusable component have a look at SDK components A SDK component is saved centrally and a change will be automatically applied to all applications.
In the ZTL part of the SDK you even can put some BIAL script providing you have the components in place in your application.