cancel
Showing results for 
Search instead for 
Did you mean: 
Reply
bkatz
Helper I
Helper I

Populating a new record with the field data from the last record submitted in SQL DB by that user

Relatively new to powerapps but I have created an app for doing site inspections (which I know is a common use) and I am incorporating mileage tracking into the app.  

 

Data is in SQL:  Table name : MileageTrackertoSQL which contains fields:

Starting_Mileage

Ending_Mileage

Starting_Location

Ending_Location

Date_and_Time

Username

ID  (Key)

Date_Created

 

In Powerapps I have a form which asks for all of these fields.  What I want is that when a user opens the form, the "Ending Location" from the most recent record (for that user) to populate the "Starting_Location" combobox default and the "Ending_Mileage" from the same record to populate the "Starting_Mileage" field text input default for the new record.  

 

I have tried to do it as a collection to collect each item from the Last record but it doesn't seem to be working because regardless of using First or Last I get the ID=1 record first.  I understand the delegation limits but if I sort by ID descending the record I want for each user should be in the top 500.  

 

When I use First or last (proceeding this) the top 5 shown are always the records starting with ID=1 instead of last record ID=499 (currently).  Just trying to get the most recent records into collection and then I want to filter by the "username" field by the logged in user using the Office365Users.MyProfile().DisplayName which matches the list of usernames. Or I could filter first and then pull the records, which ever is easiest from a processing perspective.  

 

I tried Onvisible for the form screen: 

ClearCollect(LastRecord, '[dbo].[MileageTrackertoSQL]')

 

Any help would be greatly appreciated.  

 

Thank you!

 

 

 

 

 

 

 

 

 

 

 

1 ACCEPTED SOLUTION

Accepted Solutions
v-xiaochen-msft
Community Support
Community Support

Hi @bkatz ,

 

The first() function does trigger a delegation warning.

However, when you have a lot of data, the first() function still works.

For example: when you have 3000 records, the last() function can only find the 2000th record due to delegation.

However, although the first() function has a delegation warning, it can still find the first record.

It's just a warning, it will not affect the performance of the application.

 

In addition, If you just want to eliminate this warning, you could try to use other methods instead of the first() function. Because the first() function has a delegate warning.

 

I think you could use max() function instead of first() function.

Its logic is:

1\ Use the filter() function to find all records of a certain user.

2\ Use the max function on the ID column. // find the max ID of a certain user

3\ Lookup the latest record by the max ID.

v-xiaochen-msft_0-1609987624461.png

 

 

For example:

LookUp(Filter('[dbo].[MileageTrackertoSQL]',Username=User().FullName),ID=Max(Filter('[dbo].[MileageTrackertoSQL]',Username=User().FullName),ID))

v-xiaochen-msft_1-1609987624464.png

 

 

However, user().fullname still has a delegation warning. Although it will not affect formula performance.

If you use Office365Users.MyProfile().DisplayName, It also has delegation warning.

Although the delegation warning for the first() function is gone, you still have other delegation warnings.

v-xiaochen-msft_2-1609987624465.png

 

 

Therefore, you don’t have to worry about delegation warnings, some functions will not affect the performance of your formulas.

 

Best Regards,

Wearsky

If my post helps, then please consider Accept it as the solution to help others. Thanks.

View solution in original post

11 REPLIES 11
v-xiaochen-msft
Community Support
Community Support

Hi @bkatz ,

 

Could you tell me:

  1. Do you use SQL Server ?
  2. What are the data types of these columns?
  3. Why did you put the data in the collection first? (Could the controls be directly associated with the data source instead of the collection?)
  4. Do you want to get the latest record?
  5. How many records do you have?

 

I assume:

1\ This is my hypothetical test columns. The ID column is the primary key and will increase by 1.

v-xiaochen-msft_0-1609312161842.png

 

 

2\ This is my test data

v-xiaochen-msft_1-1609312161843.png

 

 

I've made a test for your reference:

1\ Add a edit form and set its Datasource property to:

'[dbo].[MileageTrackertoSQL]'   // my table name

 

2\ Add an icon and set its onselect property to:

NewForm(Form1)  //  my edit form name

 

3\ Set the combo box control’s Items property to:

'[dbo].[MileageTrackertoSQL]'.Ending_Location

 

Set the combo box control’s DefaultSelectedItems property to:

Last('[dbo].[MileageTrackertoSQL]'.Ending_Location)

 

Set the “Starting_Location” card’s update property to:

ComboBox1.Selected.Ending_Location   // combobox1 is my combobox’s name

 

4\ Set the textinput control ’s Default property of “Starting_Mileage” to:

Last('[dbo].[MileageTrackertoSQL]').Ending_Mileage

 

5\ The Result is as follows:

III.gif

 

If my assumptions are incorrect, please provide more details.

 


Best Regards,
Wearsky
If my post helps, then please consider Accept it as the solution to help others. Thanks.

Thank you for the quick reply I've answered your questions below:

 

Could you tell me:

  1. Do you use SQL Server ?  yes
  2. What are the data types of these columns? The mileage columns are numeric(38,0), the locations are varchar(50), date and time is datetime, date created also datetime and ID is smallint.
  3. Why did you put the data in the collection first? (Could the controls be directly associated with the data source instead of the collection?) There is no need to do this, I just thought it might be an easy approach.  
  4. Do you want to get the latest record? As you mentioned elsewhere ID is my primary key and increments by one each time.  I want to get the "highest" ID number for that individual and return the details of that record.  
  5. How many records do you have? There will be a lot of records over time (certainly will exceed the 2000 threshold over the year).  There are ~20 people entering 6-7 entries a day so it won't take long to exceed the 2000.  If we sort by date created (latest) we should never be looking for something that is more than 100 records down.  

I will review the rest of your entry now but wanted to answer your questions in case it changes anything.  

 

I will experiment with what you have here but I think it will give me the last record regardless of who entered it and I do want to get that user's last entry details if possible. 

 

Also, while I do want the field to default to this entry I want the user to have the ability to change the entry to (in the case of location) my list of locations and (in the case of mileage) a different number (if for whatever reason they made a mistake previously or are entering records out of order).  I think for that to be the case the starting location and ending location "items" still need to be my location list which is currently: SortByColumns('[dbo].[SitesList]', "Name").Name

 

Thank you again!

For some reason my reply seems to have disappeared but I'll try to recreate it :

 

Could you tell me:

  1. Do you use SQL Server ?  Yes
  2. What are the data types of these columns?  

    Starting_Mileage numeric (38,0)

    Ending_Mileage numeric (38,0)

    Starting_Location varchar(50)

    Ending_Location varchar(50)

    Date_and_Time datetime

    Username varchar(50)

    ID  (Key)  smallint

    Date_Created datetime

  3. Why did you put the data in the collection first? (Could the controls be directly associated with the data source instead of the collection?) No need to do this, thought it would be easier.  
  4. Do you want to get the latest record?  I want the latest record by the username (logged in)
  5. How many records do you have? will be many records, ~20 people, 6-7 records per day 5 days a week.  If we start with a sort descending by ID number we should never be more than ~50 records down each time.  

 

I assume:

1\ This is my hypothetical test columns. The ID column is the primary key and will increase by 1.  Yes

 

I also noted in my previous reply that I want the default to be to the details of that most recent record by I still need the items and search items in the "locations" fields to be for my longer list of sites: SortByColumns('[dbo].[SitesList]', "Name").Name so that that if they don't want to use the last record's data they can change to the full list and for the mileage fields I want them to be able to change the number if they don't like the default number (sometimes they enter their records out of order so want them to be able to change them if need be.  

 

Thank you again for your assistance!

 

Brian

v-xiaochen-msft
Community Support
Community Support

Hi @bkatz ,

 

According to your description, I think you want to filter records based on username column. Then you want to fill the “Starting_Mileage” column and “Starting_Location” column by default.

The filled content is based on the Ending_Mileage column and Ending_Location column in the latest record.

In addition, you also have a gallery to display all the records of a certain user.

When the user does not want the default value, he can select a record in the gallery control, and this record will fill the “Starting_Mileage” and “Starting_Location” columns in the edit form.

Finally, the user can also enter the value by himself instead of selecting any record.

 

If my understanding above is wrong, please let me know.

 

What I am confused about is why you use the combo box control. It can only be used for selection, not for input. So I think textinput control is more suitable for “Starting_Location” column.( Maybe you have a collection of locations not mentioned?)

 

I also suggest you to use User().FullName function instead of Office365Users connector.

 

Finally, could you tell me what steps your app has performed? Where did you encounter difficulties?

It would be better if you can provide pictures and formulas.

Looking forward to your reply

 

Best Regards,

Wearsky

Answers below inline:  

 

According to your description, I think you want to filter records based on username column.  Correct Then you want to fill the “Starting_Mileage” column and “Starting_Location” column by default. Correct

The filled content is based on the Ending_Mileage column and Ending_Location column in the latest record. Correct

In addition, you also have a gallery to display all the records of a certain user. Correct

When the user does not want the default value, he can select a record in the gallery control, and this record will fill the “Starting_Mileage” and “Starting_Location” columns in the edit form. This part I'm not following, sorry.   I don't allow the users to edit a record once it is submitted.  When they open a new form on screen: AddMileageEntry and form name: EditformMileage I want it to pre-populate the fields with the data mentioned above as the default while allowing the user to change either if they want to alter the default.  

Finally, the user can also enter the value by himself instead of selecting any record. Shouldn't be any editing of previous records only option to "view" them for historical data.  Gallery is called BrowseGalleryMileage and uses for items: 

SortByColumns(Filter('[dbo].[MileageTrackertoSQL]','UserfilterinputMileageRecords(Invisible)'.Text in Name_SP_List),"Date_and_Time",Descending)

 

Then there is a text box which is hidden from the user but defaults to a variable: varusname 

When app starts I create 2 variables: Set(varuser, Office365Users.MyProfile().Id);Set(varusname, Office365Users.MyProfile().DisplayName)

 

If my understanding above is wrong, please let me know.  

 

What I am confused about is why you use the combo box control. It can only be used for selection, not for input. So I think textinput control is more suitable for “Starting_Location” column.( Maybe you have a collection of locations not mentioned?)  This assumption is correct, there are ~400 site locations in another table: SortByColumns('[dbo].[SitesList]', "Name").Name so if they don't want the last location as their new starting location I still need them to choose from this list. 

 

I also suggest you to use User().FullName function instead of Office365Users connector. This is interesting, is there a reason for this?  Even when using the office365users connector data in a variable?  Currently when a new record is created there is a hidden field which uses the varusname variable to populate each record so this is where I'm trying to match between current user and records.  Is there a benefit to using the User().FullName?  

 

Finally, could you tell me what steps your app has performed? Where did you encounter difficulties?   Hopefully that helps describe the current state.  I think your solution is close, I just need to first filter the records by the user and then pull the data you included into the default of my combobox, correct?  I'm not certain how to combine the filter with the "Last" commands you have above.  I imagine it is filter first and then last.  Do I need to sort to make sure I'm looking at the most recent records to allow for more than 2000 to be searched or are Last and Filter both delegable together so it doesn't matter?  I attached an image of the form.  

It would be better if you can provide pictures and formulas.

Looking forward to your reply

v-xiaochen-msft
Community Support
Community Support

Hi @bkatz ,

 

Firstly, Both Office365Users.MyProfile().DisplayName and User().FullName can be used. They are equal. But User().FullName is a built-in function of canvas, which is more convenient to use. You could choose what you like.

v-xiaochen-msft_0-1609747024658.png

 

 

Secondly, you could use the filter() function first, then use the last() function.  (If a user has more than 2000 records, then you could try to use the filter() function→sortbycolumns (descending) function→first() function)

 

Thirdly, I've made a test for your reference:

1\ This is my data structure

v-xiaochen-msft_1-1609747024660.png

 

 

2\ This is my test location table .

v-xiaochen-msft_2-1609747024660.png

 

 

3\ This is my test data.

v-xiaochen-msft_3-1609747024661.png

 

 

4\ Add an edit form like the picture: Its DataSource property is : '[dbo].[MileageTrackertoSQL]'

v-xiaochen-msft_4-1609747024664.png

 

 

Remove the textinput control of ‘Starting_Location’ card and add a dropdown control.

Set the dropdown control’s Items property to:

SortByColumns('[dbo].[SitesList]',"Name")

 

Set the dropdown control’s Default property to:

First(SortByColumns((Filter('[dbo].[MileageTrackertoSQL]',Username=User().FullName)),"ID",Descending)).Ending_Location

 

Set ‘Starting_Location’ card’s Update property to:

Dropdown1.Selected.Name         //Dropdown1 is my dropdown control’s name

 

Set Default property of textinput control of Starting_Mileage’s card to:

First(SortByColumns((Filter('[dbo].[MileageTrackertoSQL]',Username=User().FullName)),"ID",Descending)).Ending_Mileage

 

Remove the textinput control of Ending_Location’ card and add a dropdown control.

Set the dropdown control’s Items property to:

SortByColumns('[dbo].[SitesList]',"Name")

 

Set ‘Ending_Location’ card’s Update property to:

Dropdown2.Selected.Name         //Dropdown2 is my dropdown control’s name

 

Set the Default property of the textinput control of the Username card to:

User().FullName

 

5\ Add an icon and set its onselect property to:

NewForm(Form2)

 

Add an icon and set its onselect property to:

SubmitForm(Form2)

 

6\ Add a gallery control and set its Items property to:

Filter('[dbo].[MileageTrackertoSQL]',Username=User().FullName)   // Modify the gallery control according to your needs

 

7\ The result is as follows:

v-xiaochen-msft_5-1609747024667.png

 

Best Regards,

Wearsky

If my post helps, then please consider Accept it as the solution to help others. Thanks.

Thank you.  I went through the listed steps and I do get delegation warnings in both fields.  I've experimented with the ordering of the operations the way you mentioned but I haven't found the correct ordering based on what you mentioned here: Secondly, you could use the filter() function first, then use the last() function.  (If a user has more than 2000 records, then you could try to use the filter() function→sortbycolumns (descending) function→first() function)

v-xiaochen-msft
Community Support
Community Support

Hi @bkatz ,

 

Could you tell me:

Where did you encounter the problem when you try my solution?

 

Did you say that you encountered a delegation warning in the formula below?

v-xiaochen-msft_0-1609903882944.png

 

If so, you don’t have to worry, it does not affect your app.

If not, please tell me where your application reported an error.

 

Best Regards,

Wearsky

If my post helps, then please consider Accept it as the solution to help others. Thanks.

I found the error which was that I had a combobox and not a drop down, when I swapped those it seems to have worked.  I am still getting delegation warnings, but are you saying that won't be an issue with this setup?  Is there a way to change the syntax to avoid the warning?  I think it is the First() that is saying isn't supported by the SQL connector.  I think we're really close just prefer to get to a place with no warnings.  Thank you again for helping me get this far.  

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.

R2 (Green) 768 x 460px.png

Microsoft Dynamics 365 & Power Platform User Professionals

DynamicsCon is a FREE, 4 half-day virtual learning experience for 11,000+ Microsoft Business Application users and professionals.

Users online (1,625)