Custom-defined functions
Make functions available in text boxes, specifications, and other EbsScripts.
In Excel, it’s common to write a User-Defined Function (UDF) in a VBA macro, and have that function be available in formulas. You can do something similar in Ebsilon.
I’ll first show an example, then describe how to do this.
Example
I wrote a silly function named “DoubleIt” that just multiplies a number by 2. In the screenshot, this function is used in a Text Field and a Specification. You can also use the function in other EbsScripts.
How to Define the Function (model-specific)
This is how you define functions for use within a specific model. It’s analogous to writing Excel VBA code within an *.xlsm file — it’s available only in that model.
Later in this post, I describe how to define functions that can be available to ALL models, analogous to functions defined in Excel Add-Ins, which become available to ALL your spreadsheets.
Part 1: Write the Code
Hit the EbsScript editor on the toolbar (or hit the F8 key), then the write the code. Save it internally (you’ll be asked Where when you hit Save). Note that for internally-saved EbsScripts, the name can contain only letters (including äöêâäiçæôíó and their uppercase versions), numbers, and the _ character. Spaces are not allowed).
Here’s the code for the DoubleIt function, saved internally as “MyCustomFunctions”:
Note the three special statements, which are needed to make the DoubleIt usable outside this code module: unit, interface, and implementation (with its matching end statement at the bottom).
Part 2: Make it Available
On the Ebsilon main menu: Extras… Model Options (or hit the red gear)… EbsScripts. Then hit the New button.
Select the EbsScript code module from the list that pops up:
Usage Syntax
To use the function in a text field, enclose the function in curly brackets:
—> { DoubleIt(123) }To use the function in a specification, just enter the formula:
—> DoubleIt(100)To use the function in other EbsScript code, put a “uses” statement at the top of the code, with the name of the internally-saved code module:
—> uses MyCustomFunctions ;
How to Define Functions for use in ALL models
Write the code as described earlier, but when prompted to save it, choose External:
As for internally-saved EbsScripts, the name can contain only letters (and accented variants), numbers, and the underscore character.
The process to make the externally-saved functions available is different vs. model-level functions. Go to the Ebsilon main menu… Extras… General Options (or the blue gear button)… Paths… Path for… and select “EbsScript Standard Unit Files”:
Hit the New button:
Then the … button, and browse for the *.esc file with the code:
My code code is defined in MyCustomFunctions20230916.esc:
The functions defined in this file can be used in text fields and specifications without anything special being needed.
For use in other EbsScripts, you need a “uses” statement, but it’s a little different from internally-saved code in that it needs the “in” and the full pathname:
As with model-level code, the name of the unit on in the uses statement must match the filename.
Final Thoughts
Should your functions be defined internally (for use only in a specific model) or externally (for use in all models)? Like many things in life, “it depends”.
A key point is that if you change the code in an externally-saved file, then ALL models are affected. This might or might not be what you want. Furthermore, if you share models with other people, if they have a different version of that external *.esc file, they might get different results.
For general-purpose utility functions that don’t affect performance numbers on a heat balance diagram, application-level external functions might be appropriate. But if you need absolute control and consistency of technical data, internal, model-level code might be better.
A way to get the “best of both” could be to include a date stamp to externally-saved code. I did this in my example — the file is named MyCustomFunctions20230916.esc (with the date in yyyymmdd format). If functions are updated and perhaps distributed within your organization, they can be consciously invoked by forcing users to update the application-level Path to these functions.
A little trick I had in my example was a function to display the version of the Functions file, which could be nice to show in a text field. It uses a new feature introduced in v16.0: pre-defined EbsScript functions such as $(file). Here’s the code for the MyCustomFunctionsVersion fuction: