{"id":1431,"date":"2021-01-31T17:22:54","date_gmt":"2021-01-31T23:22:54","guid":{"rendered":"http:\/\/ninmonkeys.com\/blog\/?p=1431"},"modified":"2022-12-15T16:24:06","modified_gmt":"2022-12-15T22:24:06","slug":"power-query-custom-functions-cheat-sheet","status":"publish","type":"post","link":"https:\/\/ninmonkeys.com\/blog\/2021\/01\/31\/power-query-custom-functions-cheat-sheet\/","title":{"rendered":"Power Query Custom Functions &#8211; Cheat Sheet"},"content":{"rendered":"\n\n\n<h2>Converting Types<\/h2>\n\n\n\n<h3>DateTime.FromText using format strings<\/h3>\n\n\n\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"language-powerquery\" data-line=\"\">let dt =  DateTime.FromText(&quot;2001-01-01T05:09:23&quot;, [Format = &quot;yyyy-MM-ddTHH:mm:ss&quot;, Culture = &quot;en-us&quot;]) in dt<\/code><\/pre>\n\n\n\n<p>For format strings syntax, see: <a href=\"https:\/\/docs.microsoft.com\/en-us\/dotnet\/standard\/base-types\/custom-date-and-time-format-strings\">dotnet\/custom-date-and-time-format-strings<\/a><\/p>\n\n\n\n<h2>Web Requests<\/h2>\n\n\n\n<p>Check out the new tutorial at https:\/\/blog.powp.co\/my-power-query-web-contents-cheat-sheet-6a5bbfdce5eb <\/p>\n\n\n\n<h3>Web.Contents without Refresh Errors<\/h3>\n\n\n\n<p>The main cause of <a href=\"https:\/\/docs.microsoft.com\/en-us\/powerquery-m\/web-contents\">Web.Contents<\/a> not refreshing can be fixed by adding the <code class=\"\" data-line=\"\">options[Query]<\/code> and <code class=\"\" data-line=\"\">options[RelativeaPath]<\/code> parameters. (The UI doesn&#8217;t create them for you)<br><br>This example uses <a href=\"https:\/\/www.metaweather.com\/api\/location\/search?query=london\">https:\/\/www.metaweather.com\/api\/location\/search?query=london<\/a> See more: <a href=\"https:\/\/blog.crossjoin.co.uk\/2019\/04\/25\/skip-test-connection-power-bi-refresh-failures\/\">Skip Test Connection<\/a><\/p>\n\n\n\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"language-powerquery\" data-line=\"\">\/\/ lookup city GUID - simplified\nlet\n    exampleUrl = &quot;https:\/\/www.metaweather.com\/api\/location\/search?query=london&quot;,\n    Headers = [\n        Accept=&quot;application\/json&quot;\n    ],\n    BaseUrl = &quot;https:\/\/www.metaweather.com&quot;,\n    Options = [\n        RelativePath = &quot;\/api\/location\/search&quot;,\n        Headers = Headers,\n        Query = [\n            query = &quot;london&quot;\n        ],\n        ManualStatusHandling = {400, 404}\n    ],\n    \/\/ wrap &#039;Response&#039; in &#039;Binary.Buffer&#039; if you are using it multiple times\n    response = Web.Contents(BaseUrl, Options),\n    buffered = Binary.Buffer(response),\n    response_metadata = Value.Metadata(response),\n    status_code = response_metadata[Response.Status],\n    final_result =\n        if List.Contains({400, 404}, status_code) then response_metadata\n        else buffered,\n    from_json = Json.Document(final_result),\n    #&quot;weather record&quot; = from_json{0}\nin\n    #&quot;weather record&quot;<\/code><\/pre>\n\n\n\n<h3>Handling Specific HTTP Error Status Codes<\/h3>\n\n\n\n<p>You can filter results based on the status code, instead of getting errors.<br>See more: <a href=\"https:\/\/docs.microsoft.com\/en-us\/power-query\/handlingstatuscodes\">override default error handling<\/a>, and the example <a href=\"https:\/\/docs.microsoft.com\/en-us\/power-query\/waitretry#manualstatushandling\">wait-for loop<\/a><\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" width=\"709\" height=\"436\" src=\"https:\/\/ninmonkeys.com\/blog\/wp-content\/uploads\/2021\/04\/Power-Query-Web.Contents-Error-Handling.2021-04-04.png\" alt=\"\" class=\"wp-image-1773\" srcset=\"https:\/\/ninmonkeys.com\/blog\/wp-content\/uploads\/2021\/04\/Power-Query-Web.Contents-Error-Handling.2021-04-04.png 709w, https:\/\/ninmonkeys.com\/blog\/wp-content\/uploads\/2021\/04\/Power-Query-Web.Contents-Error-Handling.2021-04-04-300x184.png 300w\" sizes=\"(max-width: 709px) 100vw, 709px\" \/><\/figure>\n\n\n\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"language-powerquery\" data-line=\"\">\/* web request, act based on the HTTP Status Code returned\nsee more:\n    override default error handling: https:\/\/docs.microsoft.com\/en-us\/power-query\/handlingstatuscodes\n    example wait-for loop: https:\/\/docs.microsoft.com\/en-us\/power-query\/waitretry#manualstatushandling\n*\/\nlet\n    WikiRequest = (pageName as text) as any =&gt;\n        let\n            BaseUrl = &quot;https:\/\/en.wikipedia.org\/wiki&quot;,\n            Options = [\n                RelativePath = pageName,\n                ManualStatusHandling = {400, 404}\n            ],\n            \/\/ wrap &#039;Response&#039; in &#039;Binary.Buffer&#039; if you are using it multiple times\n            response = Web.Contents(BaseUrl, Options),\n            buffered = Binary.Buffer(response),\n            response_metadata = Value.Metadata(response),\n            status_code = response_metadata[Response.Status],\n            final_result = [\n                buffered = buffered,\n                response_metadata = response_metadata\n            ]\n        in\n            final_result,\n    Queries = {&quot;Cat&quot;, &quot;DoesNot Exist fake page&quot;},\n    Items = List.Transform(\n        Queries,\n        each WikiRequest( _ )\n    ),\n    ResponseTable = Table.FromRecords(\n        Items,\n        type table[buffered = binary, response_metadata = record], MissingField.Error\n    ),\n\n    #&quot;Expanded HTTP Status Codes&quot; = Table.ExpandRecordColumn(ResponseTable, &quot;response_metadata&quot;, {&quot;Response.Status&quot;}, {&quot;Response.Status&quot;}),\n    #&quot;Changed Type&quot; = Table.TransformColumnTypes(#&quot;Expanded HTTP Status Codes&quot;,{{&quot;Response.Status&quot;, Int64.Type}})\nin\n    #&quot;Changed Type&quot;<\/code><\/pre>\n\n\n\n<h3><code class=\"\" data-line=\"\">WebRequest<\/code>: Wrapper with Better Defaults<\/h3>\n\n\n\n<p>You can get the full file with extra comments: <a href=\"https:\/\/github.com\/ninmonkey\/Ninmonkey.PowerQueryLib\/blob\/master\/source\/WebRequest.pq\">WebRequest.pq<\/a><\/p>\n\n\n\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"language-powerquery\" data-line=\"\">    let\n        \/*\n        Example using this url:\n            (https:\/\/www.metaweather.com\/api\/location\/search?lattlong=36.96,-122.02)\n\n            WebRequest(\n                &quot;https:\/\/www.metaweather.com&quot;,\n                &quot;api\/location\/search&quot;,\n                [ lattlong = &quot;36.96,-122.02&quot; ]\n            )\n\n        Details on preventing &quot;Refresh Errors&quot;, using &#039;Query&#039; and &#039;RelativePath&#039;:\n            - Not using Query and Relative path cause refresh errors:\n                (https:\/\/blog.crossjoin.co.uk\/2016\/08\/23\/web-contents-m-functions-and-dataset-refresh-errors-in-power-bi\/)\n\n            - You can opt-in to Skip-Test:\n                (https:\/\/blog.crossjoin.co.uk\/2019\/04\/25\/skip-test-connection-power-bi-refresh-failures\/)\n\n            - Debugging and tracing the HTTP requests\n                (https:\/\/blog.crossjoin.co.uk\/2019\/11\/17\/troubleshooting-web-service-refresh-problems-in-power-bi-with-the-power-query-diagnostics-feature\/)\n\n        *\/\n        WebRequest = (\n            staticPath as text,                 \/\/ domain\n            relativePath as text,               \/\/ basically use everything after &quot;.com&quot; to &quot;?&quot;\n            optional query as nullable record,  \/\/ url query string\n            optional asRaw as nullable logical, \/\/ use true if content is not Json\n            optional headers as nullable record \/\/ optional HTTP headers as a record\n        ) as any =&gt;\n            let\n                query = query ?? [],\n                asRaw = asRaw ?? false, \/\/ toggles calling Json.Document() or not\n                headers = headers ?? [\n                    Accept=&quot;application\/json&quot;\n                ],\n\n                baseUrl = staticPath,\n                options = [\n                    RelativePath = relativePath,\n                    Headers = headers,\n                    Query = query\n                    \/\/ optionally toggle handling errors for specific HTTP Status codes\n                    \/\/ ManualStatusHandling = {400, 404}\n                ],\n                \/\/ wrap &#039;Response&#039; in &#039;Binary.Buffer&#039; if you are using it multiple times\n                response = Web.Contents(staticPath, options),\n                metadata = Value.Metadata(response),\n                buffered = Binary.Buffer(response),\n                result = Json.Document(buffered)\n            in\n                [\n                    response = if asRaw then buffered else result,\n                    status_code = metadata[Response.Status],\n                    metadata = metadata\n                ]\n    in\n        WebRequest<\/code><\/pre>\n\n\n\n<h3>Chaining Web.Contents to Merge Many Queries<\/h3>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" width=\"981\" height=\"365\" src=\"https:\/\/ninmonkeys.com\/blog\/wp-content\/uploads\/2021\/02\/image-18.png\" alt=\"\" class=\"wp-image-1697\" srcset=\"https:\/\/ninmonkeys.com\/blog\/wp-content\/uploads\/2021\/02\/image-18.png 981w, https:\/\/ninmonkeys.com\/blog\/wp-content\/uploads\/2021\/02\/image-18-300x112.png 300w, https:\/\/ninmonkeys.com\/blog\/wp-content\/uploads\/2021\/02\/image-18-768x286.png 768w\" sizes=\"(max-width: 981px) 100vw, 981px\" \/><\/figure>\n\n\n\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"language-powerquery\" data-line=\"\">    let \n        response_locations = WebRequest(\n            &quot;https:\/\/www.metaweather.com&quot;,\n            &quot;api\/location\/search&quot;,\n            [ lattlong = &quot;36.96,-122.02&quot; ]\n        ),\n        location_schema = type table[\n            distance = number, title = text,\n            location_type = text, woeid = number, latt_long = text\n        ],\n        cityListing = Table.FromRecords(response_locations[response], location_schema, MissingField.Error),\n        \n        city_mergedRequest = Table.AddColumn(\n            cityListing,\n            &quot;LocationWeather&quot;,\n            (row as record) as any =&gt;\n                let\n                    woeid = Text.From(row[woeid]),\n                    response = WebRequest(\n                        &quot;https:\/\/www.metaweather.com&quot;,\n                        &quot;api\/location\/&quot; &amp; woeid,\n                        []\n                    )\n                in\n                    response,\n            type any\n        )\n    in\n        city_mergedRequest<\/code><\/pre>\n\n\n\n<h2>Html.Table &#8211; Parsing with <code class=\"\" data-line=\"\">CSS Selectors<\/code><\/h2>\n\n\n\n<h3>Select a Single Element: an Image, url, text, etc&#8230;<\/h3>\n\n\n\n<p>This fetches the current heading text on the blog<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" width=\"419\" height=\"116\" src=\"http:\/\/ninmonkeys.com\/blog\/wp-content\/uploads\/2021\/02\/manual_css_SingleElement_FinalTable.png\" alt=\"\" class=\"wp-image-1490\" srcset=\"https:\/\/ninmonkeys.com\/blog\/wp-content\/uploads\/2021\/02\/manual_css_SingleElement_FinalTable.png 419w, https:\/\/ninmonkeys.com\/blog\/wp-content\/uploads\/2021\/02\/manual_css_SingleElement_FinalTable-300x83.png 300w\" sizes=\"(max-width: 419px) 100vw, 419px\" \/><\/figure>\n\n\n\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"language-powerquery\" data-line=\"\">let\n    Url = &quot;https:\/\/powerbi.microsoft.com\/en-us\/blog\/&quot;,\n    Response = Web.Contents( Url ),\n    \/*\n    note: normally do not pass dynamic urls like this, see cheatsheet on preventing refresh errors\n    Non-tabular scraping like Images or any single elements, does not use a &quot;RowSelector&quot;\n\n    This CSS Selector finds exactly one element, the Page&#039;s Header Text\n\n        .section-featured-post .text-heading1 a\n    *\/\n    HeaderText = Html.Table(\n        Response,\n        {\n            { &quot;Page Header&quot;, &quot;.section-featured-post .text-heading1 a&quot; }\n        }\n    )\nin\n    HeaderText<\/code><\/pre>\n\n\n\n<h3>Parsing Element&#8217;s Attributes<\/h3>\n\n\n\n<figure class=\"wp-block-image alignwide size-full\"><img loading=\"lazy\" width=\"1131\" height=\"117\" src=\"https:\/\/ninmonkeys.com\/blog\/wp-content\/uploads\/2021\/02\/manual_css_Parsing-HTML-Attributes.png\" alt=\"\" class=\"wp-image-1489\" srcset=\"https:\/\/ninmonkeys.com\/blog\/wp-content\/uploads\/2021\/02\/manual_css_Parsing-HTML-Attributes.png 1131w, https:\/\/ninmonkeys.com\/blog\/wp-content\/uploads\/2021\/02\/manual_css_Parsing-HTML-Attributes-300x31.png 300w, https:\/\/ninmonkeys.com\/blog\/wp-content\/uploads\/2021\/02\/manual_css_Parsing-HTML-Attributes-1024x106.png 1024w, https:\/\/ninmonkeys.com\/blog\/wp-content\/uploads\/2021\/02\/manual_css_Parsing-HTML-Attributes-768x79.png 768w\" sizes=\"(max-width: 1131px) 100vw, 1131px\" \/><\/figure>\n\n\n\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"language-powerquery\" data-line=\"\">let\n    Url = &quot;https:\/\/powerbi.microsoft.com\/en-us\/blog\/&quot;,\n    Response = Web.Contents( Url ),\n    \/*\n    The 3rd argument in &quot;columnNameSelectorPairs&quot; is the transformation function.\n    by default it uses:\n\n            each _[TextContent]\n    *\/\n    HeaderAsElement = Html.Table(\n        Response,\n        { { &quot;Link&quot;, &quot;.section-featured-post .text-heading1 a&quot;, each _ } }\n    ),\n\n    ElementRecord = Table.ExpandRecordColumn(\n        HeaderAsElement, &quot;Link&quot;,\n        {&quot;TagName&quot;, &quot;TextContent&quot;, &quot;Attributes&quot;}, {&quot;TagName&quot;, &quot;TextContent&quot;, &quot;Attributes&quot;}\n    ),\n\n    ExpandedAttributes = Table.ExpandRecordColumn(\n        ElementRecord, &quot;Attributes&quot;,\n        {&quot;href&quot;, &quot;rel&quot;, &quot;title&quot;}, {&quot;attr.href&quot;, &quot;attr.rel&quot;, &quot;attr.title&quot;}\n    )\nin\n    ExpandedAttributes<\/code><\/pre>\n\n\n\n<h3>Select Tables using your own CSS Selectors<\/h3>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" width=\"860\" height=\"446\" src=\"http:\/\/ninmonkeys.com\/blog\/wp-content\/uploads\/2021\/02\/manual_css_visualize_RowSelectors.png\" alt=\"CSS Row Selector\" class=\"wp-image-1493\" srcset=\"https:\/\/ninmonkeys.com\/blog\/wp-content\/uploads\/2021\/02\/manual_css_visualize_RowSelectors.png 860w, https:\/\/ninmonkeys.com\/blog\/wp-content\/uploads\/2021\/02\/manual_css_visualize_RowSelectors-300x156.png 300w, https:\/\/ninmonkeys.com\/blog\/wp-content\/uploads\/2021\/02\/manual_css_visualize_RowSelectors-768x398.png 768w\" sizes=\"(max-width: 860px) 100vw, 860px\" \/><figcaption>Results of the <code class=\"\" data-line=\"\">RowSelector<\/code> <\/figcaption><\/figure>\n\n\n\n<figure class=\"wp-block-image size-large is-resized\"><img loading=\"lazy\" src=\"http:\/\/ninmonkeys.com\/blog\/wp-content\/uploads\/2021\/02\/manual_css_visualize_ColumnSelectors.png\" alt=\"CSS Column Selector\" class=\"wp-image-1492\" width=\"610\" height=\"355\" srcset=\"https:\/\/ninmonkeys.com\/blog\/wp-content\/uploads\/2021\/02\/manual_css_visualize_ColumnSelectors.png 738w, https:\/\/ninmonkeys.com\/blog\/wp-content\/uploads\/2021\/02\/manual_css_visualize_ColumnSelectors-300x175.png 300w\" sizes=\"(max-width: 610px) 100vw, 610px\" \/><figcaption>Results of <code class=\"\" data-line=\"\">columnNameSelectorPairs<\/code> <\/figcaption><\/figure>\n\n\n\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"language-powerquery\" data-line=\"\">\/\/ Docs on Enum\nlet\n    Source = &quot;https:\/\/docs.microsoft.com\/en-us\/previous-versions\/dynamics\/ax-2012\/reference\/gg841505(v=ax.60)&quot;,\n    \/\/ note: normally do not pass dynamic urls like this, see cheatsheet on preventing refresh errors\n    Response = Web.BrowserContents( Source ),\n    \/*\n\n        Think of &quot;RowSelector&quot; as selecting a table row\n        Then for every row, you select &quot;columns&quot; using the &quot;columnNameSelectorPairs&quot; selector\n        The combination gives you a table cell.\n\n        For more on CSS Selectors, see: &lt;https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/CSS\/CSS_Selectors&gt;\n    *\/\n\n    columnNameSelectorPairs = {\n        \/\/ column names don&#039;t matter here, since I&#039;m using .PromoteHeaders\n        { &quot;Column1&quot;, &quot;TABLE.table &gt; * &gt; TR &gt; :nth-child(1)&quot; },\n        { &quot;Column2&quot;, &quot;TABLE.table &gt; * &gt; TR &gt; :nth-child(2)&quot; },\n        { &quot;Column3&quot;, &quot;TABLE.table &gt; * &gt; TR &gt; :nth-child(3)&quot; }\n    },\n\n    t1 = Html.Table(\n            Response, columnNameSelectorPairs,\n            [RowSelector = &quot;TABLE.table &gt; * &gt; TR&quot;]\n    ),\n\n    t2 = Table.PromoteHeaders( t1, [PromoteAllScalars = true] ),\n    FinalTable = Table.TransformColumnTypes(\n            t2,\n            { { &quot;Name&quot;, type text }, { &quot;Value&quot;, Int64.Type }, { &quot;Description&quot;, type text} }\n        )\nin\n    FinalTable<\/code><\/pre>\n\n\n\n<h2>SQL Native Query<\/h2>\n\n\n\n<h3>Parameterized SQL queries with <code class=\"\" data-line=\"\">Value.NativeQuery()<\/code><\/h3>\n\n\n\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"language-powerquery\" data-line=\"\">let\n    Source = Sql.Database(&quot;localhost&quot;, &quot;Adventure Works DW&quot;),\n    Test = Value.NativeQuery(\n        Source,\n        &quot;SELECT * FROM DimDate \n        WHERE EnglishMonthName=@MonthName&quot;,\n        [\n            MonthName = &quot;March&quot;,\n            DayName = &quot;Tuesday&quot;\n        ]\n    )\nin\n    Test<\/code><\/pre>\n\n\n\n<h2>Other<\/h2>\n\n\n\n<h3>Cartesian Product<\/h3>\n\n\n\n<figure class=\"wp-block-image alignwide size-full\"><img loading=\"lazy\" width=\"1265\" height=\"480\" src=\"https:\/\/ninmonkeys.com\/blog\/wp-content\/uploads\/2021\/02\/image-3.png\" alt=\"Table Cartesian Product\" class=\"wp-image-1468\" srcset=\"https:\/\/ninmonkeys.com\/blog\/wp-content\/uploads\/2021\/02\/image-3.png 1265w, https:\/\/ninmonkeys.com\/blog\/wp-content\/uploads\/2021\/02\/image-3-300x114.png 300w, https:\/\/ninmonkeys.com\/blog\/wp-content\/uploads\/2021\/02\/image-3-1024x389.png 1024w, https:\/\/ninmonkeys.com\/blog\/wp-content\/uploads\/2021\/02\/image-3-768x291.png 768w, https:\/\/ninmonkeys.com\/blog\/wp-content\/uploads\/2021\/02\/image-3-1200x455.png 1200w\" sizes=\"(max-width: 1265px) 100vw, 1265px\" \/><\/figure>\n\n\n\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"language-typescript\" data-line=\"\">let    \n    #&quot;Add Column Pair2&quot; = Table.AddColumn(\n        Table_Pairs1, &quot;Pairs2&quot;,\n        each Table_Pairs2,\n        Table.Type\n    ),\n    #&quot;Expanded Pairs&quot; = Table.ExpandTableColumn(\n        #&quot;Add Column Pair2&quot;,\n        &quot;Pairs2&quot;,\n        {&quot;Color&quot;, &quot;Property&quot;},\n        {&quot;Color&quot;, &quot;Property&quot;}\n    )\nin\n    #&quot;Expanded Pairs&quot;<\/code><\/pre>\n\n\n\n<p>Details: <a href=\"https:\/\/radacad.com\/cartesian-product-in-power-query-multiply-all-sets-of-all-pairs-in-power-bi\">https:\/\/radacad.com\/cartesian-product-in-power-query-multiply-all-sets-of-all-pairs-in-power-bi<\/a><\/p>\n\n\n\n<h3>Using Multiple `Enter Data` Tables in One Query<\/h3>\n\n\n\n<p>You can make start with &#8216;enter data&#8217;, then duplicate that line. You end up with two steps, each are their own <code class=\"\" data-line=\"\">enter data<\/code> <\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" width=\"785\" height=\"418\" src=\"https:\/\/ninmonkeys.com\/blog\/wp-content\/uploads\/2021\/04\/image-2.png\" alt=\"\" class=\"wp-image-1784\" srcset=\"https:\/\/ninmonkeys.com\/blog\/wp-content\/uploads\/2021\/04\/image-2.png 785w, https:\/\/ninmonkeys.com\/blog\/wp-content\/uploads\/2021\/04\/image-2-300x160.png 300w, https:\/\/ninmonkeys.com\/blog\/wp-content\/uploads\/2021\/04\/image-2-768x409.png 768w\" sizes=\"(max-width: 785px) 100vw, 785px\" \/><\/figure>\n\n\n\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"language-typescript\" data-line=\"\">let\n    Source = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText(&quot;i45WcitKzEvOLFbSUfLJrEosSgEyTJRidaKVHHNSKxJTijITgSLuqcnZ+UDaEiwTkgpS5ZtfkgGkjJRiYwE=&quot;, BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type nullable text) meta [Serialized.Text = true]) in type table [Name = _t, Species = _t, Age = _t]),\n    Source2 = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText(&quot;i45W8krNU9JRciotKUktSsupBLINlWJ1opWCE4sSM4A858QSIGlkDBYMSU0Bclzy04GkiYFSbCwA&quot;, BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type nullable text) meta [Serialized.Text = true]) in type table [Name = _t, Species = _t, Age = _t]),\n    Final = Table.Combine( { Source, Source2 } )\nin\n    Final<\/code><\/pre>\n\n\n\n<h3>Convert Table to <code class=\"\" data-line=\"\">JSON<\/code><\/h3>\n\n\n\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"language-typescript\" data-line=\"\">TableToJson = (source as table, optional encoding as nullable number) as text =&gt;\n        let\n            encoding = encoding ?? TextEncoding.Utf8,\n            bin = Json.FromValue(source, encoding),\n            jsonAsText = Text.FromBinary(bin, encoding)\n        in\n            jsonAsText<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"language-typescript\" data-line=\"\">Animals = #table(\n    {&quot;Animal&quot;, &quot;Id&quot;},\n    {{&quot;Cat&quot;, 1}, {&quot;Turtle&quot;, 2}} ),\nTableTo_Json( Animals )<\/code><\/pre>\n\n\n\n<p>Json output:<\/p>\n\n\n\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"language-json\" data-line=\"\">[{&quot;Animal&quot;:&quot;Cat&quot;,&quot;Id&quot;:1},{&quot;Animal&quot;:&quot;Turtle&quot;,&quot;Id&quot;:2}]<\/code><\/pre>\n\n\n\n<p><\/p>\n\n\n\n<h3>Converting a <code class=\"\" data-line=\"\">list<\/code> of items to a <code class=\"\" data-line=\"\">CSV<\/code> string<\/h3>\n\n\n\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"language-typescript\" data-line=\"\">let\n    \/\/ Converts a list of any type to text. Works well on most types\n    \/\/ although to support all cases, it requires more logic\n    mixedList = {4, &quot;cat&quot;, #date(1999,5,9), 0.4},\n    ListAsText = List.Transform(mixedList, each Text.From(_)),\n    CsvText = Text.Combine( ListAsText, &quot;, &quot;)\nin\n    \/\/output: &quot;4, cat, 5\/9\/1999, 0.4&quot;\n    CsvText <\/code><\/pre>\n\n\n\n<p><\/p>\n\n\n\n<h2>Functions<\/h2>\n\n\n\n<h3>Using Optional Parameters with Default Values<\/h3>\n\n\n\n<p>The <a href=\"https:\/\/en.wikipedia.org\/wiki\/Null_coalescing_operator\">Null_coalescing_operator <code class=\"\" data-line=\"\">??<\/code><\/a> simplifies default values.<br><code class=\"\" data-line=\"\">encoding<\/code> will be set to what the user passed, unless it&#8217;s <code class=\"\" data-line=\"\">null<\/code>. In that case, it is set to <code class=\"\" data-line=\"\">TextEncoding.Utf8<\/code><\/p>\n\n\n\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"language-typescript\" data-line=\"\">let\n    Read_Json = (json as any, encoding as nullable number) as any =&gt;\n        \/\/ calls Json.Document, using UTF8 by default\n        let\n            encoding = encoding ?? TextEncoding.Utf8,\n            result = Json.Document(json, encoding)\n        in\n            result\nin\n    Read_Json<\/code><\/pre>\n\n\n\n<h3>Mapping Function Calls based on Type<\/h3>\n\n\n\n<p>Caller chooses which type of conversioin to use, based on type names <code class=\"\" data-line=\"\">{ date, datetime, datetimezone }<\/code><\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" width=\"283\" height=\"87\" src=\"https:\/\/ninmonkeys.com\/blog\/wp-content\/uploads\/2021\/01\/image-45.png\" alt=\"\" class=\"wp-image-1434\"\/><\/figure>\n\n\n\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"language-typescript\" data-line=\"\">let\n    \/\/ 1] get a `type` from caller\n    \/\/ 2] return a difference function based on the type\n    GetTransformByType = (_type as type) as function =&gt;\n        let\n            \/\/ originally from: &lt;https:\/\/docs.microsoft.com\/en-us\/power-query\/helperfunctions#tablechangetype&gt;\n            func_transform = \n                 if (Type.Is(_type, type date)) then Date.From\n            else if (Type.Is(_type, type datetime)) then DateTime.From\n            else if (Type.Is(_type, type datetimezone)) then DateTimeZone.From\n            else (t) =&gt; t \/\/ else return self\n        in\n            func_transform,\n\n    nowDtz = DateTimeZone.LocalNow(),    \n\n    \/\/ invoke in 2 steps\n    toDate = GetTransformByType(type date),\n    callDate = toDate( DateTimeZone.FixedLocalNow() ),\n\n    \/\/ create, and invoke functions\n    Results = [\n        asDate = (GetTransformByType(type date))( nowDtz ),\n        asDateTime = (GetTransformByType(type datetime))( nowDtz ),\n        asDateTimeZone = (GetTransformByType(type datetimezone))( nowDtz )\n    ]\nin\n    Results<\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Declaring <code class=\"\" data-line=\"\">optional parameters<\/code> in custom functions, combine <b>multiple<\/b> <code class=\"\" data-line=\"\">Web.Contents<\/code> queries, <b>without refresh errors<\/b>. Using <code class=\"\" data-line=\"\">Html.Table<\/code> with custom <code class=\"\" data-line=\"\">CSS Selectors<\/code><\/p>\n","protected":false},"author":1,"featured_media":1513,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[65,13,9,14],"tags":[10,61,79,6,7,15,81,78],"_links":{"self":[{"href":"https:\/\/ninmonkeys.com\/blog\/wp-json\/wp\/v2\/posts\/1431"}],"collection":[{"href":"https:\/\/ninmonkeys.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/ninmonkeys.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/ninmonkeys.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/ninmonkeys.com\/blog\/wp-json\/wp\/v2\/comments?post=1431"}],"version-history":[{"count":86,"href":"https:\/\/ninmonkeys.com\/blog\/wp-json\/wp\/v2\/posts\/1431\/revisions"}],"predecessor-version":[{"id":2640,"href":"https:\/\/ninmonkeys.com\/blog\/wp-json\/wp\/v2\/posts\/1431\/revisions\/2640"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/ninmonkeys.com\/blog\/wp-json\/wp\/v2\/media\/1513"}],"wp:attachment":[{"href":"https:\/\/ninmonkeys.com\/blog\/wp-json\/wp\/v2\/media?parent=1431"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/ninmonkeys.com\/blog\/wp-json\/wp\/v2\/categories?post=1431"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/ninmonkeys.com\/blog\/wp-json\/wp\/v2\/tags?post=1431"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}