Lazy loaded imageFAQ 004:使用[]和{}能取多列、多行吗?

type
status
date
slug
summary
tags
category
icon
password
notion image

(本文3000字,阅读需要8分钟左右)

FAQ-004:使用[]和{}能取多列、多行吗?

notion image
直接给你一个答案:你不能用 {} 或者 [] 来直接取多行或者多列。
在 M 语言的语法规则里,{ } (大括号) 专情且专一,它一次只能取一个对象。
  • 对于表 (Table),{ } 的使命是“钻取” (Drill down)。
  • 钻取的含义是:把“表”这个壳砸碎,取出里面的一行“肉” (Record)。
  • 如果你想取多行,意味着结果还得是一张表 (Table)(壳还在,只是变薄了),而不是记录 (Record)
所以,在 M 语言里,取多行不是用语法符号,即{}或者[],而是用表函数。这个就是我们会逐一讲解的通过函数来操作表的知识了。
所以,只要是用到 [] {} 来取值,都只能取到一列或者一行的值,只要你对着一张 表 (Table) 单独使用 [ ] 或者 { } ,你就是在给这张表“降维”,结果在界面上都会呈现为 “竖着的一列样式”
我们可以这样理解这个规律:

1. 二维变一维(降维打击)

  • 表 (Table) 是一个 二维 的东西(有行、有列,是一个面)。
  • [ ] (取列):把面切成一条垂直竖线(List)。
  • { } (取行):也是把面切成一条水平横线(Record)。

2. 虽然都是“竖条”,但请注意“表头”

虽然它们看起来都是竖着的,但正如我们刚才讨论的,你要通过看顶部的标题或者左侧的结构来区分它们:
  • [ ] 出来的竖条
    • 这是 List (列表)
    • 特征:左边没有字段名,只有 1, 2, 3 序号。
    • 含义同一种属性的很多个值(比如全是姓名)。
  • { } 出来的竖条
    • 这是 Record (记录)
    • 特征:左边有字段名(姓名、年龄...),右边是值。
    • 含义同一个对象的很多种属性(张三的各种信息)。

3. 特殊情况:什么时候不是“竖条”?

只有一种情况,用了 [ ] 却看不到竖条,那就是你对着“记录”用 [ ] (也前面说过的的“多层嵌套”)如下图所示。
notion image
  • 源{1} -> 得到表“源”中一个竖着的 Record(李四的信息卡片)。
  • 源{1}[年龄] -> 注意! 这时候你是在对着“李四的卡片”找“年龄”信息。
  • 结果:"35"。
  • 样式:这就不再是一个竖条了,而是一个单纯的值 (Value)。界面上通常会直接显示这个文本或数字。

4. 一个有趣的“彩蛋”:列的投影

虽然逻辑上“取多列”必须返回表,但在语法上,M 语言其实给 [ ] 留了一个特殊写法,用来实现取多列(这叫“投影”)。
你可以回到你的练习界面试一下这个代码:
  • 代码= 源[[姓名], [年龄]]
  • 注意:里面是双层中括号!
  • 含义:源 表后面紧跟 [ ... ],但里面不是一个列名,而是由多个列名组成的列表
  • 结果一张表 (Table)
对比一下:
  1. = 源[姓名]
      • 只有一列 -> 降维打击 -> 变成 List(面变线)。
  1. = 源[[姓名], [年龄]]
      • 有多列 -> 无法降维(多根线拼在一起还是面) -> 保持为 Table
 
所以,如果你的工作仅仅是“把一张乱表洗干净”,那么你可能95%的时间都不需要手写 {}  [] ,光靠UI按钮生成的 Table.xxx 函数就够了。
但是,我们的课程有一个“第二阶段:能力飞跃”,一旦你跨过“洗数据”这个阶段,进入“自动化”“动态参数”的领域, {}  [] 这种钻取操作就会从“理论逻辑”摇身一变,成为实务中不可或缺的神器。
这里给大家举三个实务中非常高频的场景,如果没有这套钻取逻辑,这些需求用UI界面来操作几乎没法做,或者做得非常笨拙。

场景一:抓取“表头参数” (比如:报表日期在 A1 单元格)

痛点
很多 Excel 报表是不规范的。比如 A1 单元格写着“2023年10月”,然后 A3 单元格开始才是真正的表格头。
你把数据导入 PQ 后,想把这个“2023年10月”作为一个新列添加到所有行里,或者用来过滤数据。
如果不懂钻取
你得用“填充”、“转置”等一大堆步骤把这个日期挪到每一行去,非常麻烦。
懂钻取的高手做法
  1. 单独建一个查询(比如叫 RawData ),指向源数据。
  1. 直接写一条公式抓取 A1 的值:
    1. 我的日期 = RawData{0}[Column1](取第1行第1列的值)
  1. 现在 我的日期 就是一个具体的值(比如 2023/10/1)。
  1. 在主表里点击“添加自定义列”,公式直接写 = [销售额] * rate (假设有个汇率) 或者直接把 我的日期 当作常量来筛选。
结论:在这里, {}  [] 是你把“单元格”变成“全局变量”的唯一手段。

场景二:读取文件夹中“最新”的一个文件

痛点
你每天往文件夹里放一个新日报,想让 PQ 自动只读取修改时间最晚的那一个文件。
实务操作
  1. 连接文件夹,得到文件列表。
  1. 按“修改时间”降序排列(最新的在第一行)。
  1. 关键时刻来了:你怎么告诉 PQ “我就要第一行那个文件”?
      • UI做法:保留前1行 -> 展开二进制。 (这样依然保留了Table的壳,有时候会干扰后续步骤)。
      • 代码做法 (钻取)
        • 最新文件内容 = 排序后的表{0}[Content]
  1. 这句话的意思是:不管表里有多少文件,我只要第1行 ({0}) 的 文件内容 ([Content])。
结论:这是文件处理自动化的标准动作。

场景三:像 VLOOKUP 一样做“配置表”

痛点
你有一张参数表(Config表),里面规定了:
  • 达标线:80
  • 税率:0.13
  • 奖金系数:1.5
你想在计算工资时,直接引用这个“税率”。
高手做法
你不应该把这张配置表和工资表通过“合并查询”连起来(那样效率低且杀鸡用牛刀)。
你应该用钻取:
当前税率 = 参数表{[项目="税率"]}[数值]
这条公式就像一个精确制导导弹,直接飞到参数表里,把税率抓出来,变成一个数字 0.13。然后你在工资计算步骤里直接乘这个 当前税率 即可。

总结

  • 对于“洗菜”(清洗规范表格)UI按钮(Table 函数)是主力,钻取基本用不上。
  • 对于“做菜”(建模、自动化、参数化) {}  [] 是你提取单个值定义变量实现动态逻辑的核心手段。
所以,这里学的它们不是屠龙之技,而是当你遇到“我只需要这一个数,而不是整张表”这种需求时,唯一最有效的解决方案。
看到这里,你的 Power Query 世界观应该已经非常完整了:
操作
语法符号
结果形态
维度变化
你的逻辑验证
取一列
表[列名]
List (列表)
2D -> 1D
对!只剩一根线了
取一行
表{下标}
Record (记录)
2D -> 1D
对!只剩一根线了
取多列
表[[A],[B]] 或 Table.SelectColumns
Table (表)
2D -> 2D
对!多列还得是表
取多行
Table.Range 等
Table (表)
2D -> 2D
对!多行还得是表
所以,只要涉及到“多”,它就撑起了一个平面,结果就必然还得是“表”。 只有“单”,才能被抽离成“线”或“点”。

如果本篇文章对您有帮助或启发,请帮我们点赞、转发、推荐、关注,让更多想转型财务BP、锻造数据分析和可视化洞察能力的财务同行们看到,关注【老汪洞察】,不迷路!
若想获得更多制造业成本本管控、核算、全面预算、业财融合方面的落地实操干货,加入我们的大本营是你的不二之选,快点击下方卡片看看吧!
温馨提示
🙏🏻
如果您不想错过【老汪洞察】的文章,请将我们设为"星标",这样每次最新文章推送才会第一时间出现在您的订阅列表里。 方法:点击文章页面左上角蓝色文字“老汪洞察”进入主页,点击关注后,再点主页右上角"...",然后选择"设为星标",即可完成,感谢您的支持。
上一篇
FAQ 003:为什么[]取列值和{}取行值展示形式都是竖着的,好像都是列一样?
下一篇
存货计价核算:移动加权平均之美
Loading...
文章列表
让财税成为经营的力量
电脑与网络
从Power Query到Power BI,入门到精通
知识运用