飞天篮球

边齐
第 3 位会员
注册于 2018-08-08 14:57:03
活跃于 2020-04-01 16:24:24


  • 城市
Talk is cheap, show me your code.
专栏文章
没有任何数据~~
最近问题
没有任何数据~~
最新评论
  • List.Generate 使用中的一个问题 at 2020-08-26 21:47:05

    越界容错,所有用{a}深化的地方改成{a}?

  • 合并查询中 “其他” 情况应该怎样处理? at 2020-01-20 22:42:08

    fyi... 以下List.ReplaceRange中常量3的意思是在奖金这个列表中,“其它”之前插入一个值:

    = Table.FromRecords( 
                        List.Transform( Table.ToRecords(姓名),
                                        (x)=> List.Mode(
                                                        List.ReplaceRange(Table.ToRecords(奖金),3,0,{x}),
                                                         each [姓名] ) &x ) 
                        )

    file

  • 如何把列表中的元素对应加入另一个列表中? at 2020-01-19 19:47:17

    fyi...结果1,结果2都可以。结果1容易点,zip一下,一一对应。

    = let a = {{"a","b","c"},{"d","e","f"},{"h","i","j"}}, 
          b = {"w","x","y"},
    
          结果1 = List.Transform(List.Zip({a,b}),each _{0}&{_{1}}),
    
          结果2 = List.Accumulate( {0..2},
                                    a,
                                   (s,c)=>List.ReplaceRange(s,c,1,{s{c}&{b{c}}}))  
      in 
          结果1
  • power bi 如何实现两张表之间的计算建模? at 2020-01-11 08:44:20

    @王德福 源文件删掉了。。。你把自己的表一个个导入pq编辑器,再试试吧。

  • power bi 如何实现两张表之间的计算建模? at 2020-01-10 19:07:22

    不知道有没有理解错题意...仅供参考

    题目中的左表是表1,右表是表2

    = 表2 &
      Table.FromList( Table.ToRows(表1),
                      (x)=>{x{0},"剩余",x{1}-List.Sum(Table.SelectRows(表2,each [日期]=x{0})[消费金额])},
                      Table.ColumnNames(表2) )

    file

  • 工作需要,想用 power query 作一个 现金日记账,但始终实现不了,请大神帮忙 at 2020-01-06 22:10:35

    左表变成右表

    file

  • 工作需要,想用 power query 作一个 现金日记账,但始终实现不了,请大神帮忙 at 2020-01-06 22:04:13

    试试List.Generate,加载20万行还是很快的

    let
        源 = Excel.CurrentWorkbook(){[Name="表1"]}[Content],
    
        gen = let lst = List.Buffer(Table.ToRows(源)), 
                    n = List.Count(lst)
    
               in List.Generate( ()=>{{},"",0,0,0,0}, //{结果list,月份比较值,累计值,借方合计,贷方合计,索引}
                                 each _{5}<=n,
                                 each let l = lst{_{5}}?,
                                          c = if l=null then {} else l,
                                          m = Date.Month(c{0}?), 
                                          s = _{2}+List.Sum({c{2}?,c{3}?*-1}) 
    
                                       in if m=_{1} then { {c&{s}},m,s,List.Sum({_{3},c{2}?}),List.Sum({_{4},c{3}?}),_{5}+1}
                                          else {{{"","本月合计",_{3},_{4},_{2}},c&{s}},m,s,c{2}?,c{3}?,_{5}+1},
                                 each _{0} ),
    
        rlt = #table(Table.ColumnNames(源)&{"余额"}, List.Skip(List.Combine(gen)))
    in
        rlt
  • 筛选表的几种方法效率比较 at 2020-01-01 20:51:27

    @阿森纳里

    其实用这一步,Table.Combine(List.Repeat({Table.Buffer(源)},100000))扩充数据量不好 。Table.Combine是很耗资源的。我觉得比较妥当的还是数据源有100万行,测试会准确一些,不要在步骤里去构建。Table.SelectRows+List.Contains不慢的,150万行还是能胜任的。常量枚举,在筛选条件少的时候枚举一下也行。fyi!

  • PQ 问题,求解答 at 2019-11-21 11:27:45

    @焦棚子
    这样的话,前面都不变,group里边多写一步排序,比如:
    .........Table.Group(源,"销售经理",{"达标日期",each [a=Table.Sort(_,"销售日期"),b=fx(a,a[销售金额],1)[销售日期]?][b]},1)
    看看行不行?

  • PQ 问题,求解答 at 2019-11-21 10:29:12

    fyi

    = let fx=(x,y,z)=>if List.Sum(y)<10 then [] else 
                      if List.Sum(List.FirstN(y,z))>=10 then x{z-1}
                      else @fx(x,y,z+1) 
       in Table.Group(源,"销售经理",{"达标日期",each fx(_,[销售金额],1)[销售日期]?},1)

    file

  • 计数问题,请高手解答一下 at 2019-10-30 21:53:15
    let
        源 = Excel.CurrentWorkbook(){[Name="demo"]}[Content],
    
        acc = List.Accumulate( Table.ToRecords(源),
                               {{},"",0},
                               (s,c)=>if c[条件]="T13" then 
                                                           if s{1}="T13" then 
                                                           {s{0}&{c&[结果=s{2}]},c[条件],1} 
                                                           else {s{0}&{c&[结果=null]},c[条件],1} 
                                      else {s{0}&{c&[结果=null]},s{1},s{2}+1} ),
    
        rlt = Table.FromRecords(acc{0})
    in
        rlt
  • 计数问题,请高手解答一下 at 2019-10-30 21:50:55

    fyi...

    = let a = Table.PositionOf(源,[条件="T13"],2,each [条件]),
          b = List.Zip({a,{null}&a}),
          c = List.TransformMany( b,
                                  each if _{0}=null then {} else 
                                       if _{1}=null then List.Repeat({null},_{0})&{0} else 
                                       List.Repeat({null},_{0}-_{1}-1)&{_{0}-_{1}},
                                  (x,y)=>y )
      in Table.FromColumns( Table.ToColumns(源)&{c}, Table.ColumnNames(源)&{"结果"} )
  • 两个查询表之间 条件列 判断 是否包含第二个表 列文本 ? at 2019-03-05 11:28:17

    @秋风一达
    把最终结果手动模拟一个出来,就拿第一行为例。有什么特殊情况也一并模拟。

  • 两个查询表之间 条件列 判断 是否包含第二个表 列文本 ? at 2019-03-05 10:05:38

    是这样吗?

    = Table.AddColumn(更改的类型, "自定义", each List.Select(List.RemoveNulls(List.Distinct(词分类[修饰词])),(x)=>Text.Contains([宝贝标题],x)))

    file

  • 表格转换 at 2019-02-27 21:10:49

    @明仔
    那部分是Table.Group分组的第五参数,不能省略。

  • Table.ExpandListColumn 怎么实现同时展开一个表格多行里面的 list at 2019-01-27 23:20:14

    猜一下,展开的“self” 这一步之后,添加一步:

    = Table.FromColumns(List.Transform( Table.ToColumns(#"展开的“self”"),List.Combine),Table.ColumnNames(#"展开的“self”"))

  • 对多级 BOM 文本列进行正确排序 at 2019-01-20 16:48:04

    关于M+JS用“0”补齐位数,经畅心老板斧正,精炼了一下写法。一是JS中的自定义补齐函数用了递归,这样的好处是避免了上述补充方法中需要人为目测一个最长的连续数字长度的做法,可以做到不够位数则补全,足位数的保持原来的状态;第二个是效仿了M的隐式传递,精简了语句。比如,以下例子中把连续数字不足5位的用0补全,其中的function Pad...return Pad就是JS中的递归, replace正则替换的第二参数可以是function,且做了隐式传递,这类似于M中的List.Transform({"1".."3"},Number.From)省略了each _这样的写法。

    以下写法是把补全长度在UDF中写成了一个常量:

    = Web.Page("<script>function Pad(s) {if(s.length>=5) {return s}return Pad('0'+s)}
                        document.write('8WD.123456.371B-10-A-2'.replace(/\d+/g,Pad))
               </script>")[Data]{0}[Children]{0}[Children]{1}[Text]{0}
    

    结果如下图:

    file

    如果要传递双参数,比如字符串对象和补全长度都作为参数,那就要这样写:

    = Web.Page("<script>function Pad(s,len) {if(s.length>=len) {return s} return Pad('0'+s,len)}
                        document.write('8WD.123456.371B-10-A-2'.replace(/\d+/g,function(x){return Pad(x,5)}))
                </script>")[Data]{0}[Children]{0}[Children]{1}[Text]{0}

    从Table.Sort第二参数的写法构造引申出这些内容,个人觉得信息量不少。

    以上供参考,不妥之处请指正。

  • 对多级 BOM 文本列进行正确排序 at 2019-01-19 22:21:51

    有朋友没有更新到最新版本的PQ,没有Splitter.SplitTextByCharacterTransition,这个函数有点像正则里的零宽,断的只是一个位置。再提供两种补位的方法:

    一个是用JS自定义补位,并配合replace把字符串中的数字替换成补位后的文本数值,优点是简洁,缺点是效率欠佳:
    单独的M+JS数字补位方法,连续数字用“0”补全为10位,这个补位的取值必须要大于最大连续数字字符串的长度:

    = Web.Page("<script>function Pad(num, len) {return (Array(len).join('0') + num).slice(-len);}
                        document.write('8WD.199.371B-10-A-2'.replace(/\d+/g,function(x){return Pad(x,10)}))
                      </script>")[Data]{0}[Children]{0}[Children]{1}[Text]{0}

    运用到排序里:

    let
        源 = Excel.CurrentWorkbook(){[Name="表1"]}[Content],
    
        排序 = Table.Sort(源, each Web.Page("<script> function Pad(num, len) {return (Array(len).join('0') + num).slice(-len)}
                                                     document.write('"&[#"Excel排序功能-升序结果"]&"'.replace(/\d+/g,function(x){return Pad(x,20)}))
                                           </script>")[Data]{0}[Children]{0}[Children]{1}[Text]{0})
    in
        排序

    另一种是用List.Accumulate对字符串中的数字进行补位,本来以为用acc会简单一点,写完奔溃了,有点复杂,就当交流参考吧。希望大神能优化一下acc的写法。

    单独的accumulate补位语句,连续数字用“0”补全为5位:

    = let l=Text.ToList("8WD.199.371B-10-A-1") 
              in List.Accumulate( l&({{"1"},{""}}{Byte.From(List.Contains({"0".."9"},List.Last(l)))}),
                                  {"","",l{0}},
                                  (s,c)=>if List.ContainsAll({"0".."9"},{s{2},c}) or (not List.ContainsAny({"0".."9"},{s{2},c}))
                                         then {s{0},s{1}&c,c} 
                                         else {s{0}&{s{1},Text.PadStart(s{1},5,"0")}{Byte.From(s{1}>="0" and s{1}<="9")},c,c}){0}
    

    运用到Table.Sort里:

    let
        源 = Excel.CurrentWorkbook(){[Name="表1"]}[Content],
    
        排序 = Table.Sort( 源, each let l=Text.ToList([#"Excel排序功能-升序结果"]) 
                                    in List.Accumulate( l&({{"1"},{""}}{Byte.From(List.Contains({"0".."9"},List.Last(l)))}),
                                                        {"","",l{0}},
                                                        (s,c)=>if   List.ContainsAll({"0".."9"},{s{2},c}) 
                                                                    or 
                                                                    (not List.ContainsAny({"0".."9"},{s{2},c})) 
                                                               then {s{0},s{1}&c,c} 
                                                               else { s{0} 
                                                                      & { s{1},Text.PadStart(s{1},5,"0") }{Byte.From(s{1}>="0" and s{1}<="9")},c,c}){0})
    in
        排序
  • 对多级 BOM 文本列进行正确排序 at 2019-01-19 13:30:01

    @斜杠星号
    昏倒,跟着畅老板忙活一上午,你居然没有那个函数,哈哈哈哈哈。。。。
    还有一个写法,跟着畅老板学的。 一个是把fx单独写了一步,另一个是把排序的内容先拆了,用0补全为5位数后,合并再排序。供参考:

    let
        源 = Excel.CurrentWorkbook(){[Name="表1"]}[Content],
    
        fx = let fx = (x)=>Splitter.SplitTextByCharacterTransition(x,each not List.Contains(x,_))  in fx,
    
        排序 = Table.Sort( 源, each Text.Combine(
                                                 List.Transform( 
                                                                 List.Combine(
                                                                              List.TransformMany( Text.SplitAny([#"Excel排序功能-升序结果"],".- "),
                                                                                                   each fx({"0".."9"})(_), 
                                                                                                   (x,y)=>fx({"A".."Z"})(y))),
                                                                (t)=>Text.PadStart(t,5,"0") ) ) )
    in
        排序
  • 对多级 BOM 文本列进行正确排序 at 2019-01-19 12:21:51

    @斜杠星号

    (以下语句和方法,得到了畅老板和晨星大佬的指点,谢谢)

    有点复杂,也有考虑不到边的情况。我的想法就是把每个ID拆开,只要是数字连在一起的就一起不拆开,有分隔符的就拆开,字母连在一起的还是连在一起,比如"8WD.199.371B-10-A-2"拆成8,WD,199,371,B,10,A,2这样子后,再按每个元素的先后位次按照其对应字符的序列进行排序。不知道这个逻辑是不是对的? 大概弄了一下,按照目前数据源的情况测试,结果是对的。有两种方法,一个是用Splitter.SplitTextByCharacterTransition,一个是用正则,正则简单但速度慢。以下仅供参考,普适性有待检验。源就是你表格左侧的那一列。

    方法一:Splitter拆

    let
        源 = Excel.CurrentWorkbook(){[Name="表1"]}[Content],
    
        排序 = Table.Sort( 源, List.Transform( {0..15}, (x)=>each 
                                     let fx = (x)=>Splitter.SplitTextByCharacterTransition(x,each not List.Contains(x,_)),
                                          l = List.Combine(List.TransformMany( Text.SplitAny([#"Excel排序功能-升序结果"],".- "), 
                                                                               each fx({"0".."9"})(_), 
                                                                               (x,y)=>fx({"A".."Z"})(y))) 
                                      in try Number.From(l{x}) otherwise l{x}?))
    in
        排序

    方法二:正则拆

    let
        源 = Excel.CurrentWorkbook(){[Name="表1"]}[Content],
    
        排序 = Table.Sort(源, List.Transform({0..15},(x)=>each 
                                     Table.TransformColumns( Web.Page("<script>
                                                                               document.write('"&[#"Excel排序功能-升序结果"]&"'.match(/\d+|[A-Z]+/g).join('<br>'))
                                                                       </script>")[Data]{0}[Children]{0}[Children]{1},
                                                             {"Text",(x)=>try Number.From(x) otherwise x})  [Text] {x}?))
    in
        排序

    还有一个就是你说的补全位数后排序:

    let
        源 = Excel.CurrentWorkbook(){[Name="表1"]}[Content],
    
        排序 = Table.Sort( 源, List.Transform( {0..15}, (x)=>each 
                                 let fx = (x)=>Splitter.SplitTextByCharacterTransition(x,each not List.Contains(x,_)),
                                      l = List.Transform(List.Combine(List.TransformMany( Text.SplitAny([#"Excel排序功能-升序结果"],".- "), 
                                                                               each fx({"0".."9"})(_), 
                                                                               (x,y)=>fx({"A".."Z"})(y))),(t)=>Text.PadStart(t,2,"0"))
                                      in l{x}?))
    in
        排序