Power Apps Custom Functions & Reusable Code
“Don’t repeat yourself” is a software development principle all great app makers follow. In a practical sense, it means any repetitive code should only be written once as a custom function. Then the function can be called on again-and-again to do a task. For many years Power Apps fans have been asking for a custom functions feature but this week it was finally announced on the official blog.
In this article I will show you how to write a Power Apps custom functions and unlock the power of reusable code.
Table of Contents:
Introduction: Build The EOMonth Function
Enable Power Apps Custom Functions
Build A Function Component
Use A Function Component On A Screen
Add An Optional Parameter
Final Thoughts
Introduction: Build The EOMonth Function
EOMonth is handy function that exists in Excel but not in Power Apps. It finds the last day of a given month. We will build EOMonth as a Power Apps custom function.
EOMONTH(StartDate, AddMonths)
- StartDate – Required. Date/time value to operate on.
- AddMonths – Optional. Number of months to add to the start date. Can be either positive or negative.
Assuming today’s date is 2/21/2021 the EOMonth function would show the following results.
EOMONTH(Today(), 0) // Result: 2/28/2021
EOMONTH(Today(), 1) // Result: 3/31/2021
EOMONTH(Today(), -3) // Result: 11/30/2020
Enable Power Apps Custom Functions
Custom functions are an experimental feature at this time. To use them you must open the advanced settings menu and turn on Enhanced component properties.
Build A Function Component
Let’s get started. Open Power Apps Studio and create a new app from blank. Go to the components screen and add a new component called DateFunctions.
Add a new custom property called EOMonth. Make the property type Output and the Data type Date and time. Then click on + New parameter.
Parameters are a new concept. A parameter is a value input by the app maker while using the custom function. Give the parameter a name: StartDate. Select the Data type Date and time and choose Required. Once finished click Create.
Now we will write the custom function. Go to the EOMonth property…
…and write this code in the formula bar. It will calcuate the end of the month based on a StartDate input by the app maker.
Date(Year(StartDate), Month(StartDate)+1, 1)-1
Use A Function Component On A Screen
The custom function not completely done yet but we can already try using it. Go to a blank screen in the app, insert the DateFunctions component and name it cmp_DateFunctions.
Then add a label to the screen and put this code in the Text property.
cmp_DateFunctions.EOMonth(Today())
It will show the last day of the current month.
Add An Optional Parameter
OK, now let’s add another feature to our custom function. EOMonth should give an app maker the ability to optionally add months to the StartDate.
Go back to the DateFunctions component and add another parameter called AddMonths. Define the Data type as Number and do not make it a required value. Click the create button when done.
On the Edit custom property menu you will see StartDate is a required parameter and AddMonths is in the Optional section. Click Save.
Change the EOMonth property of the DateFunctions component…
…to this code.
DateAdd(Date(Year(StartDate), Month(StartDate)+1, 1), AddMonths, TimeUnit.Months)-1
Then change the AddMonths property of EOMonth to 0. This is the default value to be used when the app maker does not provide an optional value.
Our custom function is now done! Go back the screen with the component and try adding a number as the 2nd parameter for EOMonth.
Final Thoughts
Here are a few more thoughts I have about Power Apps custom functions:
- Custom functions require a component to be placed on the screen. Either put your custom functions inside a title bar component which is found on every screen or create a small transparent component to hold them.
- Custom functions should be stored in a centralized library so they are reusable from project-to-project.
- Don’t wait for this feature to come out of experimental status to start compiling your list of custom functions. Start doing it now so you are ready when the feature hits general availability.
Want To Learn More About Power Apps Canvas Components?
This tutorial is part of a free online course called Learn Power Apps Canvas Components By Making 5 Components. The best way to learn isn’t by watching videos, or by reading articles. The best way to master Power Apps canvas components is by building real-world projects. So that’s exactly what we’ll do. Go ahead and get started on the other lessons below. I know you’re going to get alot of this free course.
Did You Enjoy This Article? 😺
Subscribe to get new Power Apps articles sent to your inbox each week for FREE
Questions?
If you have any questions or feedback about Power Apps Custom Functions please leave a message in the comments section below. You can post using your email address and are not required to create an account to join the discussion.
Thank you for writing this article Matthew.
I think the first example has a typo and should be minus three:
Maarten,
Thanks for spotting that. I’ve gone ahead and fixed it 🙂
Thank you for writing up such a detailed explanation. I can’t wait until I can get in there and try this out. I just recently learned how to use select to put my reusable code in buttons, this is definitely a step up. As a programmer, I’m wondering why this wasn’t implemented much sooner.
I’m excited for you to get started on building your own functions Valerie. I wish it came sooner too, but I’m so happy its here now 🙂
Hi Matthew I might of missed something, but the end of March is the 31st not the 28th as shown in your last screen.
Nigel,
Great catch. I will fix this immediately.
Hi Matthew This Formula for EOMonth appears to work for me :- Date(Year(StartDate),Month(StartDate)+ AddMonths + 1,0)
Nigel,
I settled on something different but thank you for the advice 🙂
DateAdd(Date(Year(StartDate), Month(StartDate)+1, 1), AddMonths, Months)-1
Have you started to create your own custom functions yet? Which ones did you make?
As always Matthew a great post. I missed this blog so your post was revelatory. We need a place for people to post custom functions, perhaps in the PAC
Bill,
I’ve started a public Github repo for sharing Power Apps custom functions. We already have 3 contributors and want to get as many people as possible involved. If you are interested in sharing your work you can add it using a ‘pull request’. I can help you get started if you’re not familiar with Github.
I’m also working on figuring out the best place in the PAC: whether it’s the existing component samples or something else.
Link:
https://github.com/yourekittenme/powerapps-custom-functions
Thanks for this article. I’m playing with custom functions now and wondered if there’s a way to use them to update a Collection that derives it’s data from SQL Server? I’ve got a few drop down lists on a screen with a gallery list which is populated with a Collection (i.e. data from SQL server that has filters applied to it. I wanted to update the Collection data (i.e. go to the SQL Server and return query results and put them into the collection) each time a user selects a new value in a drop down list. I was hoping to find a nice way to put the large filter method that is the basis for the SQL Server query into a reusable function. Currently the filter is not recognising the data source. This would avoid me putting the same long filter method into each dropdown list in the OnSelect or OnChange methods – minimising the point of maintenance.
Sandy,
At this moment its not really possible because a component cannot access a data source. It’s disappointing for sure…
Are all of your dropdowns on the same page? If this is the case, I use a technique where I put all of the repetitive code in OnSelect property of a Power Apps button control and then set the Visible property to false. When I need to run the code I write Select(button_name) in another control on the same screen. This way it can be reused.
Hi Matthew,
Yes all the dropdowns are on the same page. Your workaround method worked a treat!
I look forward to the maturation of PowerApps as it grows in popularity….
Thanks for your help!
Sandy
Sandy,
You’re welcome. I’m glad my approach made sense for your scenario.
Matthew,
Is this still the case? I really want to combine some of my collecting code into one place because I use it on three separate sections of my app. It gets really old having to change code in more than one place.
Hi Valerie,
this also bothered me. As an App grows, collecting Data, rebuilding Collections and so on is often resused on many different places.
There is an pretty easy way to do this with a custom component.
All you need is an event and an action property.
Let’s name the event property “formula” and the action property “execute”.
Within the action property you call the “formula” in the fx bar with “self.formula()”.
Now you import the component into your app and you just enter your desired code into the formula property of the imported component.
Last step is to execute the formula by calling the “execute” property of the component at your desired place (eg. on visible or on select for a button)
That’s it.
Hi Matthew,
Why do you need to place the component on all screens. In my testing you can refer to the component with the custom function on another screen and it will work just fine. Even when the screen hasn’t been loaded before.
Jean-Paul,
I do this because I don’t want more than one screen loaded into memory at a time. But I realize its a bit redundant. Its fine to use only one component if your app is still performant.
Error using this formula in EOMonth()
DateAdd(Date(Year(StartDate), Month(StartDate)+1, 1), AddMonths, Months)-1
*error- MONTHS isnt recognised
FIX worked for me, although might not be correct?
DateAdd(Date(Year(StartDate), Month(StartDate)+1, 1), AddMonths, “Months”)-1
Nipun,
The change should be TimeUnit.Months
What about a simple one like this:
Concurrent(
Refresh(tbl_List1),
Refresh(tbl_List2),
Refresh(tbl_List2)
)
I can’t figure it out. 🙁
Matthew,
Great article. Thank you for the insights.
Quick note/question: It’s correct that Components cannot currently read/change global variables, right? I am setting global variables in my App’s OnStart, which I would like to change in the functions defined in my Component. This is where I stumbled upon the one thing that keeps me from using Components; the fact that it can’t read global Variables.
If you have a workaround or a suggestion on how I could improve my current way of working, I’m looking very much forward to it.
Daniel,
Correct, you cannot change a variable’s scope from inside a component. But if you turn on the enhanced component properties experimental settings you could do it like this:
https://www.matthewdevaney.com/power-apps-component-with-an-onselect-property/
RE comment posted earlier today – I now see that my plan to use Formulas in App area does not allow for behavior function in a non-behavior property – and, I’m not sure if the method you are posting allows the sort of functionality I’m after. For instance, define ‘U’ as follows: U = Collect(colhmm,{hmm:1}); AND THEN on a screen, create a button which simply has in its onSelect property [ U ]. The goal I’m trying to end up achieving is the ability to make my code simpler, less bloated.
Hi, really interesting. I tried and have been successful with simple input parameter. I’m now trying to build a recursive function to generate a collection containing the bill of material of a product… Is it possible in Power Apps components ?
Louis,
Nope. Recursion won’t work in Power Apps.
Thanks for your feedback.
Hi,
I was getting an error on the EOMonth property, but changing it to the following fixed it:
DateAdd(Date(Year(StartDate), Month(StartDate)+1, 1), AddMonths, TimeUnit.Months)-1
I have learned a lot from your articles. Thanks very much!
Ray,
Yes, the Power Apps language changed over time and you’ve come across the correct fix.
Hi Matthew,
Great article – i’ve used this quite frequently for our projects in the past but was always a little bit nervous given it was still an ‘experimental’ feature. Having said that, its been almost 3 years that this has been available but not necessarily a GA feature
We are build a pretty complex ISV solution and custom functions would massively simplify the implementation. Would you recommend we use this in production scenarios / have you used this in production situations yet?
Fawaz,
I would use “Enhanced Component Properties” feature in production. It’s stable.