cancel
Showing results for 
Search instead for 
Did you mean: 
Reply
joef
Continued Contributor
Continued Contributor

Running ForAll loops sequentially

Hi All,

I am trying to run 2 Forall(Patch({})) sequentially from a submit button.

It seems they run concurrently.

I need to have my second Forall(Patch({})) wait for my first Forall(Patch({})) to complete.

 

Is this possible?

 

TIA,

Joe

1 ACCEPTED SOLUTION

Accepted Solutions
RandyHayes
Super User III
Super User III

@joef 

I am not completely clear on what you mean by uncommitted work.  Your first formula will not be making any changes to the values in your Gallery, and your formulas are all using values already in the Gallery.  So, even if they both happen at the same time, your values should not be any different.

Perhaps it is that you are saying you want to make sure there are not submit errors in the first formula before you do the second...if so, you can try the following formula:

Collect(WorkList,
    ForAll(Filter(Gallery3.AllItems, Toggle3.Value) As _items,
    
    Patch(_items,
       { EmployeeEmailAddress: VarUserID,
         LocationName: ComboBox1.Selected,  // I have concerns on this one...is LocationName a record type column (choice, lookup, etc.)?
         Percentage: Value(TXT_EG_Percent.Text)
       }
    )
)

If(IsEmpty(Errors(WorkList)),

    Collect(EmployeeTime,
        ForAll(Gallery3.AllItems,  // don't you want to filter based on your toggle here?

        Patch(Defaults(EmployeeTime),
            { PeriodName1: TXT_PeriodName.Text,
              PeriodID1: Value(TXT_PeriodID.Text),
              EmployeeEmailAddress: TextInput1.Text,
              LocationName1: ComboBox1.Selected.Value,  //Here you're using the Value for location name, but above you used the Selected record?
              LocationID1: Value(TXT_LocID_1.Text),
              Percentage: Value(TXT_EG_Percent.Text)
            }
        )
    )
    , 
    Notify("Something went wrong with WorkList", Error)
)

If(!IsEmpty(Errors(EmployeeTime)),
    Notify("Something went wrong with EmployeeTime", Error)
) 

(please scrub for any syntax errors - this was written free-hand without the help of the formula editor)

This should perform the full submit (Collect) of all the records at once and then hold for the Errors to be returned in the first If statement - then do the second chunck.

 

If that produces no joy...then the other option is to do as you had - place the second in a separate button (make it not visible) and then at the end of the first button function, put a Select(theOtherButtonName)  This will cause the formula to execute and then it will select the other Button automatically.

 

_____________________________________________________________________________________
Digging it? - Click on the Thumbs Up below. Solved your problem? - Click on Accept as Solution below. Others seeking the same answers will be happy you did.
Check out my PowerApps Videos too! And, follow me on Twitter @RandyHayes

Really want to show your appreciation? Buy Me A Cup Of Coffee!

View solution in original post

4 REPLIES 4
RandyHayes
Super User III
Super User III

@joef 

Although I see everyone trying to use ForAll functions as if they are For/Loop statements in development, they are quite different.  The ForAll returns a Table based on the parameters of the ForAll.  That table can then be used to populate a control, a variable, a collect, a datasource, etc.

 

In the case of Patching...too common to see the Patch in the ForAll.  It need not be (and for performance, shouldn't be)  The Collect function (which everyone assumes to be about Collections) actually goes the other way...to the datasource.

So, Collect(yourDataSource, ForAll(someTable, {column1: something1, column2 : something2}))

Would actually submit a complete table to the datasource with the records it needs.

 

So, provide a little more detail on what you are trying to do and perhaps I can shed some more light on options.

_____________________________________________________________________________________
Digging it? - Click on the Thumbs Up below. Solved your problem? - Click on Accept as Solution below. Others seeking the same answers will be happy you did.
Check out my PowerApps Videos too! And, follow me on Twitter @RandyHayes

Really want to show your appreciation? Buy Me A Cup Of Coffee!
joef
Continued Contributor
Continued Contributor

Hi @RandyHayes ,

Let me try to explain this :).

I have 2 lists that I am patching to.  I bring in a working table into a gallery, where you can change your location and percentage of time you worked at each location.  

After you select all your locations and add the percentage, I want to save the working table as well as save the same data with extra columns like "Period" and a few other user info to a history list where I will have a process to pull the data into our financial system to allocate employees time to the proper GL accounts and legal entity.

 

If you already submitted for the current period I display the Allocation information with an edit button.

If you edit, it removes the allocation, and brings in the working list into a gallery (Which will be the same as last submission).

Since I am in a gallery, I already have my collection.  I have 2 patches (See below) but they seem to fire off at the same time not serially, causing my allocation list to grab the uncommitted work list items before the first patch updates the data.

 

I setup my gallery to look like the quick edit of SPO, so you can work in the form like in Excel.  I set a toggle if something changes so I don't blindly write everything every time. 

Since PowerApps does not have the concept of a Waitfor or Delay command, I had to use 2 buttons to save the data. "OnSelect" of the save it patches the work list, then enables the submit button to patch the allocation list.

My boss does not like to push buttons, so I was hoping for a workaround to patch both list correctly all the time 🙂  If I change 1 item the 2 loops work, but if I change 2 or more, only the first is updated before the second loop pulls the uncommitted data.  

 

IfError(
ForAll(Filter(Gallery3.AllItems, Toggle3.Value = true),
Patch(WorkList,ThisRecord, //Gallery3.Selected,
{ EmployeeEmailAddress: VarUserID,
LocationName: ComboBox1.Selected,
Percentage: Value(TXT_EG_Percent.Text)
})),
Notify(
"Something went wrong",
NotificationType.Error
)

) ;

 

IfError(
ForAll(Gallery3.AllItems,
Patch(EmployeeTime,Defaults(EmployeeTime),
{ PeriodName1: TXT_PeriodName.Text,
PeriodID1: Value(TXT_PeriodID.Text),
EmployeeEmailAddress: TextInput1.Text,
LocationName1: ComboBox1.Selected.Value,
LocationID1: Value(TXT_LocID_1.Text),
Percentage: Value(TXT_EG_Percent.Text)}))
,
Notify(
"Something went wrong",
NotificationType.Error
)
) ;

RandyHayes
Super User III
Super User III

@joef 

I am not completely clear on what you mean by uncommitted work.  Your first formula will not be making any changes to the values in your Gallery, and your formulas are all using values already in the Gallery.  So, even if they both happen at the same time, your values should not be any different.

Perhaps it is that you are saying you want to make sure there are not submit errors in the first formula before you do the second...if so, you can try the following formula:

Collect(WorkList,
    ForAll(Filter(Gallery3.AllItems, Toggle3.Value) As _items,
    
    Patch(_items,
       { EmployeeEmailAddress: VarUserID,
         LocationName: ComboBox1.Selected,  // I have concerns on this one...is LocationName a record type column (choice, lookup, etc.)?
         Percentage: Value(TXT_EG_Percent.Text)
       }
    )
)

If(IsEmpty(Errors(WorkList)),

    Collect(EmployeeTime,
        ForAll(Gallery3.AllItems,  // don't you want to filter based on your toggle here?

        Patch(Defaults(EmployeeTime),
            { PeriodName1: TXT_PeriodName.Text,
              PeriodID1: Value(TXT_PeriodID.Text),
              EmployeeEmailAddress: TextInput1.Text,
              LocationName1: ComboBox1.Selected.Value,  //Here you're using the Value for location name, but above you used the Selected record?
              LocationID1: Value(TXT_LocID_1.Text),
              Percentage: Value(TXT_EG_Percent.Text)
            }
        )
    )
    , 
    Notify("Something went wrong with WorkList", Error)
)

If(!IsEmpty(Errors(EmployeeTime)),
    Notify("Something went wrong with EmployeeTime", Error)
) 

(please scrub for any syntax errors - this was written free-hand without the help of the formula editor)

This should perform the full submit (Collect) of all the records at once and then hold for the Errors to be returned in the first If statement - then do the second chunck.

 

If that produces no joy...then the other option is to do as you had - place the second in a separate button (make it not visible) and then at the end of the first button function, put a Select(theOtherButtonName)  This will cause the formula to execute and then it will select the other Button automatically.

 

_____________________________________________________________________________________
Digging it? - Click on the Thumbs Up below. Solved your problem? - Click on Accept as Solution below. Others seeking the same answers will be happy you did.
Check out my PowerApps Videos too! And, follow me on Twitter @RandyHayes

Really want to show your appreciation? Buy Me A Cup Of Coffee!

View solution in original post

joef
Continued Contributor
Continued Contributor

Hi @RandyHayes ,

Thank you for this!!  I was able to accomplish serializing the functions with one collect and 2 patches.  

 

Thanks for your help,

Joe

Helpful resources

Announcements
PA_User Group Leader_768x460.jpg

Manage your user group events

Check out the News & Announcements to learn more.

Power Query PA Forum 768x460.png

Check it out!

Did you know that you can visit the Power Query Forum in Power BI and now Power Apps

Carousel 2021 Release Wave 2 Plan 768x460.jpg

2021 Release Wave 2 Plan

Power Platform release plan for the 2021 release wave 2 describes all new features releasing from October 2021 through March 2022.

PowerPlatform 768x460.png

Microsoft Learn

Check out our new Discover Your Career Path blog post series and get all the details.

Users online (1,133)