Showing posts with label Export. Show all posts
Showing posts with label Export. Show all posts

Wednesday, September 21, 2022

Power Automate: Export To Excel For Dynamic View/Filter Selection In PowerApps

Hello Friends,

Welcome back with another post on Power Automate. We had already discussed about "Export To Excel" in our earlier posts. However, we are again going to discuss the same. This time, we are getting the data based upon the selection of View as well as filters applied in PowerApps. This post is also related to my previous two posts-
Let's start-
  1. Open the Power Automate maker portal and create a Instant cloud flow with trigger type as "PowerApps" and flow name as- "POC-DynamicExportToExcel".
  2. Now, we have 3 parameters to apply filter upon data-
    1. View Name
    2. Experience
    3. Free Text Search
  3. We will initialize 3 variables (using Initialize variable and value as Ask in PowerApps) that will communicate with PowerApps to provide these values to the flow-
  4. Variable1: ViewName
  5. Variable2: Experience
  6. Variable3: FreeTextSearch
  7. Now, we will define another variable named "strFilterCriteriaByViewName". This will be the first filter criteria.
  8. Keep saving your flow frequently.
  9. Here, we will use the same filter conditions as we applied in PowerApps. For that, we will apply a Switch-Case.
  10. Now, refer back to the previous post, where, we have defined the Views. Check the "Items" property of DataTable / Gallery.
  11. Please find below the function from PowerApps for ready reference.
    1. Switch(
          Dropdown_SelectView.SelectedText.ViewName,
          "All Employees",
          Filter(
              EmployeeInfo,
              Experience.Value in If(
                  Radio_SelectExperience.SelectedText.Experience = "All",
                  Experience.Value,
                  Radio_SelectExperience.SelectedText.Experience
              ) && (Trim(TextInput_Search.Text) in 'First Name' || Trim(TextInput_Search.Text) in 'Last Name' || 
      Trim(TextInput_Search.Text) in Designation.Value || Trim(TextInput_Search.Text) in Experience.Value || 
      Upper(Title) = Upper(Trim(TextInput_Search.Text))) || Text(
                  'Date Of Joining',
                  "m/d/yyyy",
                  "en-US"
              ) = Text(
                  Trim(TextInput_Search.Text),
                  "m/d/yyyy",
                  "en-US"
              ) || Text(Trim(Salary)) = Trim(TextInput_Search.Text)
          ),
          "Software Engineer",
          Filter(
              EmployeeInfo,
              "Software Engineer" in Designation.Value,
              Experience.Value in If(
                  Radio_SelectExperience.SelectedText.Experience = "All",
                  Experience.Value,
                  Radio_SelectExperience.SelectedText.Experience
              ) && (Trim(TextInput_Search.Text) in 'First Name' || Trim(TextInput_Search.Text) in 'Last Name' || 
      Trim(TextInput_Search.Text) in Designation.Value || Trim(TextInput_Search.Text) in Experience.Value || 
      Upper(Title) = Upper(Trim(TextInput_Search.Text))) || Text(
                  'Date Of Joining',
                  "m/d/yyyy",
                  "en-US"
              ) = Text(
                  Trim(TextInput_Search.Text),
                  "m/d/yyyy",
                  "en-US"
              ) || Text(Trim(Salary)) = Trim(TextInput_Search.Text)
          ),
          "Module Lead",
          Filter(
              EmployeeInfo,
              "Module Lead" in Designation.Value,
              Experience.Value in If(
                  Radio_SelectExperience.SelectedText.Experience = "All",
                  Experience.Value,
                  Radio_SelectExperience.SelectedText.Experience
              ) && (Trim(TextInput_Search.Text) in 'First Name' || Trim(TextInput_Search.Text) in 'Last Name' || 
      Trim(TextInput_Search.Text) in Designation.Value || Trim(TextInput_Search.Text) in Experience.Value || 
      Upper(Title) = Upper(Trim(TextInput_Search.Text))) || Text(
                  'Date Of Joining',
                  "m/d/yyyy",
                  "en-US"
              ) = Text(
                  Trim(TextInput_Search.Text),
                  "m/d/yyyy",
                  "en-US"
              ) || Text(Trim(Salary)) = Trim(TextInput_Search.Text)
          ),
          "Project Manager",
          Filter(
              EmployeeInfo,
              "Project Manager" in Designation.Value,
              Experience.Value in If(
                  Radio_SelectExperience.SelectedText.Experience = "All",
                  Experience.Value,
                  Radio_SelectExperience.SelectedText.Experience
              ) && (Trim(TextInput_Search.Text) in 'First Name' || Trim(TextInput_Search.Text) in 'Last Name' || 
      Trim(TextInput_Search.Text) in Designation.Value || Trim(TextInput_Search.Text) in Experience.Value || 
      Upper(Title) = Upper(Trim(TextInput_Search.Text))) || Text(
                  'Date Of Joining',
                  "m/d/yyyy",
                  "en-US"
              ) = Text(
                  Trim(TextInput_Search.Text),
                  "m/d/yyyy",
                  "en-US"
              ) || Text(Trim(Salary)) = Trim(TextInput_Search.Text)
          ),
          "Program Manager",
          Filter(
              EmployeeInfo,
              "Program Manager" in Designation.Value,
              Experience.Value in If(
                  Radio_SelectExperience.SelectedText.Experience = "All",
                  Experience.Value,
                  Radio_SelectExperience.SelectedText.Experience
              ) && (Trim(TextInput_Search.Text) in 'First Name' || Trim(TextInput_Search.Text) in 'Last Name' || 
      Trim(TextInput_Search.Text) in Designation.Value || Trim(TextInput_Search.Text) in Experience.Value || 
      Upper(Title) = Upper(Trim(TextInput_Search.Text))) || Text(
                  'Date Of Joining',
                  "m/d/yyyy",
                  "en-US"
              ) = Text(
                  Trim(TextInput_Search.Text),
                  "m/d/yyyy",
                  "en-US"
              ) || Text(Trim(Salary)) = Trim(TextInput_Search.Text)
          )
      )
  12. The same we are going to implement in flow. The primary filter is upon Designation-
    1. All Employees - No Filter Criteria
    2. Software Engineer - Filter Designation by "Software Engineer"
    3. Module Lead - Filter Designation by "Module Lead"
    4. Project Manager - Filter Designation by "Project Manager"
    5. Program Manager - Filter Designation by "Program Manager"
  13. We had completed first part.
  14. Now, we will fetch all such items from SharePoint list that matches this filter criteria. For that, we have to define three variables then use "Do Until" action to perform the activity.
  15. Now, we will use Do-Until action to fetch the items.
  16. Get Items Using ItemID variable & FilterCriteria
  17. Select the required fields
  18. Join the output with arrAllItems array
  19. Update the variable arrAllItems with the previous action result
  20. Update the intItemID with the last ItemID from the output of GetItems action. If GetItems action output is NULL, then assign it with 0.
  21. Now, check if the output of GetItems is empty or not. If empty, set the blnIsEmpty to true otherwise false.
  22. Now, we will set the "Configure Run After" condition for the action. For this, click on ellipses (3 dots) ahead to the Set blnIsEmpty action and choose "Configure run after".
  23. You will find that "is successful" is by default selected. Select "is failed" as well and click on Done.
  24.  
  25. This completes the second part.
  26. Now, the third part is to filter data by Experience choice. If Experience selected by user is not "All", then we have to apply additional filter of Experience upon the outcome of Do-Until action.
  27. Before that, we will execute this flow and get the schema so that we can parse the output to JSON as we cannot apply filter upon array.
  28. Then use Parse JSON action.
  29. Now add a "Condition" action and check if Experience is not selected as "All". If true, apply "Filter" action on output of ParseJSON action and set the output again to arrAllItems variable.
  30. This completes third part.
  31. Now, the fourth part is to apply filter using free text search.
  32. This is the main section. Here we will apply filter on each field separately and capture the outcome in an individual array.
  33. After then we will combine all these outcomes in single array. Thus, unique results will be obtained.
  34. As we can see that we had applied free text search upon all 7 fields. Thus, we have to create 7 array variables and then apply filter one by one.
  35. First define the arrays.
  36. Now, check if the FreeTextSearch variable is having any value or not. If Yes, then start filtering one by one.
  37. Apply Parse JSON upon arrAllItems so that filter can be applied.
  38. We will check if the FreeTextSearch value is contained (unless specified) in the item respective field.
  39. Filter for Title field.
  40. Remember, when you are applying a filter, you have to use the output (body) of Parse JSON action. When you are updating the respective array with the output of respective filter, then you have to use the output (body) of Filter action.
  41. Filter for First Name field.
  42. Remember, when you are applying a filter, you have to use the output (body) of Parse JSON action. When you are updating the respective array with the output of respective filter, then you have to use the output (body) of Filter action.
  43. Filter for Last Name field.
  44. Remember, when you are applying a filter, you have to use the output (body) of Parse JSON action. When you are updating the respective array with the output of respective filter, then you have to use the output (body) of Filter action.
  45. Filter for Date Of Joining field. Here, we will first format the date to "M/d/yyyy" format and then check if both are equal. Additionally, here we will use the "Configure run after" as well because in case the FreeTextSearch is not a date then the formatDateTime will throw an error and our further processing will get failed. So, we have to handle that case.
  46. Remember, when you are applying a filter, you have to use the output (body) of Parse JSON action. When you are updating the respective array with the output of respective filter, then you have to use the output (body) of Filter action.
  47. Filter for Salary field.
  48. Remember, when you are applying a filter, you have to use the output (body) of Parse JSON action. When you are updating the respective array with the output of respective filter, then you have to use the output (body) of Filter action.
  49. Filter for Designation field.
  50. Remember, when you are applying a filter, you have to use the output (body) of Parse JSON action. When you are updating the respective array with the output of respective filter, then you have to use the output (body) of Filter action.
  51. Filter for Experience field. However, we can avoid filter condition upon Experience as this is already present upon screen in the form of Radio Choice.
  52. Remember, when you are applying a filter, you have to use the output (body) of Parse JSON action. When you are updating the respective array with the output of respective filter, then you have to use the output (body) of Filter action.
  53. Now, we have individual filter results for each FreeText filter criteria. We have to combine these outcomes. Thus, we will now use Compose action to apply union function to combine these outcomes. The benefit of union is that it takes unique items. If any item is found duplicate, it keeps only one of those item instances. 
  54. Now, set the output of this Compose action to arrAllItems.
  55. This completes out fourth part.
  56. Now, the fifth & final part. Here, we will export this output to Excel. For this, you may refer my earlier blogs using OneDrive as well as SharePoint library.
    1. Using One Drive-
      1. Export To Excel Using Power Automate
    2. Using SharePoint Library-
      1. Power Automate: Export To Excel (SharePoint)
  57. This is how, we can Export data to excel.
With this, I am concluding this post.
Happy Coding !!!
Will see you again with some new topics.

Stay Safe !
Stay Healthy !

Tuesday, May 24, 2022

Power Automate: Export To Excel (SharePoint)

Hello Friends,
Welcome back with another post on Power Automate. Last year, we have learned about Export To Excel Using Power Automate where we have used OneDrive to store the excel template. Recently, someone asked me provide the same feature without using OneDrive. In short, their requirement was- whenever an item (request) is created in SharePoint list, the information is to be emailed in the form of Excel file to the user and the same excel file needs to be stored in a document library for future reference. Let's begin-
  1. Let's create a SharePoint list "TestList". It is having "Title" column by default.
  2. Below is the design of Excel template. It is having a table "Table1" with 2 columns "ID" & "Title".
  3. Below is the structure of document library "ExcelLibrary" where we will save the template and the files.
  4. The root library is "ExcelLibrary". It is having 2 nested folders -
    1. Template - It will hold the Excel template.
    2. DataFiles - It will be used to save the final excel files for each request.
  5. Upload the Excel template in "ExcelLibrary" >> "Template" folder as shown in above screenshot.
  6. Now, we will write the Power Automate Flow. Open the Power Automate Portal and click on "+ Create".
  7. Select "Automated cloud flow". Give flow a suitable name and choose the flow trigger as "When an item is created (SharePoint)".
  8. Select the Site Address and List Name. Here list name will be "TestList".
  9. Now, we will copy the excel template from Template folder to DataFiles folder. For this, we will choose "Copy file (SharePoint)" action.
  10. Select the Current Site Address, File to Copy (the excel template file), Destination Site Address (it will remain same as we are copying to same site), Destination Folder (ExcelLibrary >> DataFiles).
  11. Now the important point here is to select the course of action if another file is already there with same name. Here we will choose to Copy the file with new name. Basically, the flow will append an incremental number ahead to the file name and save. It will save us from replacing the existing file of another request.
  12. Save the flow and keep saving the flow at regular interval in order to save your precious efforts.
  13. Now, add another action to add row in excel file. For this choose the action name "Add a row into a table (Excel Online (Business))".
  14. Select the Location, Document Library.
  15. For File, select the "Id" property of "Copy file" action from dynamic expression.
  16. For Table, it will not show any table name because, you are providing the file dynamically. Therefore, choose "Enter custom value" and input "Table1". If you remember, you had added a table in Excel Template, if you check the same of this table, you will find it Table1. Otherwise, whatever be the table name, you have to put in here.
  17. Now, there will be another filed get displayed called "Row".
  18. As, all the values are dynamic in nature, therefore in design time, power automate is unable to fetch the schema of the table as well. Therefore, it allows us to provide the data to be inserted in JSON format.
  19. { 
      "ID": @{triggerOutputs()?['body/ID']},
      "Title": "@{triggerOutputs()?['body/Title']}"
    }
    
  20. The next step is to get the content of this file and send it through Email. Before that, we will add a delay of around 1 minute so that the writing of data gets completed in excel file.
  21. Now, add the Get file content (SharePoint).
  22. Select the Site Address. File Identifier will again picked from Copy file "Id" property.
  23. Now, send an email using "Send an email (V2) (Office 365 Outlook)" action.  
  24. Here, we can give the file name as per our wish. I had created a combination of "Created By Display Name" (replaced spaces by Underscore), suffixed by ItemID.
  25. concat(replace(triggerOutputs()?['body/Author/DisplayName'],' ','_'),'_',triggerOutputs()?['body/ID'],'.xlsx')
    
  26. Now, the attachment content will be mapped with the File Content property of Get file content action.
  27. Now the next step is to rename the copied file in DataFiles folder with same name we used in attachment. But that is not so easy because, the file copied and written content in it gets locked as we were editing (adding items in that file) the file. Therefore, the file will not get renamed.
  28. For this, we have to wait to get it unlocked. Here we will use "Do until" action. Let add the steps for it-
  29. Add "Initialize variable" action -
    1. Name: blnIsFileLocked
    2. Type: Boolean
    3. Value: true
  30. Add "Do until" action -
  31. Change the limits as shown below.
  32. Add "Delay" action and set count to 1 and unit to Minute.
  33. Now, we will try to rename the file. If the file is unlocked, it will get renamed otherwise, it will throw error. We have to handle the error carefully. For this, you may use the property "Configure run after".
  34. Add "Send an HTTP request to SharePoint" action.
  35. Fill up the required details. Here, we are using "ItemId" attribute to fetch the desired file.
  36. For Body section, again it will take JSON and the FileLeafRef property is set to the file name we had used earlier (without .xlsx).
  37. {'__metadata':{'type':'SP.Data.ExcelLibraryItem'},'FileLeafRef':'@{concat(replace(triggerOutputs()?['body/Author/DisplayName'],' ','_'),'_',triggerOutputs()?['body/ID'])}'}
    
  38. Add "Set variable" action and set the variable "blnIsFileLocked" to false.
  39. Now, we will set the "Configure run after" property for this action. Click on ellipses (marked in above screenshot) and choose "Configure run after".
  40. It will show the settings as above screenshot. By default, "is successful" is selected. This is what, we require. This action should only execute if the file get renamed means the HTTP request get executed successfully. Click on "Done".
  41. Now, add "Get file properties (SharePoint)" action to get the properties of the file. You may skip this step. I am adding this step to send another mail with the link of the excel file for future reference. For each step you have to set the "Configure run after" property (for "is successful")
  42. The last step is to add action "Send an email (V2)".
  43. The Item Link is set as-
  44. concat('<a href="',split(outputs('Get_file_properties')?['body/{Link}'],'?')[0],'">Item Link</a>')
    
  45. Set "Configure run after" for "is successful".
  46. At last, you may add "Terminate" action with Status as "Succeeded".
  47. Let's start testing.
  48. Add an item in TestList.
  49. As checked, file has been created in DataFiles folder with content as below.
  50. Now, we are waiting to get file renamed.
  51. Finally, the workflow got completed successfully. Let's see, if the file name has been changed. Yes, it's done.
  52. And the mails, I received are-
  53. This way, you can achieve the functionality.
With this, I am concluding this post.
Happy Coding !!!
Will see you again with some new topics.

Stay Safe !
Stay Healthy !