cancel
Showing results for 
Search instead for 
Did you mean: 
Reply
jaipalambati
Frequent Visitor

Export CSV with custom rows

Hello community, I am trying to generate a CSV using Flow. I have joined my data using ID's. 

Schema as below:

[{
"DCQ":2,

"Export_Items":{
"Title":"AG-P-Triangle-01-2-F-2",
"minDQ":6,
"trancheCommodityBasePrice":6,
"trancheDCQ":6,
"trancheEndDate":"2024-01-10",
"trancheID":1,
"trancheMDQ":6,
"trancheStartDate":"2024-01-04"
},"MDQ":2,
"Title":"AG-P-Triangle-01-2-F-2",
"clientName":"Triangle",
"commodityBasePrice":2,
"endDate":"2024-02-02",
"startDate":"2024-01-02",
"transportCost":2
}
]

 

Is it possible to write highlighted data as a new row?

For example:

DCQMDQminDQTitleclientNamecommodityBasePriceendDatestartDatetransportCosttrancheId
22 nullAG-P-Triangle-01-2-F-2Triangle22/02/20242/01/20242null
666AG-P-Triangle-01-2-F-2null610/01/20244/01/2024null1

 

The second row is from the "Export_Items" object, mapping them to headers.

 

Please share your ideas on this.TIA 

15 REPLIES 15

I can't understand your example.
Can you use colors to show value mapping from JSON to table?

@Chriddle , sorry for confusion. It is not about the color. I just highlighted the text.

 

I want to export a CSV, the first row of the CSV must be the text in black color as it is my Main Table,

The second row of the CSV must be in red as it is my Child table.

 

To be clear, I have 2 tables, I joined them using MainTable.ID = ChildTable.parentID

Hence I generated the Json data as I mentioned in my question.

Hi, @jaipalambati, you can achieve what you're after with this:

 

Split The Export and Non-Export Data And Re-join

I have represented your data in the Compose action named 'array' at the start here, obviously you will need to refer to your appropriately named resource.

Clipboard_01-30-2024_02.png

 

SelectNonExport

Here's the expression in the 'Map' value for the 'SelectNonExport' Select action. Be sure that the Map field is switched to the 'text' entry method by tapping the little pen to the right:

 

addProperty(
    addProperty(
        removeProperty(
            removeProperty(
                item(), 
                'clientName'
            ), 
            'Export_Items'
        ), 
        'minDQ', 
        null
    ), 
    'trancheID', 
    null
)

 

 

FilterHasExportItemsValue

Before the 'SelectExports' Select action you will note that I performed a belt and braces check to ensure that the items actually have values in that specific key.

 

Whilst you may wish to omit this step for brevity it is there none-the-less, and the condition in the 'FilterHasExportItemsValue' Filter action is:

 

@not(equals(item()?['Export_Items'], null))

 

 

SelectExports

This Select action uses the 'text' mode (as previous) to ensure that values are properly added, but you should be OK in the normal view just adding the fields. This is the contents of that 'Map' if you wish to paste it in:

 

{
    "DCQ": @{item()?['Export_Items/trancheDCQ']},
    "minDQ": @{item()?['Export_Items/minDQ']},
    "MDQ": @{item()?['Export_Items/trancheMDQ']},
    "Title": "@{item()?['Export_Items/Title']}",
    "commodityBasePrice": @{item()?['Export_Items/trancheCommodityBasePrice']},
    "endDate": "@{item()?['Export_Items/trancheEndDate']}",
    "startDate": "@{item()?['Export_Items/trancheStartDate']}",
    "transportCost": @{null},
    "trancheID": @{item()?['Export_Items/trancheID']}
}

 

 

Create CSV table

Then you use a union to join the two data sets as the source 'From' value for the final Create CSV table creation action:

 

union(
    body('SelectNonExport'), 
    body('SelectExports')
)

 

 

Result

It should all finally look like this:

csv_vers.png

 

Here that is in an HTML table for clarity:

html_vers.png

Or just create the whole array from scratch:

Chriddle_0-1706620169532.png

Compose:

first(outputs('Json'))

Create HTML table:

[
	{
		"DCQ": @{outputs('Compose')?['DCQ']},
		"MDQ": @{outputs('Compose')?['MDQ']},
		"minDQ": null,
		"Title": @{outputs('Compose')?['Title']},
		"clientName": @{outputs('Compose')?['clientName']},
		"commodityBasePrice": @{outputs('Compose')?['commodityBasePrice']},
		"endDate": @{outputs('Compose')?['endDate']},
		"startDate": @{outputs('Compose')?['startDate']},
		"transportCost": @{outputs('Compose')?['transportCost']},
		"trancheId": null
	},
	{
		"DCQ": @{outputs('Compose')?['Export_Items']?['trancheDCQ']},
		"MDQ": @{outputs('Compose')?['Export_Items']?['trancheMDQ']},
		"minDQ": @{outputs('Compose')?['Export_Items']?['minDQ']},
		"Title": @{outputs('Compose')?['Export_Items']?['Title']},
		"clientName": null,
		"commodityBasePrice": @{outputs('Compose')?['Export_Items']?['trancheCommodityBasePrice']},
		"endDate": @{outputs('Compose')?['Export_Items']?['trancheEndDate']},
		"startDate": @{outputs('Compose')?['Export_Items']?['trancheStartDate']},
		"transportCost": null,
		"trancheId": @{outputs('Compose')?['Export_Items']?['trancheID']}
	}
]

Or with a little less writing work

Chriddle_1-1706622141674.png

Table From:

 

 

createArray(
	removeProperty(
		first(outputs('Json')),
		'Export_Items'
	),
	json(
		replace(
			string(first(outputs('Json'))?['Export_Items']),
			'tranche',
			''
		)
	)
)

 

 

 

 

@Chriddle  life saver..! This is a great solution. 

Just another query, how can I do this if I have multiple records? 

I just mentioned only one record in my question.

 

jaipalambati_0-1706661212408.png

here is my flow. 

ParseJson: my schema

Compose : outputs('Parse_JSON')

HTML table: query you have written in your solution ( with custom columns)

I am getting null values in the output 

 

jaipalambati_1-1706661414088.png

 

 

Any ideas on this?

@eliotcole  thank you for the solution. This works but I am afraid of how this works if I have multiple records? 

 

For Example:

1st item has 2 child items

2nd item has 3 child items

 

Will they join correctly with "Union"

 

I worked on one of those solutions but that didn't join properly.

They should work just fine, that's how it was designed, @jaipalambati 🙂 ... why not give it a try?

 


@jaipalambati wrote:

@eliotcole  thank you for the solution. This works but I am afraid of how this works if I have multiple records? 

 

For Example:

1st item has 2 child items

2nd item has 3 child items

 

Will they join correctly with "Union"

 

I worked on one of those solutions but that didn't join properly.


Basically, you obviously ignore my action named 'array' ... and the two actions after that are filtering YOUR array ... the one on the left grabs all the items without their 'Exports' data ... the one on the right grabs only the exports data for those that have them.

 

The union() of the two will remove any duplicates so that you only have the unique entries for both. Pretty much everything you need is above to just paste into the right fields. Just ensure that the 'From' fields of the SelectNonExport and the FilterHasExportItemsValue have your source in there. 👍

 

( if you would have included screenshots of your flow as embedded images - not attached - in the original question I would have given you something to simply paste into your flow 🙂 )

Can you provide an example of a JSON with multiple records?

Good point, @Chriddle ... @jaipalambati your original example shows the 'export' as a single item. Is it a property that can be either a single item or an array of items?


@Chriddle wrote:

Can you provide an example of a JSON with multiple records?


So if export items is always going to be presented as it *could* have either a single entry or multiples, this would be good information to have.

 

If you have just made an oopsie, and it was supposed to look like the code in the below spoiler, then I totally understand, and I will amend my solution accordingly.

Spoiler
[
	{
		"DCQ": 2,
		"Export_Items": [
			{
				"Title": "AG-P-Triangle-01-2-F-2",
				"minDQ": 6,
				"trancheCommodityBasePrice": 6,
				"trancheDCQ": 6,
				"trancheEndDate": "2024-01-10",
				"trancheID": 1,
				"trancheMDQ": 6,
				"trancheStartDate": "2024-01-04"
			}
		],
		"MDQ": 2,
		"Title": "AG-P-Triangle-01-2-F-2",
		"clientName": "Triangle",
		"commodityBasePrice": 2,
		"endDate": "2024-02-02",
		"startDate": "2024-01-02",
		"transportCost": 2
	}
]

 @Chriddle & @eliotcole  here you go

[{
"DCQ":1,
"Export_Items":{
"Title":"AG-S--1-AA-1",
"minDQ":2,
"trancheCommodityBasePrice":2,
"trancheDCQ":2,
"trancheEndDate":"2024-01-11",
"trancheID":1,
"trancheMDQ":2,
"trancheStartDate":"2024-01-09"
},
"MDQ":1,
"Title":"AG-S--1-AA-1",
"clientName":"Agnew",
"commodityBasePrice":1.2,
"endDate":"2024-01-31",
"startDate":"2024-01-01",
"transportCost":1,
},{
"DCQ":2,
"Export_Items":{
"Title":"AG-P-Triangle-01-2-F-2",
"minDQ":2,
"trancheCommodityBasePrice":2,
"trancheDCQ":2,
"trancheEndDate":"2024-01-10",
"trancheID":1,
"trancheMDQ":2,
"trancheStartDate":"2024-01-04"
},
"MDQ":2,
"Title":"AG-P-Triangle-01-2-F-2",
"clientName":"Triangle",
"commodityBasePrice":2,
"endDate":"2024-02-02",
"startDate":"2024-01-02",
"transportCost":2
}, {
"DCQ":7,
"Export_Items":null,
"MDQ":7,
"Title":"AG-P-Triangle-01-7-AA-7",
"clientName":"Triangle",
"commodityBasePrice":7,
"endDate":"2024-01-25",
"startDate":"2024-01-17",
"transportCost":7,
}]

OK, @jaipalambati , that's great, then ... as long as the Export_Items field never responds with a value that looks like the following, then my solution will work perfectly.

[
	{
		"DCQ": 1,
		"Export_Items": [
			{
				"Title": "AG-S--1-AA-1",
				"minDQ": 2,
				"trancheCommodityBasePrice": 2,
				"trancheDCQ": 2,
				"trancheEndDate": "2024-01-11",
				"trancheID": 1,
				"trancheMDQ": 2,
				"trancheStartDate": "2024-01-09"
			},
			{
				"Title": "AG-P-Triangle-01-2-F-2",
				"minDQ": 2,
				"trancheCommodityBasePrice": 2,
				"trancheDCQ": 2,
				"trancheEndDate": "2024-01-10",
				"trancheID": 1,
				"trancheMDQ": 2,
				"trancheStartDate": "2024-01-04"
			}
		],
		"MDQ": 1,
		"Title": "AG-S--1-AA-1",
		"clientName": "Agnew",
		"commodityBasePrice": 1.2,
		"endDate": "2024-01-31",
		"startDate": "2024-01-01",
		"transportCost": 1
	}, ...
]

Chriddle_0-1706710721420.png

Compose

The original array

Spoiler
[
  {
    "DCQ": 1,
    "Export_Items": {
      "Title": "AG-S--1-AA-1",
      "minDQ": 2,
      "trancheCommodityBasePrice": 2,
      "trancheDCQ": 2,
      "trancheEndDate": "2024-01-11",
      "trancheID": 1,
      "trancheMDQ": 2,
      "trancheStartDate": "2024-01-09"
    },
    "MDQ": 1,
    "Title": "AG-S--1-AA-1",
    "clientName": "Agnew",
    "commodityBasePrice": 1.2,
    "endDate": "2024-01-31",
    "startDate": "2024-01-01",
    "transportCost": 1
  },
  {
    "DCQ": 2,
    "Export_Items": {
      "Title": "AG-P-Triangle-01-2-F-2",
      "minDQ": 2,
      "trancheCommodityBasePrice": 2,
      "trancheDCQ": 2,
      "trancheEndDate": "2024-01-10",
      "trancheID": 1,
      "trancheMDQ": 2,
      "trancheStartDate": "2024-01-04"
    },
    "MDQ": 2,
    "Title": "AG-P-Triangle-01-2-F-2",
    "clientName": "Triangle",
    "commodityBasePrice": 2,
    "endDate": "2024-02-02",
    "startDate": "2024-01-02",
    "transportCost": 2
  },
  {
    "DCQ": 7,
    "Export_Items": null,
    "MDQ": 7,
    "Title": "AG-P-Triangle-01-7-AA-7",
    "clientName": "Triangle",
    "commodityBasePrice": 7,
    "endDate": "2024-01-25",
    "startDate": "2024-01-17",
    "transportCost": 7
  }
]

Select

Basically the same expression as above, creates the 2 items

From

 

outputs('Compose')

 

Map

 

createArray(
	removeProperty(
		item(),
		'Export_Items'
	),
	json(
		replace(
			string(item()?['Export_Items']),
			'tranche',
			''
		)
	)
)

 

 

Select 2

Since Select made an array of 2 items for each item in the original array, flatening the array is necessary

From

 

xpath(
    xml(json(concat('{"Root":{"Item":', body('Select'),'}}'))),
    '/Root/Item/Item'
)

 

Map

 

json(item())['Item']

 

 

Filter

Remove the items that are created based on "Export_Items": null

From

 

body('Select_2')

 

Filter

item() is not equal to null

 

Coincidentally, @Chriddle, I was just improving my solution with an xpath(), too! 😅

 

Split Exports & NonExports Then Union() - Improved

This does exactly the same as my previous answer, @jaipalambati, but this will ensure that each item does not care about whether the Export_items value is an array or an object.

Flow - Design.png

 

You can put this straight into your flow by copying the code in the below spoiler and pasting it into your own.

Spoiler
{"id":"bd5aed05-bd91-4f00-93c1-be7054e02dc3","brandColor":"#8C3900","connectionReferences":{},"connectorDisplayName":"Control","icon":"data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMzIiIGhlaWdodD0iMzIiIHZlcnNpb249IjEuMSIgdmlld0JveD0iMCAwIDMyIDMyIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPg0KIDxwYXRoIGQ9Im0wIDBoMzJ2MzJoLTMyeiIgZmlsbD0iIzhDMzkwMCIvPg0KIDxwYXRoIGQ9Im04IDEwaDE2djEyaC0xNnptMTUgMTF2LTEwaC0xNHYxMHptLTItOHY2aC0xMHYtNnptLTEgNXYtNGgtOHY0eiIgZmlsbD0iI2ZmZiIvPg0KPC9zdmc+DQo=","isTrigger":false,"operationName":"ScopeFlattenArrays","operationDefinition":{"type":"Scope","actions":{"SelectNonExport":{"type":"Select","inputs":{"from":"@body('SelectAddExportType')","select":"@addProperty(\r\n\taddProperty(\r\n\t\tremoveProperty(\r\n\t\t\tremoveProperty(\r\n\t\t\t\tremoveProperty(\r\n\t\t\t\t\titem(), \r\n\t\t\t\t\t'clientName'\r\n\t\t\t\t), \r\n\t\t\t\t'Export_Items'\r\n\t\t\t), \r\n\t\t\t'exportItemsStatus'\r\n\t\t), \r\n\t\t'minDQ', \r\n\t\tnull\r\n\t),\r\n\t'trancheID',\r\n\tnull\r\n)"},"runAfter":{"SelectAddExportType":["Succeeded"]},"description":"This removes information you do not want and adds the columns unused from exports - addProperty(addProperty(removeProperty(removeProperty(removeProperty(item(), 'clientName'), 'Export_Items'), 'exportItemsStatus'), 'minDQ', null), 'trancheID', null)","metadata":{"operationMetadataId":"7bd3a248-ea40-4ff3-9f64-941e86a546ed"}},"FilterHasExportItemsValue":{"type":"Query","inputs":{"from":"@body('SelectAddExportType')","where":"@or(equals(item()?['exportItemsStatus'], 'array'), equals(item()?['exportItemsStatus'], 'object'))"},"runAfter":{"SelectAddExportType":["Succeeded"]},"description":"This checks whether or not the item is either an array or an object and if it is either includes it - @or(equals(item()?['exportItemsStatus'], 'array'), equals(item()?['exportItemsStatus'], 'object'))","metadata":{"operationMetadataId":"8956c5a1-c78e-48ba-ac5d-d087d7679ac9"}},"SelectExports":{"type":"Select","inputs":{"from":"@xpath(\r\n    xml(\r\n        json(\r\n            concat(\r\n                '{\"r\": { \"c\":', \r\n                string(body('FilterHasExportItemsValue')), \r\n                '}}'\r\n            )\r\n        )\r\n    ),\r\n    '/r/c/Export_Items'\r\n)","select":{"DCQ":"@int(json(item())?['Export_Items/trancheDCQ'])","minDQ":"@int(json(item())?['Export_Items/minDQ'])","MDQ":"@int(json(item())?['Export_Items/trancheMDQ'])","Title":"@json(item())?['Export_Items/Title']","commodityBasePrice":"@int(json(item())?['Export_Items/trancheCommodityBasePrice'])","endDate":"@json(item())?['Export_Items/trancheEndDate']","startDate":"@json(item())?['Export_Items/trancheStartDate']","transportCost":"@null","trancheID":"@int(json(item())?['Export_Items/trancheID'])"}},"runAfter":{"FilterHasExportItemsValue":["Succeeded"]},"description":"This formats the filtered items from JSON to XML and flattens to only Export_items then the Map expressions translate back to JSON - xpath(xml(json(concat('{\"r\": { \"c\":', string(body('FilterHasExportItemsValue')), '}}'))), '/r/c/Export_Items')","metadata":{"operationMetadataId":"6650e4c4-7e20-4af4-989f-2533a0d23703"}},"SelectAddExportType":{"type":"Select","inputs":{"from":"@outputs('InputArray')","select":"@addProperty(\r\n    item(), \r\n    'exportItemsStatus',\r\n    if(\r\n        equals(\r\n\t\t\titem()?['Export_Items'], \r\n\t\t\tnull\r\n\t\t),\r\n        'null',\r\n        if(\r\n            empty(\r\n                trim(\r\n                    string(item()?['Export_Items'])\r\n                )\r\n            ), \r\n            'null', \r\n            if(\r\n                startsWith(\r\n                    trim(\r\n                        string(item()?['Export_Items'])\r\n                    ),\r\n\t\t\t\t\t'['\r\n                ), \r\n                'array', \r\n                if(\r\n                    startsWith(\r\n\t\t\t\t\t\ttrim(\r\n\t\t\t\t\t\t\tstring(item()?['Export_Items'])\r\n\t\t\t\t\t\t),\r\n\t\t\t\t\t\t'{'\r\n\t\t\t\t\t), \r\n                    'object', \r\n                    if(\r\n\t\t\t\t\t\tisInt(\r\n\t\t\t\t\t\t\ttrim(\r\n\t\t\t\t\t\t\t\tstring(item()?['Export_Items'])\r\n\t\t\t\t\t\t\t)\r\n\t\t\t\t\t\t), \r\n\t\t\t\t\t\t'integer', \r\n\t\t\t\t\t\tif(\r\n\t\t\t\t\t\t\tisFloat(\r\n\t\t\t\t\t\t\t\ttrim(\r\n\t\t\t\t\t\t\t\t\tstring(item()?['Export_Items'])\r\n\t\t\t\t\t\t\t\t)\r\n\t\t\t\t\t\t\t), \r\n\t\t\t\t\t\t\t'floating', \r\n\t\t\t\t\t\t\t'other'\r\n\t\t\t\t\t\t)\r\n\t\t\t\t\t)\r\n                )\r\n            )\r\n        )\r\n    )\r\n)"},"runAfter":{"InputArray":["Succeeded"]},"description":"This will add a piece of information to make it simple for the FilterHasExportItemsValue to differentiate what is relevant - addProperty(item(), 'exportItemsStatus', if(equals(item()?['Export_Items'], null),'null', if(empty(trim(string(item()?['Expor","metadata":{"operationMetadataId":"576f83c6-f1cb-4d6c-920d-5f9f5ccc1db7"}},"InputArray":{"type":"Compose","inputs":"","runAfter":{},"description":"Ensure you place your array in the inputs here","metadata":{"operationMetadataId":"6e013c43-f0f5-49e1-b968-71117b4d23ec"}},"OutputArray":{"type":"Compose","inputs":"@union(\r\n    body('SelectNonExport'), \r\n    body('SelectExports')\r\n)","runAfter":{"SelectExports":["Succeeded"],"SelectNonExport":["Succeeded"]},"description":"This provides an array that you can use in subsequent actions by merging the SelectNonExport results and the SelectExport results to make one proper list without duplicates - union(body('SelectNonExport'), body('SelectExports'))","metadata":{"operationMetadataId":"b64f3be7-0db5-4a2e-808c-a8930e258fc4"}},"OutputCsvTable":{"type":"Table","inputs":{"from":"@outputs('OutputArray')","format":"CSV"},"runAfter":{"OutputArray":["Succeeded"]},"description":"This produces a CSV table","metadata":{"operationMetadataId":"17901388-356f-4bc4-a1ec-05563c2b4bc7"}},"OutputHtmlTable":{"type":"Table","inputs":{"from":"@outputs('OutputArray')","format":"HTML"},"runAfter":{"OutputArray":["Succeeded"]},"description":"This produces an HTML table","metadata":{"operationMetadataId":"b072dae0-1e89-4c35-85ad-0e768a203502"}}},"runAfter":{},"metadata":{"operationMetadataId":"2e572720-9da4-4138-b754-6ac302592f99"}}}

 

Output

So, using the below (in spoiler) sample data this resulted in the below:

Spoiler
[
  {
    "DCQ": 1,
    "Export_Items": [
      {
        "Title": "AG-S--1-AA-1",
        "minDQ": 2,
        "trancheCommodityBasePrice": 2,
        "trancheDCQ": 2,
        "trancheEndDate": "2024-01-11",
        "trancheID": 1,
        "trancheMDQ": 2,
        "trancheStartDate": "2024-01-09"
      },
      {
        "Title": "AG-P-Triangle-01-2-F-22",
        "minDQ": 1,
        "trancheCommodityBasePrice": 32,
        "trancheDCQ": 3,
        "trancheEndDate": "2024-01-11",
        "trancheID": 2,
        "trancheMDQ": 2,
        "trancheStartDate": "2024-01-04"
      }
    ],
    "MDQ": 1,
    "Title": "AG-S--1-AA-1",
    "clientName": "Agnew",
    "commodityBasePrice": 1.2,
    "endDate": "2024-01-31",
    "startDate": "2024-01-01",
    "transportCost": 1
  },
  {
    "DCQ": 1,
    "Export_Items": [
      {
        "Title": "AG-S--1-AA-7",
        "minDQ": 5,
        "trancheCommodityBasePrice": 2,
        "trancheDCQ": 2,
        "trancheEndDate": "2024-01-12",
        "trancheID": 1,
        "trancheMDQ": 2,
        "trancheStartDate": "2024-01-09"
      }
    ],
    "MDQ": 1,
    "Title": "AG-S--1-AA-1",
    "clientName": "Agnew",
    "commodityBasePrice": 1.2,
    "endDate": "2024-01-31",
    "startDate": "2024-01-01",
    "transportCost": 1
  },
  {
    "DCQ": 2,
    "Export_Items": {
      "Title": "AG-P-Triangle-01-2-F-22",
      "minDQ": 2,
      "trancheCommodityBasePrice": 32,
      "trancheDCQ": 2,
      "trancheEndDate": "2024-01-11",
      "trancheID": 1,
      "trancheMDQ": 2,
      "trancheStartDate": "2024-01-04"
    },
    "MDQ": 2,
    "Title": "AG-P-Triangle-01-2-F-2",
    "clientName": "Triangle",
    "commodityBasePrice": 2,
    "endDate": "2024-02-02",
    "startDate": "2024-01-02",
    "transportCost": 2
  },
  {
    "DCQ": 7,
    "Export_Items": null,
    "MDQ": 7,
    "Title": "AG-P-Triangle-01-7-AA-7",
    "clientName": "Triangle",
    "commodityBasePrice": 7,
    "endDate": "2024-01-25",
    "startDate": "2024-01-17",
    "transportCost": 7
  }
]

 

Actions

This provides a breakdown on each action and as I have been through most of it before this will mostly be brief.

 

InputArray

This is empty in the copy/paste so that you can drop in the value of whatever is producing your array.

 

SelectAddExportType

This is a new action that I've added, and it will add an extra piece of information which classifies the type of Export.

Flow - Action SelectAddExportType.pngThe very long expression in the below spoiler is essentially a long if/then/else logic which helps define what the exportItemsStatus. I've indented it so that it is easier to follow.

Spoiler
addProperty(
	item(), 
	'exportItemsStatus',
	if(
		equals(
			item()?['Export_Items'], 
			null
		),
		'null',
		if(
			empty(
				trim(
					string(item()?['Export_Items'])
				)
			), 
			'null', 
			if(
				startsWith(
					trim(
						string(item()?['Export_Items'])
					),
					'['
				), 
				'array', 
				if(
					startsWith(
						trim(
							string(item()?['Export_Items'])
						),
						'{'
					), 
					'object', 
					if(
						isInt(
							trim(
								string(item()?['Export_Items'])
							)
						), 
						'integer', 
						if(
							isFloat(
								trim(
									string(item()?['Export_Items'])
								)
							), 
							'floating', 
							'other'
						)
					)
				)
			)
		)
	)
)

 

FilterHasExportItemsValue

This has changed, so here is a little image of that:

Flow - Action FilterHasExportItemsValue.png

... and here you can see where it uses the following advanced 'Where' expression to find relevant items.

@or(equals(item()?['exportItemsStatus'], 'array'), equals(item()?['exportItemsStatus'], 'object'))

As you can see the new classification in the previous action allows us to simply ask for any items which are an array or an object. 👍

 

SelectExports

This has changed, and here I have made it look a little more simple by switching to the normal Map view, and there are clear differences in the From/Map values.

Flow - Action SelectExports.png

From

Here this utilises the xpath() function to do pretty much all of the heavy lifting.

Spoiler
xpath(
    xml(
        json(
            concat(
                '{"r": { "c":', 
                string(body('FilterHasExportItemsValue')), 
                '}}'
            )
        )
    ),
    '/r/c/Export_Items'
)

The initial important part, here, is ensuring that the xml() conversion can properly understand what it is getting. So we have to place the value of the filter (as a string) inside an object ('r') with one property ('c') which holds the array of items from the filter action.

 

Then once that is converted to XML the xpath() expression reads *only* the Export_Items values from the array and objects fed through.

 

Map

All of the above means that each item() in the array will end up looking something like the following without some help:

{
  "$content-type": "xml/something blah blah",
  "$content": "sdfkushgkudhfgkudhfg-sdfgsidufghsdifguh_difudhfgidufhg+=="
}

Now ... that is just gibberish. So ... In order to help that along, I will show you how the DCQ value is correctly worked out into a proper integer value.

int(json(item())?['Export_Items/trancheDCQ'])

There you can see that the original item() that would otherwise be gibberish is placed inside a json() conversion function! Nice! This makes that nonsense a bit more understandable.

 

However, since you know for sure that the value will convert, and is needed to be in the integer format, then the final thing to do is to wrap an int() conversion function around the whole thing. This then ensures that the final value is a proper integer number that can be used accordingly.

 

OutputArray

I have separated this out so that you can reuse the data in this as you see fit for other actions down the line. This simply represents what I spoke about in the previous response with the union() function smashing together the two different sets of data that the flow has produced.

 

OutputCsvTable

This outputs your CSV table.

 

OutputHtmlTable

This outputs an HTML table should you wish it.

 

How To Paste Into My Clipboard Tab

I believe that this might only be available in the old 'V2' designer, but check the images in the below spoiler which should show you where to CTRL+V what you have copied.

Spoiler
Add action > My clipboard CTRL+V
My Clipboard 1.png My Clipboard 2.png

 

Yeah, I knew I'd forget one little bit ... it's not important, but I forgot to show you the outputs in the Outputs section above, @jaipalambati ... sorry about that! 😅

 

Flow - Result.png

 

Helpful resources

Announcements

Community will be READ ONLY July 16th, 5p PDT -July 22nd

Dear Community Members,   We'd like to let you know of an upcoming change to the community platform: starting July 16th, the platform will transition to a READ ONLY mode until July 22nd.   During this period, members will not be able to Kudo, Comment, or Reply to any posts.   On July 22nd, please be on the lookout for a message sent to the email address registered on your community profile. This email is crucial as it will contain your unique code and link to register for the new platform encompassing all of the communities.   What to Expect in the New Community: A more unified experience where all products, including Power Apps, Power Automate, Copilot Studio, and Power Pages, will be accessible from one community.Community Blogs that you can syndicate and link to for automatic updates. We appreciate your understanding and cooperation during this transition. Stay tuned for the exciting new features and a seamless community experience ahead!

Summer of Solutions | Week 4 Results | Winners will be posted on July 24th

We are excited to announce the Summer of Solutions Challenge!    This challenge is kicking off on Monday, June 17th and will run for (4) weeks.  The challenge is open to all Power Platform (Power Apps, Power Automate, Copilot Studio & Power Pages) community members. We invite you to participate in a quest to provide solutions to as many questions as you can. Answers can be provided in all the communities.    Entry Period: This Challenge will consist of four weekly Entry Periods as follows (each an “Entry Period”)   - 12:00 a.m. PT on June 17, 2024 – 11:59 p.m. PT on June 23, 2024 - 12:00 a.m. PT on June 24, 2024 – 11:59 p.m. PT on June 30, 2024 - 12:00 a.m. PT on July 1, 2024 – 11:59 p.m. PT on July 7, 2024 - 12:00 a.m. PT on July 8, 2024 – 11:59 p.m. PT on July 14, 2024   Entries will be eligible for the Entry Period in which they are received and will not carryover to subsequent weekly entry periods.  You must enter into each weekly Entry Period separately.   How to Enter: We invite you to participate in a quest to provide "Accepted Solutions" to as many questions as you can. Answers can be provided in all the communities. Users must provide a solution which can be an “Accepted Solution” in the Forums in all of the communities and there are no limits to the number of “Accepted Solutions” that a member can provide for entries in this challenge, but each entry must be substantially unique and different.    Winner Selection and Prizes: At the end of each week, we will list the top ten (10) Community users which will consist of: 5 Community Members & 5 Super Users and they will advance to the final drawing. We will post each week in the News & Announcements the top 10 Solution providers.  At the end of the challenge, we will add all of the top 10 weekly names and enter them into a random drawing.  Then we will randomly select ten (10) winners (5 Community Members & 5 Super Users) from among all eligible entrants received across all weekly Entry Periods to receive the prize listed below. If a winner declines, we will draw again at random for the next winner.  A user will only be able to win once overall. If they are drawn multiple times, another user will be drawn at random.  Individuals will be contacted before the announcement with the opportunity to claim or deny the prize.  Once all of the winners have been notified, we will post in the News & Announcements of each community with the list of winners.   Each winner will receive one (1) Pass to the Power Platform Conference in Las Vegas, Sep. 18-20, 2024 ($1800 value). NOTE: Prize is for conference attendance only and any other costs such as airfare, lodging, transportation, and food are the sole responsibility of the winner. Tickets are not transferable to any other party or to next year’s event.   ** PLEASE SEE THE ATTACHED RULES for this CHALLENGE**   Week 1 Results: Congratulations to the Week 1 qualifiers, you are being entered in the random drawing that will take place at the end of the challenge.   Community MembersNumber SolutionsSuper UsersNumber Solutions Deenuji 9 @NathanAlvares24  17 @Anil_g  7 @ManishSolanki  13 @eetuRobo  5 @David_MA  10 @VishnuReddy1997  5 @SpongYe  9JhonatanOB19932 (tie) @Nived_Nambiar  8 @maltie  2 (tie)   @PA-Noob  2 (tie)   @LukeMcG  2 (tie)   @tgut03  2 (tie)       Week 2 Results: Congratulations to the Week 2 qualifiers, you are being entered in the random drawing that will take place at the end of the challenge. Week 2: Community MembersSolutionsSuper UsersSolutionsPower Automate  @Deenuji  12@ManishSolanki 19 @Anil_g  10 @NathanAlvares24  17 @VishnuReddy1997  6 @Expiscornovus  10 @Tjan  5 @Nived_Nambiar  10 @eetuRobo  3 @SudeepGhatakNZ 8     Week 3 Results: Congratulations to the Week 3 qualifiers, you are being entered in the random drawing that will take place at the end of the challenge. Week 3:Community MembersSolutionsSuper UsersSolutionsPower Automate Deenuji32ManishSolanki55VishnuReddy199724NathanAlvares2444Anil_g22SudeepGhatakNZ40eetuRobo18Nived_Nambiar28Tjan8David_MA22   Week 4 Results: Congratulations to the Week 4 qualifiers, you are being entered in the random drawing that will take place at the end of the challenge. Week 4:Community MembersSolutionsSuper UsersSolutionsPower Automate Deenuji11FLMike31Sayan11ManishSolanki16VishnuReddy199710creativeopinion14Akshansh-Sharma3SudeepGhatakNZ7claudiovc2CFernandes5 misc2Nived_Nambiar5 Usernametwice232rzaneti5 eetuRobo2   Anil_g2   SharonS2  

Check Out | 2024 Release Wave 2 Plans for Microsoft Dynamics 365 and Microsoft Power Platform

On July 16, 2024, we published the 2024 release wave 2 plans for Microsoft Dynamics 365 and Microsoft Power Platform. These plans are a compilation of the new capabilities planned to be released between October 2024 to March 2025. This release introduces a wealth of new features designed to enhance customer understanding and improve overall user experience, showcasing our dedication to driving digital transformation for our customers and partners.    The upcoming wave is centered around utilizing advanced AI and Microsoft Copilot technologies to enhance user productivity and streamline operations across diverse business applications. These enhancements include intelligent automation, AI-powered insights, and immersive user experiences that are designed to break down barriers between data, insights, and individuals. Watch a summary of the release highlights.    Discover the latest features that empower organizations to operate more efficiently and adaptively. From AI-driven sales insights and customer service enhancements to predictive analytics in supply chain management and autonomous financial processes, the new capabilities enable businesses to proactively address challenges and capitalize on opportunities.    

Updates to Transitions in the Power Platform Communities

We're embarking on a journey to enhance your experience by transitioning to a new community platform. Our team has been diligently working to create a fresh community site, leveraging the very Dynamics 365 and Power Platform tools our community advocates for.  We started this journey with transitioning Copilot Studio forums and blogs in June. The move marks the beginning of a new chapter, and we're eager for you to be a part of it. The rest of the Power Platform product sites will be moving over this summer.   Stay tuned for more updates as we get closer to the launch. We can't wait to welcome you to our new community space, designed with you in mind. Let's connect, learn, and grow together.   Here's to new beginnings and endless possibilities!   If you have any questions, observations or concerns throughout this process please go to https://aka.ms/PPCommSupport.   To stay up to date on the latest details of this migration and other important Community updates subscribe to our News and Announcements forums: Copilot Studio, Power Apps, Power Automate, Power Pages