recursionnestedpower-automatemerging-data

Is there a simple Power Automate method of recursively working through an entire OneDrive file structure without the limits of nesting?


I'm trying to create a Power Automate Flow which, essentially recursively trawls through a OneDrive file structure (many layers deep) without the limiting factor of only being able to nest a maximum of 8 'For Each' loops.

I'm sure there's a better way to design my flow but I'm not sure what actions to use except loops. I've seen several people suggest using switches instead but I'm unsure of how this would work.

The overall purpose of the trawling is to pickup .pdf files at (usually) the deepest layer (maybe 10 deep), and merge all in each folder into a single document.

I've tried nesting 'For each' actions but was not aware that there was a limit on this. I'm unsure whether there is a workaround to this, or whether I can use a differently structured approach to merge all these files.


Solution

  • The way of doing this in a classic programming environment would be to use recursion, however, I tried that and to say it doesn't perform is a massive understatement. No matter what I did, it just didn't work out.

    So rather than having a process where it calls itself recursively, I took an approach of traversing down levels of the folder structures and extracting each folder out and processing them until no new folders are found.

    The only annoying thing about this approach is that the files and folders are not organised in a nice (somewhat) sequential order, but, it does give you what you need given you can then just filter for the files you ultimately want, i.e. your PDF's.

    Depending on your file structure, this could take a while to run but, given time, it will finish.

    If it doesn't finish then you may need to find another approach and that approach will be a more conventional programming approach.

    This is the definition ...

    {
        "$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#",
        "contentVersion": "undefined",
        "parameters": {
            "$authentication": {
                "defaultValue": {},
                "type": "SecureObject"
            },
            "$connections": {
                "defaultValue": {},
                "type": "Object"
            }
        },
        "triggers": {
            "manual": {
                "metadata": {},
                "type": "Request",
                "kind": "Http",
                "inputs": {
                    "schema": {
                        "type": "object",
                        "properties": {
                            "folderId": {
                                "type": "string"
                            },
                            "files": {
                                "type": "array",
                                "items": {
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "triggerAuthenticationType": "All"
                }
            }
        },
        "actions": {
            "Initialize_Files_And_Folders": {
                "runAfter": {
                    "Initialize_Loop_Finished": [
                        "Succeeded"
                    ]
                },
                "type": "InitializeVariable",
                "inputs": {
                    "variables": [
                        {
                            "name": "Files And Folders",
                            "type": "array",
                            "value": "@triggerBody()?['files']"
                        }
                    ]
                }
            },
            "List_Files_In_Folder_(Root)": {
                "runAfter": {
                    "Initialize_Files_And_Folders": [
                        "Succeeded"
                    ]
                },
                "metadata": {
                    "6e202211-2856-4d17-9ded-5beb8b8626b0": "/"
                },
                "type": "OpenApiConnection",
                "inputs": {
                    "parameters": {
                        "id": "6e202211-2856-4d17-9ded-5beb8b8626b0"
                    },
                    "host": {
                        "apiId": "/providers/Microsoft.PowerApps/apis/shared_onedriveforbusiness",
                        "connectionName": "shared_onedriveforbusiness",
                        "operationId": "ListFolderV2"
                    },
                    "retryPolicy": {
                        "type": "none"
                    },
                    "authentication": "@parameters('$authentication')"
                },
                "runtimeConfiguration": {
                    "paginationPolicy": {
                        "minimumItemCount": 5000
                    }
                }
            },
            "Initialize_Loop_Finished": {
                "runAfter": {},
                "type": "InitializeVariable",
                "inputs": {
                    "variables": [
                        {
                            "name": "Loop Finished",
                            "type": "boolean",
                            "value": false
                        }
                    ]
                }
            },
            "Set_Files_And_Folders_(From_Root)": {
                "runAfter": {
                    "List_Files_In_Folder_(Root)": [
                        "Succeeded"
                    ]
                },
                "type": "SetVariable",
                "inputs": {
                    "name": "Files And Folders",
                    "value": "@outputs('List_Files_In_Folder_(Root)')?['body/value']"
                }
            },
            "Do_Until_Loop_Finished_EQ_True": {
                "actions": {
                    "If_New_Folders_Exist": {
                        "actions": {
                            "Set_Loop_Finished": {
                                "type": "SetVariable",
                                "inputs": {
                                    "name": "Loop Finished",
                                    "value": true
                                }
                            }
                        },
                        "runAfter": {
                            "For_Each_New_Folder_To_Process": [
                                "Succeeded"
                            ]
                        },
                        "else": {
                            "actions": {}
                        },
                        "expression": {
                            "or": [
                                {
                                    "equals": [
                                        "@length(variables('New Folder List'))",
                                        0
                                    ]
                                }
                            ]
                        },
                        "type": "If"
                    },
                    "For_Each_New_Folder_To_Process": {
                        "foreach": "@outputs('Compose_New_Folders_To_Process')",
                        "actions": {
                            "List_All_Files_In_A_Folder": {
                                "runAfter": {
                                    "Compose_Current_Folder_Item": [
                                        "Succeeded"
                                    ]
                                },
                                "type": "OpenApiConnection",
                                "inputs": {
                                    "parameters": {
                                        "id": "@outputs('Compose_Current_Folder_Item')['Id']"
                                    },
                                    "host": {
                                        "apiId": "/providers/Microsoft.PowerApps/apis/shared_onedriveforbusiness",
                                        "connectionName": "shared_onedriveforbusiness",
                                        "operationId": "ListFolderV2"
                                    },
                                    "authentication": "@parameters('$authentication')"
                                }
                            },
                            "Compose_Current_Folder_Item": {
                                "type": "Compose",
                                "inputs": "@item()"
                            },
                            "For_Each_New_File_And_Folder": {
                                "foreach": "@outputs('List_All_Files_In_A_Folder')?['body/value']",
                                "actions": {
                                    "Append_To_Files_And_Folders": {
                                        "type": "AppendToArrayVariable",
                                        "inputs": {
                                            "name": "Files And Folders",
                                            "value": "@item()"
                                        }
                                    },
                                    "Condition": {
                                        "actions": {
                                            "Append_To_New_Folders_List": {
                                                "type": "AppendToArrayVariable",
                                                "inputs": {
                                                    "name": "New Folder List",
                                                    "value": "@item()"
                                                }
                                            }
                                        },
                                        "runAfter": {
                                            "Append_To_Files_And_Folders": [
                                                "Succeeded"
                                            ]
                                        },
                                        "else": {
                                            "actions": {}
                                        },
                                        "expression": {
                                            "and": [
                                                {
                                                    "equals": [
                                                        "@item()['IsFolder']",
                                                        true
                                                    ]
                                                }
                                            ]
                                        },
                                        "type": "If"
                                    }
                                },
                                "runAfter": {
                                    "List_All_Files_In_A_Folder": [
                                        "Succeeded"
                                    ]
                                },
                                "type": "Foreach"
                            }
                        },
                        "runAfter": {
                            "Reset_New_Folder_List": [
                                "Succeeded"
                            ]
                        },
                        "type": "Foreach"
                    },
                    "Compose_New_Folders_To_Process": {
                        "type": "Compose",
                        "inputs": "@variables('New Folder List')"
                    },
                    "Reset_New_Folder_List": {
                        "runAfter": {
                            "Compose_New_Folders_To_Process": [
                                "Succeeded"
                            ]
                        },
                        "type": "SetVariable",
                        "inputs": {
                            "name": "New Folder List",
                            "value": []
                        }
                    }
                },
                "runAfter": {
                    "Initialize_New_Folder_List": [
                        "Succeeded"
                    ]
                },
                "expression": "@equals(variables('Loop Finished'),true)",
                "limit": {
                    "count": 5000,
                    "timeout": "PT660H"
                },
                "type": "Until"
            },
            "Initialize_New_Folder_List": {
                "runAfter": {
                    "Filter_For_Folders_Only_(From_Root)": [
                        "Succeeded"
                    ]
                },
                "type": "InitializeVariable",
                "inputs": {
                    "variables": [
                        {
                            "name": "New Folder List",
                            "type": "array",
                            "value": "@body('Filter_For_Folders_Only_(From_Root)')"
                        }
                    ]
                }
            },
            "Filter_For_Folders_Only_(From_Root)": {
                "runAfter": {
                    "Set_Files_And_Folders_(From_Root)": [
                        "Succeeded"
                    ]
                },
                "type": "Query",
                "inputs": {
                    "from": "@variables('Files And Folders')",
                    "where": "@equals(item()['IsFolder'],true)"
                }
            }
        }
    }
    

    Section 1

    enter image description here

    Section 2

    enter image description here

    Section 3

    enter image description here