{"id":2497,"date":"2022-09-24T10:46:18","date_gmt":"2022-09-24T15:46:18","guid":{"rendered":"http:\/\/ninmonkeys.com\/blog\/?p=2497"},"modified":"2024-06-02T00:51:06","modified_gmt":"2024-06-02T05:51:06","slug":"inspecting-function-subtypes-in-power-query","status":"publish","type":"post","link":"https:\/\/ninmonkeys.com\/blog\/2022\/09\/24\/inspecting-function-subtypes-in-power-query\/","title":{"rendered":"Inspecting Function &#8220;subtypes&#8221; in Power Query"},"content":{"rendered":"\n\n\n<p>PowerQuery has metadata  that you don&#8217;t normally see. For example, take the function <a href=\"https:\/\/learn.microsoft.com\/en-us\/powerquery-m\/table-fromrecords\">Table.FromRecords<\/a><\/p>\n\n\n\n<p>Create a<strong> new blank query,<\/strong> and set the value to a function&#8217;s name. When you reference a function without arguments or parenthesis, it displays documentation. ( It&#8217;s mostly the same as <a href=\"https:\/\/learn.microsoft.com\/en-us\/powerquery-m\/table-fromrecords\">the online docs<\/a> )<\/p>\n\n\n\n<figure class=\"wp-block-image size-large is-resized\"><img loading=\"lazy\" src=\"https:\/\/ninmonkeys.com\/blog\/wp-content\/uploads\/2022\/09\/image-2.png\" alt=\"\" class=\"wp-image-2499\" width=\"472\" height=\"466\" srcset=\"https:\/\/ninmonkeys.com\/blog\/wp-content\/uploads\/2022\/09\/image-2.png 629w, https:\/\/ninmonkeys.com\/blog\/wp-content\/uploads\/2022\/09\/image-2-300x296.png 300w\" sizes=\"(max-width: 472px) 100vw, 472px\" \/><\/figure>\n\n\n\n<p>Where does this come from? A lot of it is generated by <strong>metadata on the function&#8217;s type<\/strong> itself. <\/p>\n\n\n\n<p>Let&#8217;s start drilling down. Using the function <a href=\"https:\/\/learn.microsoft.com\/en-us\/powerquery-m\/value-type\">Value.Type<\/a> you can view the type&#8217;s definition<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" width=\"453\" height=\"139\" src=\"https:\/\/ninmonkeys.com\/blog\/wp-content\/uploads\/2022\/09\/image-5.png\" alt=\"\" class=\"wp-image-2503\" srcset=\"https:\/\/ninmonkeys.com\/blog\/wp-content\/uploads\/2022\/09\/image-5.png 453w, https:\/\/ninmonkeys.com\/blog\/wp-content\/uploads\/2022\/09\/image-5-300x92.png 300w\" sizes=\"(max-width: 453px) 100vw, 453px\" \/><\/figure>\n\n\n\n<p>It doesn&#8217;t seem very useful at first. The data we want is from the metadata, <a href=\"https:\/\/learn.microsoft.com\/en-us\/powerquery-m\/m-spec-types#ascribed-type-of-a-value\">the Ascribed types<\/a>.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" width=\"498\" height=\"152\" src=\"https:\/\/ninmonkeys.com\/blog\/wp-content\/uploads\/2022\/09\/image-6.png\" alt=\"\" class=\"wp-image-2513\" srcset=\"https:\/\/ninmonkeys.com\/blog\/wp-content\/uploads\/2022\/09\/image-6.png 498w, https:\/\/ninmonkeys.com\/blog\/wp-content\/uploads\/2022\/09\/image-6-300x92.png 300w\" sizes=\"(max-width: 498px) 100vw, 498px\" \/><\/figure>\n\n\n\n<h2>Metadata of the function type<\/h2>\n\n\n\n<p>The first level describes the function using <a href=\"https:\/\/learn.microsoft.com\/en-us\/power-query\/handlingdocumentation\">specific field names that the UI looks for<\/a> . The UI renders some Html from the  <code class=\"\" data-line=\"\">[Documentation.LongDescription]<\/code> value.<\/p>\n\n\n\n<p>You can drill down to <code class=\"\" data-line=\"\">[Documentation.Examples]<\/code> , which is a list of records. <\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" width=\"794\" height=\"449\" src=\"https:\/\/ninmonkeys.com\/blog\/wp-content\/uploads\/2022\/09\/image-7.png\" alt=\"\" class=\"wp-image-2514\" srcset=\"https:\/\/ninmonkeys.com\/blog\/wp-content\/uploads\/2022\/09\/image-7.png 794w, https:\/\/ninmonkeys.com\/blog\/wp-content\/uploads\/2022\/09\/image-7-300x170.png 300w, https:\/\/ninmonkeys.com\/blog\/wp-content\/uploads\/2022\/09\/image-7-768x434.png 768w\" sizes=\"(max-width: 794px) 100vw, 794px\" \/><figcaption>Viewing <code class=\"\" data-line=\"\">Documenation.Examples<\/code><\/figcaption><\/figure>\n\n\n\n<h2>Function Parameters Types<\/h2>\n\n\n\n<p>There can be data defined for the arguments themselves. Parameters that are <code class=\"\" data-line=\"\">type any<\/code> <a href=\"https:\/\/bengribaudo.com\/blog\/2021\/09\/21\/6179\/describing-function-record-parameters\">may have more information in their metadata<\/a>. <\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" width=\"722\" height=\"433\" src=\"https:\/\/ninmonkeys.com\/blog\/wp-content\/uploads\/2022\/09\/power-query-nested-sub-types-explains-array-2-Screenshot-2022-09-11-094910.png\" alt=\"\" class=\"wp-image-2506\" srcset=\"https:\/\/ninmonkeys.com\/blog\/wp-content\/uploads\/2022\/09\/power-query-nested-sub-types-explains-array-2-Screenshot-2022-09-11-094910.png 722w, https:\/\/ninmonkeys.com\/blog\/wp-content\/uploads\/2022\/09\/power-query-nested-sub-types-explains-array-2-Screenshot-2022-09-11-094910-300x180.png 300w\" sizes=\"(max-width: 722px) 100vw, 722px\" \/><figcaption>Parameters may have metadata<\/figcaption><\/figure>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" width=\"798\" height=\"426\" src=\"https:\/\/ninmonkeys.com\/blog\/wp-content\/uploads\/2022\/09\/power-query-nested-sub-types-explains-array-4-Screenshot-2022-09-11-094910.png\" alt=\"\" class=\"wp-image-2505\" srcset=\"https:\/\/ninmonkeys.com\/blog\/wp-content\/uploads\/2022\/09\/power-query-nested-sub-types-explains-array-4-Screenshot-2022-09-11-094910.png 798w, https:\/\/ninmonkeys.com\/blog\/wp-content\/uploads\/2022\/09\/power-query-nested-sub-types-explains-array-4-Screenshot-2022-09-11-094910-300x160.png 300w, https:\/\/ninmonkeys.com\/blog\/wp-content\/uploads\/2022\/09\/power-query-nested-sub-types-explains-array-4-Screenshot-2022-09-11-094910-768x410.png 768w\" sizes=\"(max-width: 798px) 100vw, 798px\" \/><figcaption>Sometimes the metadata, of a parameter&#8217;s metadata &#8212; has more metadata! <\/figcaption><\/figure>\n\n\n\n<h2>Your First Function types<\/h2>\n\n\n\n<p>How do you document your own functions? Here&#8217;s a medium example. The function declared further below starts with this definition:<\/p>\n\n\n\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"language-powerquery\" data-line=\"\">Text.ReplacePartialMatches_impl = (\n        source as text, mapping as table\n    ) as text =&gt; ...<\/code><\/pre>\n\n\n\n<p>To create the type, you start your <code class=\"\" data-line=\"\">function type<\/code> almost the exact same as the definition. Then wrap it inside a <code class=\"\" data-line=\"\">type function<\/code> <\/p>\n\n\n\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"language-powerquery\" data-line=\"\">Text.ReplacePartialMatches.Type = type function(\n        source as text,\n        mapping as table\n    ) as text meta [ .. ]<\/code><\/pre>\n\n\n\n<p>Next you start adding records to the final type&#8217;s metadata. If you haven&#8217;t seen the <code class=\"\" data-line=\"\">meta<\/code> operator, check out Ben&#8217;s series:<\/p>\n\n\n\n<figure class=\"wp-block-embed is-type-wp-embed is-provider-ben-gribaudo wp-block-embed-ben-gribaudo\"><div class=\"wp-block-embed__wrapper\">\n<blockquote class=\"wp-embedded-content\" data-secret=\"pP4XBfeUV4\"><a href=\"https:\/\/bengribaudo.com\/blog\/2021\/03\/17\/5523\/power-query-m-primer-part20-metadata\">Power Query M Primer (Part 20): Metadata<\/a><\/blockquote><iframe class=\"wp-embedded-content\" sandbox=\"allow-scripts\" security=\"restricted\" style=\"position: absolute; clip: rect(1px, 1px, 1px, 1px);\" title=\"&#8220;Power Query M Primer (Part 20): Metadata&#8221; &#8212; Ben Gribaudo\" src=\"https:\/\/bengribaudo.com\/blog\/2021\/03\/17\/5523\/power-query-m-primer-part20-metadata\/embed#?secret=fNhVRKFfJ7#?secret=pP4XBfeUV4\" data-secret=\"pP4XBfeUV4\" width=\"580\" height=\"327\" frameborder=\"0\" marginwidth=\"0\" marginheight=\"0\" scrolling=\"no\"><\/iframe>\n<\/div><\/figure>\n\n\n\n<p>The part that comes after <code class=\"\" data-line=\"\">meta<\/code> operator is a regular <code class=\"\" data-line=\"\">record<\/code><\/p>\n\n\n\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"language-powerquery\" data-line=\"\">let\n    Text.ReplacePartialMatches = Value.ReplaceType( Text.ReplacePartialMatches_impl, Text.ReplacePartialMatches.Type ),\n    Text.ReplacePartialMatches.Type = type function(\n        source as text,\n        mapping as Table.Type\n    ) as text meta [\n        Documentation.Name = &quot;Text.ReplacePartialMatches&quot;,\n        Documentation.LongDescription = Text.Combine({\n            &quot;Test strings for partial text matches. Replace the entire cell\/value with the new replacement text.&quot;,\n            &quot;&quot;,\n            &quot;Mapping table requires two columns: &lt;code&gt;[Partial]&lt;\/code&gt; and &lt;code&gt;[New Value]&lt;\/code&gt; &quot;\n\n        }, &quot;&lt;br&gt;&quot;)\n    ],\n\n    Text.ReplacePartialMatches_impl = ( source as text, mapping as table ) as text =&gt;\n        \/\/ todo: performance, exit early on first replacement\n        let\n            mappingList = Table.ToRecords( mapping ),\n            result = List.Accumulate(\n                mappingList,\n                source,\n                (state, cur) =&gt;\n                    if Text.Contains( state, cur[Partial], Comparer.OrdinalIgnoreCase )\n                    then cur[New Value] else state\n            )\n        in result\n\nin\n    Text.ReplacePartialMatches<\/code><\/pre>\n\n\n\n<h2>Query For the Screenshot<\/h2>\n\n\n\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"language-powerquery\" data-line=\"\">let\n    Custom1 = Value.Type( Value.Type( Table.FromRecords ) ),\n    fn_typeMeta = Value.Metadata( Value.Type( Table.FromRecords ) ),\n    fn_typeMeta_example = ( Value.Metadata( Value.Type( Table.FromRecords ) )[Documentation.Examples]){1},\n    t_fnParams = Type.FunctionParameters( Value.Type( Table.FromRecords ) ),\n    fn_metaType = Value.Metadata( Type.FunctionParameters( Value.Type( Table.FromRecords ) ) ),\n    type_ofFuncType = Value.Type( Type.FunctionParameters( Value.Type( Table.FromRecords ) ) [missingField] ),\n    type_param_ofFuncType = Value.Metadata( Type.FunctionParameters( Value.Type( Table.FromRecords ) )[missingField] ),\n    required_ofFuncType = Type.FunctionRequiredParameters( Value.Type( Table.FromRecords ) ) ,\n    type_ofRequiredType = Value.Type( Type.FunctionRequiredParameters( Value.Type( Table.FromRecords ) ) ),\n    type_ofType_ofRequiredType = Value.Metadata( Value.Type( Type.FunctionRequiredParameters( Value.Type( Table.FromRecords ) ) ) )\n    \nin\n    type_ofType_ofRequiredType<\/code><\/pre>\n\n\n\n<h2>Related Posts<\/h2>\n\n\n\n<figure class=\"wp-block-embed is-type-wp-embed is-provider-ninmonkey wp-block-embed-ninmonkey\"><div class=\"wp-block-embed__wrapper\">\n<blockquote class=\"wp-embedded-content\" data-secret=\"RbnWCemLTm\"><a href=\"http:\/\/ninmonkeys.com\/blog\/2024\/06\/01\/power-query-capturing-response-metadata-from-web-contents\/\">Capturing Metadata of your Web.Contents calls &#8211; Using REST APIs in Power Query<\/a><\/blockquote><iframe class=\"wp-embedded-content\" sandbox=\"allow-scripts\" security=\"restricted\" style=\"position: absolute; clip: rect(1px, 1px, 1px, 1px);\" title=\"&#8220;Capturing Metadata of your Web.Contents calls &#8211; Using REST APIs in Power Query&#8221; &#8212; Ninmonkey\" src=\"http:\/\/ninmonkeys.com\/blog\/2024\/06\/01\/power-query-capturing-response-metadata-from-web-contents\/embed\/#?secret=RbnWCemLTm\" data-secret=\"RbnWCemLTm\" width=\"580\" height=\"327\" frameborder=\"0\" marginwidth=\"0\" marginheight=\"0\" scrolling=\"no\"><\/iframe>\n<\/div><\/figure>\n\n\n\n<h2>Related Links<\/h2>\n\n\n\n<ul><li><a href=\"https:\/\/learn.microsoft.com\/en-us\/power-query\/handlingdocumentation\">Docs\/Handling Documentation<\/a><\/li><li><a href=\"https:\/\/learn.microsoft.com\/en-us\/powerquery-m\/metadata\">Docs\/Metadata<\/a><\/li><li><a href=\"https:\/\/github.com\/ninmonkey\/ninMonkQuery-examples\/blob\/30a80d527a5b79ed7607834077a234f1dd0d2015\/Types\/pq\/joining-text%20as%20pipes%20from%20auto-coerced-column-values.pq\">An example using html tables in the documentation<\/a><\/li><\/ul>\n\n\n\n<h2>Related Functions<\/h2>\n\n\n\n<ul><li><a href=\"https:\/\/learn.microsoft.com\/en-us\/powerquery-m\/value-metadata\">Value Functions<\/a> <\/li><li><a href=\"https:\/\/learn.microsoft.com\/en-us\/powerquery-m\/type-functions\" data-type=\"URL\" data-id=\"https:\/\/learn.microsoft.com\/en-us\/powerquery-m\/type-functions\">Type Functions<\/a><\/li><\/ul>\n\n\n\n<figure class=\"wp-block-embed is-type-wp-embed is-provider-ben-gribaudo wp-block-embed-ben-gribaudo\"><div class=\"wp-block-embed__wrapper\">\n<blockquote class=\"wp-embedded-content\" data-secret=\"yC7YUzPHz5\"><a href=\"https:\/\/bengribaudo.com\/blog\/2021\/09\/21\/6179\/describing-function-record-parameters\">Describing a Function&#8217;s Record Parameters<\/a><\/blockquote><iframe class=\"wp-embedded-content\" sandbox=\"allow-scripts\" security=\"restricted\" style=\"position: absolute; clip: rect(1px, 1px, 1px, 1px);\" title=\"&#8220;Describing a Function&#8217;s Record Parameters&#8221; &#8212; Ben Gribaudo\" src=\"https:\/\/bengribaudo.com\/blog\/2021\/09\/21\/6179\/describing-function-record-parameters\/embed#?secret=nLGSNbnkvq#?secret=yC7YUzPHz5\" data-secret=\"yC7YUzPHz5\" width=\"580\" height=\"327\" frameborder=\"0\" marginwidth=\"0\" marginheight=\"0\" scrolling=\"no\"><\/iframe>\n<\/div><\/figure>\n\n\n\n<figure class=\"wp-block-embed is-type-wp-embed is-provider-ben-gribaudo wp-block-embed-ben-gribaudo\"><div class=\"wp-block-embed__wrapper\">\n<blockquote class=\"wp-embedded-content\" data-secret=\"dKvJUFCOmW\"><a href=\"https:\/\/bengribaudo.com\/blog\/2020\/06\/02\/5259\/power-query-m-primer-part18-type-system-iii-custom-types\">Power Query M Primer (Part 18): Type System III \u2013 Custom Types<\/a><\/blockquote><iframe class=\"wp-embedded-content\" sandbox=\"allow-scripts\" security=\"restricted\" style=\"position: absolute; clip: rect(1px, 1px, 1px, 1px);\" title=\"&#8220;Power Query M Primer (Part 18): Type System III \u2013 Custom Types&#8221; &#8212; Ben Gribaudo\" src=\"https:\/\/bengribaudo.com\/blog\/2020\/06\/02\/5259\/power-query-m-primer-part18-type-system-iii-custom-types\/embed#?secret=E3SNlBaK6j#?secret=dKvJUFCOmW\" data-secret=\"dKvJUFCOmW\" width=\"580\" height=\"327\" frameborder=\"0\" marginwidth=\"0\" marginheight=\"0\" scrolling=\"no\"><\/iframe>\n<\/div><\/figure>\n","protected":false},"excerpt":{"rendered":"<p>PowerQuery has metadata that you don&#8217;t normally see. For example, take the function Table.FromRecords Create a new blank query, and set the value to a function&#8217;s name. When you reference a function without arguments or parenthesis, it displays documentation. ( It&#8217;s mostly the same as the online docs ) Where does this come from? A [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":2536,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[72,13,9,1],"tags":[133,117,6,7],"_links":{"self":[{"href":"https:\/\/ninmonkeys.com\/blog\/wp-json\/wp\/v2\/posts\/2497"}],"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=2497"}],"version-history":[{"count":41,"href":"https:\/\/ninmonkeys.com\/blog\/wp-json\/wp\/v2\/posts\/2497\/revisions"}],"predecessor-version":[{"id":2804,"href":"https:\/\/ninmonkeys.com\/blog\/wp-json\/wp\/v2\/posts\/2497\/revisions\/2804"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/ninmonkeys.com\/blog\/wp-json\/wp\/v2\/media\/2536"}],"wp:attachment":[{"href":"https:\/\/ninmonkeys.com\/blog\/wp-json\/wp\/v2\/media?parent=2497"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/ninmonkeys.com\/blog\/wp-json\/wp\/v2\/categories?post=2497"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/ninmonkeys.com\/blog\/wp-json\/wp\/v2\/tags?post=2497"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}