PowerQuery 格式化工具及格式化 API 调用

话说DAX的格式化工具出来很久了,M的格式化工具一直不见踪影,这让不少小伙伴心里不平衡了,,,
不过已经有人做出了这款工具,并且提供了免费调用API,下面一起来看一看这款工具。

https://powerqueryformatter.com

file
我们只需要在上图的红框内写下M语句,然后根据需要设置下面的格式化参数选项Options后点击Format即可帮我们格式化好我们的M语句。
file
格式化后的效果如下:
file
提一下Options的几个主要参数:
缩进字符数:Indentation
行宽:Line width
括号类别数:Number of brackets
标签CSS样式:InlineCss
除以上这些还有一些参数,从API参考文档可以知悉:

https://powerqueryformatter.com/api

Post定义的body部分的定义为:

{
     code: string,
     config: IConfig
}

其中code为我们需要格式化的M语句,config就是咱们需要设置的格式化参数。
config的具体定义如下:

{
    //用于缩进的字符串,默认=“  ”
    indentation: string;
   //缩进字符串的长度(用于确定何时达到最大线宽)
    indentationLength: number;
    //用于终止行的字符串,默认=“ <br/>”
    lineEnd: string;
    //用作空格的字符串,默认=“&nbsp;”
    ws: string;
   //最大线宽,默认值为100。如果达到最大线宽,格式化程序会强制表达式分成几行。请不要将某些表达式不能分成多行,例如很长的标识符,因此在这种情况下可以超过最大行宽。截至目前,尚无警告可为您提供有关此信息。
    lineWidth: number;
    //不同括号类别的数量,默认=3。格式化程序将括号对分配给类别'bracket'和'bracket- {num}',其中num = 1 ... {numBrackets}。然后,您可以使用可配置的深度设置匹配括号的样式。
    numBrackets: number;
   //所有文本(代码)均转义为html格式,默认= true。
    escapeHtmlText: boolean;
    //用成对的等号对齐配对的表达式,默认= false。
    alignPairedExpressionsByEqual: boolean;
    //如果为null,则格式化程序会将类放到生成的html上,但不放置样式(可用于您要用css自己设置格式化html样式的网站)。如果非null,则类将转换为html元素上的内联样式。
    inlineCss: string;
}

工具开发者在Github给出了一个API调用案例:

https://github.com/mogular/powerquery-formatter-examples

通过查看js文件

https://github.com/mogular/powerquery-formatter-examples/blob/master/src/example.js

我们尝试配置PowerQuery中调用该API接口的参数:
API调用地址:https://m-formatter.azurewebsites.net/api/format/v1
Header中Content-Type:application/json
POST请求body部分:

{code:"let a=1,b=2,c=3 in a+b/c",
config: 
    {indentation:"&nbsp;&nbsp;",
        indentationLength:2,
        lineEnd:"<br/>",
        ws:"&nbsp;",
        lineWidth:100,
        numBrackets:3,
        escapeHtmlText:true,
        alignPairedExpressionsByEqual:false,
        inlineCss:Css样式文本}
    }

先使用简单的形式,部分默认参数不传输进去:

Json.Document(Web.Contents("https://m-formatter.azurewebsites.net/api/format/v1", [Content
  = Json.FromValue([code = "let a=1,b=2 in a+b", config = [
  indentation = "&nbsp;&nbsp;", 
  indentationLength = 2, 
  lineEnd = "<br/>", 
  ws = "&nbsp;", 
  lineWidth = 100, 
  numBrackets = 3
]])]))[result]

返回:
file
由于返回的是HTML相关网页元素,所以无法直接查看,我们可以将返回结果放入txt中另存为html文件用浏览器打开就可以看到最终格式化的M效果,也可以使用htmlViewer.1.0.2.0.pbiviz(应用商店貌似下线了,找保存到本地的资源)可视化对象在PowerBI中查看效果:
file
file
如果想要美化直接添加相关设置参数即可!

如果不考虑颜色字号等信息,直接在PQ显示换行和缩进可以使用:

Html.Table(Text.Replace(Json.Document(Web.Contents("https://m-formatter.azurewebsites.net/api/format/v1", [Content
  = Json.FromValue([code = "let a=1,b=2 in a+b", config = [
  indentation = "  ", 
  indentationLength = 2, 
  lineEnd = "<br/>", 
  ws = " ", 
  lineWidth = 100, 
  numBrackets = 3
]])]))[result],"<br>","#(lf)"),{{"格式化","div"}})

或者

Html.Table(Text.Replace(Text.FromBinary(Web.Contents("https://m-formatter.azurewebsites.net/api/format/v1", [Content
  = Json.FromValue([code = "let a=1,b=2 in a+b", config = [
  indentation = "  ", 
  indentationLength = 2, 
  ws = " "
]])])),"<br>","#(lf)"),{{"格式化","div"}})

file
尝试格式化下面超长代码,效果还不错:

let                                         
fx = (path)=>let                                         
Header = BinaryFormat.Record([MiscHeader = BinaryFormat.Binary(14),BinarySize = BinaryFormat.ByteOrder(BinaryFormat.UnsignedInteger32,0),FileSize   = BinaryFormat.ByteOrder(BinaryFormat.UnsignedInteger32,0),                                          
FileNameLen= BinaryFormat.ByteOrder(BinaryFormat.UnsignedInteger16,0),ExtrasLen  = BinaryFormat.ByteOrder(BinaryFormat.UnsignedInteger16,0)]),                                            
HeaderChoice = BinaryFormat.Choice(BinaryFormat.ByteOrder(BinaryFormat.UnsignedInteger32,0),each if _ <> 67324752 then BinaryFormat.Record([IsValid = false,Filename=null,Content=null])                                            
else BinaryFormat.Choice(BinaryFormat.Binary(26), each BinaryFormat.Record([IsValid  = true,                                          
Filename = BinaryFormat.Text(Header(_)[FileNameLen]),Extras   = BinaryFormat.Text(Header(_)[ExtrasLen]),  
Content  = BinaryFormat.Transform(BinaryFormat.Binary(Header(_)[BinarySize]),(x) => try Binary.Buffer(Binary.Decompress(x, Compression.Deflate)) otherwise null)]), type binary)),                                          
ZipFormat = BinaryFormat.List(HeaderChoice, each [IsValid]),Entries=List.Transform(List.RemoveLastN(ZipFormat(File.Contents(path)),1),(e)=>[FileName=e[Filename],Content=e[Content]])                                           
in Entries                                         
in fx

file
file

道高一尺 魔高一丈
https://pbihub.cn/users/44
M与DAX的恩怨纠葛