{"id":2855,"date":"2024-06-05T22:27:11","date_gmt":"2024-06-06T03:27:11","guid":{"rendered":"http:\/\/ninmonkeys.com\/blog\/?p=2855"},"modified":"2024-06-05T22:31:10","modified_gmt":"2024-06-06T03:31:10","slug":"power-query-functions-part1-using-optional-parameters","status":"publish","type":"post","link":"https:\/\/ninmonkeys.com\/blog\/2024\/06\/05\/power-query-functions-part1-using-optional-parameters\/","title":{"rendered":"Power Query Functions ( Part 1): Introduction to Optional Parameters"},"content":{"rendered":"\n\n\n<p><a href=\"https:\/\/github.com\/ninmonkey\/Ninmonkey.PowerQueryLib\/blob\/bf4e1d63b8bb9ffe3b3e4df0d687435bb88be30d\/Examples-Blog\/Custom%20Functions\/Part%201%20-%20Using%20Optional%20Parameters.pq\">You can view the final .pq query here <\/a><\/p>\n\n\n\n<h2>3 Main Methods to Declare Optional Parameters<\/h2>\n\n\n\n<p>There&#8217;s 3 main ways you can declare optional parameters in your own functions.<\/p>\n\n\n\n<ol><li>By setting your parameter type to nullable type. <br><br><code class=\"\" data-line=\"\">name as text<\/code> becomes<br><code class=\"\" data-line=\"\">name as nullable text<\/code><br><br>This version requires you to always pass something, even if it&#8217;s null.<br><br><\/li><li>By setting the type to optional like<br><br><code class=\"\" data-line=\"\">optional name as nullable text<\/code> . You can shorten it by skipping the nullable part<br><code class=\"\" data-line=\"\">optional name as text<\/code> ( <a href=\"https:\/\/learn.microsoft.com\/en-us\/powerquery-m\/m-spec-types#function-types\">Because optional parameters are implicitly nullable<\/a> )<br><br><br>Unlike #1, you can skip optional parameters when calling functions. <br><br><\/li><li>By using a <code class=\"\" data-line=\"\">record<\/code> parameter. <br><br>Usually it&#8217;s a <code class=\"\" data-line=\"\">optional options as record<\/code><br><br>This lets you call a function with any combination of keyword arguments.<br><br><\/li><li>Merging Default Values With the User&#8217;s Record<\/li><\/ol>\n\n\n\n<p>With record parameters you can merge the user&#8217;s record with your your own default values. <br>It lets the user pick and choose which defaults to override &#8212; <strong>compared to using nulls as an &#8220;all-or-nothing&#8221; approach<\/strong>. I&#8217;ll cover this in a future post.<\/p>\n\n\n\n<h2>Creating Your Own Custom Functions <\/h2>\n\n\n\n<p>Let&#8217;s write a wrapper that calls <a href=\"https:\/\/learn.microsoft.com\/en-us\/powerquery-m\/text-combine\">Text.Combine<\/a> . It&#8217;s a simple example to see how the parameter types differ<\/p>\n\n\n\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"language-powerquery\" data-line=\"\">    Join_Nullable = (texts as list, separator as nullable text) =&gt;\n        Text.Combine( texts, separator ),\n\n    Join_Optional = (texts as list, optional separator as text) =&gt;\n        Text.Combine( texts, separator ),<\/code><\/pre>\n\n\n\n<h3>Type 1: Using Nullable Parameters<\/h3>\n\n\n\n<p>Regular nullable parameters are still mandatory. Even if it&#8217;s null. <\/p>\n\n\n\n<div class=\"wp-block-columns\">\n<div class=\"wp-block-column\" style=\"flex-basis:100%\">\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"language-powerquery\" data-line=\"\">\/\/ input [1]\nJoin_Nullable( chars, &quot;, &quot; )\n\n\/\/ input [2]\nJoin_Nullable( chars, null )\n\n\/\/ input [3]\nJoin_Nullable( chars )<\/code><\/pre>\n\n\n\n<p><\/p>\n<\/div>\n\n\n\n<div class=\"wp-block-column\" style=\"flex-basis:100%\">\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"language-powerquery\" data-line=\"\">\/\/ output [1]\na, b, c, d, e, f, g, h\n\n\/\/ output [2]\nabcdefgh\n\n\/\/ output [3]\nError: 1 arguments were passed\nto a function which expects 2.<\/code><\/pre>\n\n\n\n<p><\/p>\n<\/div>\n<\/div>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large is-resized\"><img loading=\"lazy\" src=\"https:\/\/ninmonkeys.com\/blog\/wp-content\/uploads\/2024\/06\/Blog-Post-Article-Image.2024-05-30.png\" alt=\"\" class=\"wp-image-2900\" width=\"719\" height=\"434\" srcset=\"https:\/\/ninmonkeys.com\/blog\/wp-content\/uploads\/2024\/06\/Blog-Post-Article-Image.2024-05-30.png 719w, https:\/\/ninmonkeys.com\/blog\/wp-content\/uploads\/2024\/06\/Blog-Post-Article-Image.2024-05-30-300x181.png 300w\" sizes=\"(max-width: 719px) 100vw, 719px\" \/><\/figure><\/div>\n\n\n\n<h3>Type 2: Optional Parameters<\/h3>\n\n\n\n<p>If functions end with optional parameters, you can skip them entirely.<\/p>\n\n\n\n<div class=\"wp-block-columns\">\n<div class=\"wp-block-column\" style=\"flex-basis:100%\">\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"language-powerquery\" data-line=\"\">\/\/ input [1]\nJoin_Optional( chars, &quot;, &quot; )\n\n\/\/ input [2]dfsdf\nJoin_Optional( chars, null )\n\n\/\/ input [3]\nJoin_Optional( chars )<\/code><\/pre>\n<\/div>\n\n\n\n<div class=\"wp-block-column\" style=\"flex-basis:100%\">\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"language-powerquery\" data-line=\"\">\/\/ output [1]\na, b, c, d, e, f, g, h\n\n\/\/ output [2]\nabcdefghfds\n\n\/\/ output [3]\nabcdefghfds<\/code><\/pre>\n\n\n\n<p><\/p>\n<\/div>\n<\/div>\n\n\n\n<h2>Type 3 Examples: Using Optional Records<\/h2>\n\n\n\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"language-powerquery\" data-line=\"\">Text.JoinString = (strings as list, optional options as record) as text =&gt; let\n        Prefix    = options[Prefix]?    ?? &quot;&quot;,\n        Suffix    = options[Suffix]?    ?? &quot;&quot;,\n        Delimiter = options[Delimiter]? ?? &quot;,&quot;\n    in\n        Prefix &amp; Text.Combine( strings, Delimiter ) &amp; Suffix<\/code><\/pre>\n\n\n\n<p>You can mix and match any combinations of the keys <strong>Prefix<\/strong>, <strong>Suffix<\/strong>, and <strong>Delimiter<\/strong> .<\/p>\n\n\n\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"language-powerquery\" data-line=\"\">names = {&quot;Jen&quot;, &quot;Hubert&quot;, &quot;Nobody&quot;, &quot;Somebody&quot; },\n\nDefault       = Text.JoinString( names ) ,\nAsCsv         = Text.JoinString( names, [ Delimiter = &quot;, &quot;] ),\n\nAsTablePipes  = Text.JoinString( names, [\n    Prefix = &quot;| &quot;, Delimiter = &quot; | &quot;, Suffix = &quot; |&quot; ] ),\n\nAsBullets     = Text.JoinString( names, [\n    Prefix    = &quot; #(2022) &quot;,\n    Delimiter = &quot; #(cr,lf) #(2022) &quot;\n])<\/code><\/pre>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" width=\"611\" height=\"440\" src=\"https:\/\/ninmonkeys.com\/blog\/wp-content\/uploads\/2024\/06\/part3-Blog-Post-Article-Image.2024-05-30.png\" alt=\"\" class=\"wp-image-2944\" srcset=\"https:\/\/ninmonkeys.com\/blog\/wp-content\/uploads\/2024\/06\/part3-Blog-Post-Article-Image.2024-05-30.png 611w, https:\/\/ninmonkeys.com\/blog\/wp-content\/uploads\/2024\/06\/part3-Blog-Post-Article-Image.2024-05-30-300x216.png 300w\" sizes=\"(max-width: 611px) 100vw, 611px\" \/><\/figure>\n\n\n\n<h2>Examples In The Standard Library<\/h2>\n\n\n\n<h3>Type 2 Examples: Optional Parameters<\/h3>\n\n\n\n<p>When you import columns with <a href=\"https:\/\/learn.microsoft.com\/en-us\/powerquery-m\/table-transformcolumntypes\">Table.TransformColumnTypes<\/a>, the UI doesn&#8217;t include the culture parameter. Unless you choose &#8220;using locale&#8221;. <\/p>\n\n\n\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"language-powerquery\" data-line=\"\">\/\/ it&#039;s declared as\nTable.TransformColumnTypes( \n     table as table, typeTransformations as list,\n     optional culture as text) as table\n\n\/\/ The GUI skips the culture parameter \n= Table.TransformColumnTypes( Source,{  {&quot;Date&quot;, type text}} )\n\n\/\/ if you click on &quot;locale&quot;\n= Table.TransformColumnTypes( Source,{  {&quot;Date&quot;, type text}}, &quot;en-GB&quot; )<\/code><\/pre>\n\n\n\n<h3>Type 3 Examples: Using Optional Records<\/h3>\n\n\n\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"language-powerquery\" data-line=\"\">\/\/ It&#039;s declared as\nDateTime.FromText( text as nullable text, optional options as any) as nullable datetime\n\n\/\/ without the optional parameter\n= DateTime.FromText(&quot;2010-12-31T01:30:25&quot;)\n\n\/\/ They pass 2 keyword-style arguments.\n= DateTime.FromText(\n     &quot;30 Dez 2010 02:04:50.369730&quot;, \n     [ \n          Format = &quot;dd MMM yyyy HH:mm:ss.ffffff&quot;, \n          Culture=&quot;de-DE&quot; \n     ] )<\/code><\/pre>\n\n\n\n<p>Why does <a href=\"https:\/\/learn.microsoft.com\/en-us\/powerquery-m\/datetime-fromtext\">DateTime.FromText<\/a> use <strong>options as any<\/strong> and not <strong>options as record<\/strong> ? In this case it&#8217;s for backwards compatibility. If they were writing it from scratch today, it could have used a record. Older versions used a <code class=\"\" data-line=\"\">type text<\/code> parameter.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>You can view the final .pq query here 3 Main Methods to Declare Optional Parameters There&#8217;s 3 main ways you can declare optional parameters in your own functions. By setting your parameter type to nullable type. name as text becomesname as nullable text This version requires you to always pass something, even if it&#8217;s null. [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":2945,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[150,13,9],"tags":[160,162,159,161,6,7],"_links":{"self":[{"href":"https:\/\/ninmonkeys.com\/blog\/wp-json\/wp\/v2\/posts\/2855"}],"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=2855"}],"version-history":[{"count":91,"href":"https:\/\/ninmonkeys.com\/blog\/wp-json\/wp\/v2\/posts\/2855\/revisions"}],"predecessor-version":[{"id":2950,"href":"https:\/\/ninmonkeys.com\/blog\/wp-json\/wp\/v2\/posts\/2855\/revisions\/2950"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/ninmonkeys.com\/blog\/wp-json\/wp\/v2\/media\/2945"}],"wp:attachment":[{"href":"https:\/\/ninmonkeys.com\/blog\/wp-json\/wp\/v2\/media?parent=2855"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/ninmonkeys.com\/blog\/wp-json\/wp\/v2\/categories?post=2855"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/ninmonkeys.com\/blog\/wp-json\/wp\/v2\/tags?post=2855"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}