Until FOR loops are added in PowerApps, I have a workaround that I've been using and it's really come in handy.
I start by adding a collection in my App's OnStart property (I'll show at the end how to do this in Flow, which I prefer).
I've attached a template for this from 0-1000 (For.txt at the bottom)
ClearCollect(Loop,
{Index:0},
{Index:1},
{Index:2},
{Index:3},
...
{Index:100}
)
You can now perform a FOR loop by filtering this collection. For example, if I want to get a collection of dates that are 7 days from a selected date, I can do this:
Clear(NextDates);
ForAll(Filter(Loop,Index<=7),
Collect(NextDates,
{
Date:DateAdd(DatePicker1.SelectedDate,Index,Days),
DaysSincePickedDate:Index,
DayOfWeek:Weekday(DateAdd(DatePicker1.SelectedDate,Index,Days))
}
))
I get this result:\
Remember that the numbers don't have to be hardcoded. You can use CountRows(),a numeric input, or any other integer to drive this code.
The shell of the FOR loop looks like this:
Set(i,0);
ForAll(
Filter(Loop,Index<=7,Index>=i),
//Code
)
This would be the equivalent to something like this:
for (i = 0; i <= 7; i++)
{
//code
}
To clean up the Loop collection, I use Flow. Here's what that solution looks like:
I can now use this code to get my Loop collection (I like to rename the column to Index, since Value is the generic term from Flow)
ClearCollect(Loop,RenameColumns(For.Run(1000),"Value","Index"));
That will return a collection of 1000 rows without all the manual coding! This Flow is pretty slow, so you can also setup this logic to only load it once for each user (this saves the collection to memory on mobile):
LoadData(Loop,"Loop", true );
If(CountRows(Loop)=0,
ClearCollect(Loop,RenameColumns(For.Run(100),"Value","Index"));
SaveData(Loop,"Loop")
)
Solved! Go to Solution.
This is a pretty good workaround to the lack of a 'for' construct in PowerApps. I've been using something similar, and those are some things that you can do to make your code a little faster and/or smaller:
ForAll(
FirstN(LoopMaster, CountRows(MyColl)),
// Code
)
ClearCollect(LoopMaster,{Index:0}); Clear(LoopMaster);
ForAll(
RenameColumns([0,1,2,3,4,5,6,7,8,9], "Value", "Hundreds"),
ForAll(
RenameColumns([0,1,2,3,4,5,6,7,8,9], "Value", "Tens"),
ForAll(
RenameColumns([0,1,2,3,4,5,6,7,8,9], "Value", "Ones"),
Collect(LoopMaster, {Index: Hundreds * 100 + Tens * 10 + Ones}))))
Clear(NextDates);
ForAll(
FirstN(LoopMaster, 8),
Collect(
NextDates,
{
Date:DateAdd(DatePicker1.SelectedDate,Index,Days),
DaysSincePickedDate:Index,
DayOfWeek:Weekday(DateAdd(DatePicker1.SelectedDate,Index,Days))
}))
ClearCollect(
NextDates,
DropColumns(
AddColumns(
FirstN(LoopMaster, 8),
"Date", DateAdd(DatePicker1.SelectedDate,Index,Days),
"DaysSincePickedDate", Index,
"DayOfWeek", Weekday(DateAdd(DatePicker1.SelectedDate,Index,Days))),
"Index"))
Hope this helps, and thank you for sharing your ideas!
This is a pretty good workaround to the lack of a 'for' construct in PowerApps. I've been using something similar, and those are some things that you can do to make your code a little faster and/or smaller:
ForAll(
FirstN(LoopMaster, CountRows(MyColl)),
// Code
)
ClearCollect(LoopMaster,{Index:0}); Clear(LoopMaster);
ForAll(
RenameColumns([0,1,2,3,4,5,6,7,8,9], "Value", "Hundreds"),
ForAll(
RenameColumns([0,1,2,3,4,5,6,7,8,9], "Value", "Tens"),
ForAll(
RenameColumns([0,1,2,3,4,5,6,7,8,9], "Value", "Ones"),
Collect(LoopMaster, {Index: Hundreds * 100 + Tens * 10 + Ones}))))
Clear(NextDates);
ForAll(
FirstN(LoopMaster, 8),
Collect(
NextDates,
{
Date:DateAdd(DatePicker1.SelectedDate,Index,Days),
DaysSincePickedDate:Index,
DayOfWeek:Weekday(DateAdd(DatePicker1.SelectedDate,Index,Days))
}))
ClearCollect(
NextDates,
DropColumns(
AddColumns(
FirstN(LoopMaster, 8),
"Date", DateAdd(DatePicker1.SelectedDate,Index,Days),
"DaysSincePickedDate", Index,
"DayOfWeek", Weekday(DateAdd(DatePicker1.SelectedDate,Index,Days))),
"Index"))
Hope this helps, and thank you for sharing your ideas!
Hey @CarlosFigueira,
this is such a useful tip, but I can't for the life of me get the RenameColumns([0,1,2,3,4,5,6,7,8,9,...,999] to work. I always get a squiggle under the ... "invalid use of '.'"
Is there some preview feature I need to turn on to get this?
Thanks
Craig
The '...' is just to denote numbers between 9 and 999, it's not actually part of the formula.
Seriously? So you have to type in all 1000 numbers? (or script out somewhere else and paste in)
There has to be a better way!
There are a handful of other ways, but typing it out is the fastest (to process, that is). You could setup an excel document with maxed out rows of consecutive integers and use that, which would probably be the most efficient.
You don't need 1000 "numbers" you need 1000 rows. It can be anything. I just did this:
Collect(aLongTable, [" ", " ", " ", " ",
Then copy and pasted:
" ", " ", " ", " ",
to get
Collect(aLongTable, [" ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ",
Then copy and paste
" ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ",
etc...
Took me about 30 seconds to make a table of 1000's of rows. Now you can use this to run your ForAll on your FirstN(aLongTable, NumberOfLoopsYouWant)
It's not exactly elegant and I still don't know a great way to increment a variable inside a ForAll but I'm sure there's a workaround for that too.
Yeah, I get that, but still, YUCK!
The value of putting numbers in the rows is that you can then compare and use partial ranges to get subsets of values - smaller numbers of items.
User | Count |
---|---|
183 | |
124 | |
88 | |
45 | |
43 |
User | Count |
---|---|
248 | |
157 | |
127 | |
78 | |
73 |