Monday 22 January 2018

PowerQuery (M) to drill into Google Sheets API v.3 and extract sheet name and link url

So I am indebted to a fellow StackOverflow citizen who helped me over a Power Query problem. Powerquery looks like a great technology and has been in Excel since 2013 edition but not VBA scriptable until 2016 edition. I especially like the ability to drill into JSON documents and extract information. But I find Powerquery's syntax challenging and clealy I have yet to master it.

The use case in hand is calling the Google Sheets API (version 3, I know I should move to version 4) to get the 'master' details of a Google sheets workbook and then drill in to find the sheet details. Amongst the sheet details are the sheet name and the url of the sheet data itself. I have tidied an example structure and it is given below. The sheet name is at feed.entry[x].title.$t whilst the url for the sheet data is at feed.entry[x].link[y].href where x increments and y is 0.


{ ""feed"": {""entry"": [ 
  {     ""title"": { ""$t"": ""1 Med"" },     ""link"": [ { ""href"": 
""https//removed1...."" } ]   }, 
  {     ""title"": { ""$t"": ""2 Dent"" },     ""link"": [ { ""href"": 
""https//removed2...."" } ]   }, 
  {     ""title"": { ""$t"": ""3 Vet"" },     ""link"": [  { ""href"": 
""https//removed3...."" }]   }
] } }

Powerquery is orientated towards outputting data onto a grid of cells. I asked for a query to give the sheet name and url for each of the three sheets, yielding a 3 row 2 column matrix. So, my thanks to Mike Honey who gave a correct working answer


let
    Source = Json.Document("{ ""feed"": {""entry"": [
  {     ""title"": { ""$t"": ""1 Med"" },     ""link"": [ { ""href"": ""https//removed1...."" } ]   },
  {     ""title"": { ""$t"": ""2 Dent"" },     ""link"": [ { ""href"": ""https//removed2...."" } ]   },
  {     ""title"": { ""$t"": ""3 Vet"" },     ""link"": [  { ""href"": ""https//removed3...."" }]   }
] } }"),
    feed = Source[feed],
    entry = feed[entry],
    #"Converted to Table" = Table.FromList(entry, Splitter.SplitByNothing(), null, null, ExtraValues.Error),
    #"Expanded Column2" = Table.ExpandRecordColumn(#"Converted to Table", "Column1", {"title", "link"}, {"title", "link"}),
    #"Expanded title1" = Table.ExpandRecordColumn(#"Expanded Column2", "title", {"$t"}, {"$t"}),
    #"Expanded link" = Table.ExpandListColumn(#"Expanded title1", "link"),
    #"Expanded link1" = Table.ExpandRecordColumn(#"Expanded link", "link", {"href"}, {"href"})
in
    #"Expanded link1"

Here is the output

1 Medhttps//removed1
2 Denthttps//removed2
3 Vethttps//removed3

I would like to be able to compete with PowerQuery in regards to a declarative technology that avoids stepping through using CallByName on JScriptTypeInfo.

Over the course of the weekend I wrote some VBA to implement a declarative syntax and then I rewrote it in Javascript. The results work but I am not happy with this code and would like to get the jsonpath library to work in the ScriptControl. Nevertheless, depositing the code here to pick up later.

No comments:

Post a Comment