一、了解何时使用循环
本单元是概念基础:学习 Flow Builder 的 Loop 元素如何工作,何时用 Loop 而非 Transform 元素或手动循环,以及如何避免嵌套循环的性能陷阱。
进入循环的世界(1):循环做什么
Flow Builder 中的循环(Loop)遍历一个记录集合,一次处理一个项目。常见用例:根据条件更新多条记录(如给超过 10 万美元的机会打折)、逐个处理集合中的每个项目(校验、转换、赋值)、跨记录做聚合计算(总和、平均、计数)。Loop 元素接收一个集合变量(记录或值的列表)作为输入,输出一个当前项目变量(迭代中的当前项)。循环对集合中的每个项目运行一次,循环内部的一切都会对每个项目执行。这就是基本迭代模式:对集合中的每个 X,做 Y。
上图用一个编号流程展示了一个实际循环的运行过程。
进入循环的世界(2):Loop 元素的解剖
Loop 元素结构简单但影响深远。它只需一个配置设置:集合变量(Collection Variable)——要遍历的项目列表,通常由 Get Records 元素填充。循环还生成一个特殊的当前项目变量(Current Item from Loop),让你在循环内通过点号访问当前项目的字段。Loop 有两条路径:For Each 路径包含对每个项目执行的逻辑(决策、赋值、更新),会运行 N 次(每个项目一次);After Last 路径在所有项目处理完后恰好运行一次。理解这个结构至关重要——For Each 里的数据操作会计入 governor 限额,而循环之后的操作不会。
进入循环的世界(3):循环 vs 批处理
这是 Flow 循环最关键的性能概念:Flow 循环在单个 flow interview(事务)内运行,所有迭代在一次执行中完成。这与 Batch Apex 不同——Batch Apex 把项目拆到多个事务中。因此要特别关注 governor 限额:如果循环处理 200 条记录、又在循环里放了 Update Records 元素,就会尝试 200 次 DML 操作,而 DML 限额是 150,flow 会失败。最佳实践:不要把 Update Records 放进循环里。改用 Assignment 在循环内修改项目、收集起来,循环结束后用一次 Update Records 提交。
进入循环的世界(4):实用示例
示例:给所有超过 10 万美元的机会打 9 折。错误做法(有限额风险):Get Opportunities → Loop → 循环内 Update Records,200 次更新 = 200 次 DML = 超限。正确做法(高效):Get Opportunities → Loop → Decision(Amount > 100000?)→ Assignment(Amount = Amount × 0.9)→ 加入集合变量 →(After Last)Update Records(对所有修改记录做一次 DML)。这个模式——查询、循环修改、循环后一次提交——适用于任何批量更新场景,学会它就不会再撞 DML 限额。
不用 Loop 元素做循环(1):Transform vs Loop
Flow Builder 提供两种迭代工具。Transform 元素:用公式把输入集合映射到输出集合,同时处理所有项目,但无法做逐项目的决策或分支——适合数据转换、字段映射、简单计算(如把名字都转成大写)。Loop 元素:一次处理一个项目,支持逐项目决策(If/Else),能根据项目值分支——适合条件处理、复杂的逐项目逻辑(如根据金额阈值给不同折扣)。经验法则:所有项目需要同样处理时用 Transform,项目需要不同处理时用 Loop。
不用 Loop 元素做循环(2):手动循环
你可能会问"为什么要用 Loop 元素?不能用手动连接元素形成圆吗?"手动循环比 Loop 元素风险更大,有两个原因:退出手动循环需要 Decision 元素,用户与实时数据可能造成意外场景,导致 flow 永远不走退出路径、陷入无限循环;而且手动循环没有 Loop 与 Transform 元素内置的优化,处理时间更长、更容易超 CPU 时限。但手动循环有一个主要优势:不需要集合变量就能迭代——如果要循环非集合数据(如多选 picklist 的值),手动循环可行。总原则:能用 Transform 就用 Transform,不能用 Transform 才用 Loop,只有 Loop 与 Transform 都不可能、或避免手动循环会让 flow 复杂得多时,才用手动循环。
避免嵌套循环(1):性能问题
嵌套循环就是一个 Loop 套在另一个 Loop 里。例如:循环遍历账户 → 对每个账户 Get Contacts → 再循环遍历联系人 → 更新每个联系人。如果有 100 个账户、每个 50 个联系人,就是 100×50 = 5000 次迭代。这是 O(n×m) 操作,乘法式增长,数据一多性能就迅速恶化,也容易撞 CPU 时限、难以调试。应尽可能避免嵌套循环。
上图是一个 Loop 元素嵌套在另一个 Loop 元素里的示意。
避免嵌套循环(2):替代模式
把嵌套循环转成顺序操作是关键的优化手段。SOQL 子查询:一次查询同时取父记录与子记录(如 SELECT Id, (SELECT Id FROM Contacts) FROM Account),省掉循环内的第二次 Get Records。展平集合:第一个循环把所有子项收集到单个集合,第二个循环(顺序的、非嵌套的)处理这个扁平集合,把 O(n×m) 变成 O(n+m)。Transform 元素:如果子项都需要同样转换,用 Transform 代替第二个循环。循环前过滤:用 Get Records 的 WHERE 子句只取真正需要处理的记录。牢记:看到一个循环套循环,就问自己"能不能改成顺序的?"多数时候答案是可以。
二、构建循环
本单元动手构建循环:创建计划 flow、获取记录、构建 Loop 元素、在循环内创建动作、用 Decision 分支、用 Assignment 修改记录、用 Update Records 提交。
创建计划 Flow 并获取机会(1):Flow 设置
计划 flow(scheduled flow)按定时器运行——每天、每周或自定义间隔。当需要按固定计划批量处理记录、而非记录一变化就立即处理时,它是正确选择。创建 flow、配置计划,平台负责执行。每次计划运行创建一个 flow interview,处理所有匹配的记录——这就是循环逻辑的容器。
创建计划 Flow 并获取机会(2):Get Records
Get Records 是循环的数据源,你在这里应用的过滤器决定了循环运行多少次——所以要积极过滤。如果 flow 只处理打开的机会,就在 Get Records 的 WHERE 子句里过滤,而不是循环所有机会再用 Decision 检查 Stage。查询级过滤远优于循环级过滤。集合变量存储所有返回的记录,这就是 Loop 元素要遍历的内容。
创建 Loop 元素与循环动作(1):Loop 设置
在 Get Records 之后添加 Loop 元素,配置集合变量(如 Open_Opportunities)与循环变量(如 Current_Opp),方向默认 First to Last。随后出现两条路径:For Each(放逐项目逻辑)与 After Last(循环后继续)。在 For Each 里用 Decision 检查当前项目的条件、用 Assignment 修改值——通过循环变量用点号访问字段,如 {!Current_Opp.Amount}、{!Current_Opp.Stage}。每次迭代循环变量更新为集合的下一个项目,Decision 与 Assignment 处理该项目。这就是条件批量处理发生的地方。
在循环中使用动作
在 For Each 路径里放置处理每条记录的动作:Decision 元素做分支,Assignment 元素修改值,Add to Collection 累积更改。每个动作在每次迭代中运行一次。
创建循环动作(2):Decision 与 Assignment 模式
完成逐项目处理逻辑:Decision 检查多个条件(如 Amount > 100K 且 Close Date ≤ TODAY+30 → "高价值、即将关闭";Amount > 100K → "高价值";默认无变化),每个结果有各自的 Assignment 修改记录并把它加入 Modified_Opportunities 集合。关键:在循环内构建修改记录的集合,绝不在循环内用 Update Records。循环结束后,用一个 Update Records 元素在单次 DML 中更新整个集合——这是零 governor 限额风险的模式。
用循环更新多条记录(1):完整模式
完整批量更新模式:Get Records → 集合变量 → Loop(对每个项目 Decision + Assignment + 加入修改集合)→ After Last → Update Records(一次提交整个集合)。例如分档打折:Amount > 100K 打 85 折、50-100K 打 9 折、< 50K 打 95 折,循环后一次 Update Records。这个六步模式(查询 → 循环 → 决策 → 修改 → 收集 → 提交)适用于任何批量更新场景。
用循环更新多条记录(2):真实示例
真实示例:给机会分档打折——Amount 超 10 万打 85 折、5 万到 10 万打 9 折、低于 5 万打 95 折;循环结束后用一次 Update Records 在单次 DML 中提交所有更改。
创建计划 Flow 及其公式(1):设置
构建一个用户维护的计划 flow:创建计划 Flow 并配置计划(如每周),创建计算日期差的公式资源,用 Get Records 检索匹配条件的 User 记录(如 IsActive = True,存到 Active_Users)。这个 flow 处理用户记录做维护任务——检查登录活动、更新状态、执行清理。计划 flow + 用户记录 = 强大的管理员自动化。
创建计划 Flow 及其公式(2):公式资源
为日期比较、状态检查与计算值创建公式资源。公式提供 Decision 元素在循环内评估的动态数据,设计良好的公式让 Decision 逻辑清晰、可维护。
用 Decision 元素创建多个结果(1):分支
在循环内添加带多个结果的 Decision 元素:"不活跃用户"(Last Login < TODAY-90 → 标记待停用审查)、"低频用户"(TODAY-90 ≤ Last Login < TODAY-30 → 发重新激活邮件)、"活跃用户"(默认,无变化)。每个结果有各自的 Assignment 修改当前 User 记录。多个结果 = 在一个循环内为不同类型的记录提供多条处理路径——这是 Flow 版的分支逻辑。
获取用户记录(1):查询设置
添加 Get Records 元素:Object 选 User,Filter 设 IsActive = True,结果存到集合变量。这检索所有活跃用户供处理,查询级过滤把循环迭代次数降到最低。
用 Decision 元素创建多个结果(2):结果逻辑
Decision 结果的设计原则:顺序很重要——结果从上到下评估,第一个匹配的结果胜出,所以要先放具体的条件、后放通用的条件,默认结果放最底部兜底。保持结果互斥——每条记录应恰好匹配一个结果,条件重叠会导致不可预测的行为。反例(错误顺序):先放 Amount > 1000(匹配一切),再放 Amount > 100000(永远够不着)。正例(正确顺序):先 Amount > 100000,再 Amount > 1000,最后 Default。用样本数据测试,确认正确的记录进入正确的结果。
获取用户记录(2):为循环做准备
循环前创建空的集合(修改用户集合、错误记录集合)。循环内:Decision 评估用户活动,Assignment 修改值并加入修改集合。循环后:Update Records 一次提交全部。
用 Assignment 元素编辑和保存数据(1):在内存中修改
Assignment 元素修改值但不执行 DML。常见循环赋值:{!Current_Opp.Description} = "Priority"、{!Current_Opp.Discount__c} = {!Current_Opp.Amount} * 0.1、把 {!Current_Opp} 加入 {!Modified_Opportunities}。Assignment 只改内存中的值,直到你显式用 Update Records 元素才会写数据库。
这就是避免 governor 限额的关键——所有修改都用 Assignment,最后一次性提交。
用 Assignment 元素编辑和保存数据(2):构建集合
在循环内构建集合:循环前创建一个空集合变量(如 Modified_Records),循环内修改循环变量后把它 Add 进集合,集合随每次迭代增长、累积所有修改记录,循环后用 Update Records 处理这个集合(一次 DML 更新所有)。只把真正修改过的记录加入集合——未修改的记录会浪费 DML;用单独的 Decision 结果跳过无变化记录,跳过 add 步骤。
用 Update Records 提交更改(1):最后一步
循环结束(After Last 路径)后,添加 Update Records 元素,选"使用记录集合的 ID 与字段值",Record Collection 选 Modified_Records——它在一次 DML 操作中更新集合里的所有记录。对比把 Update Records 放进循环:每记录一次 DML = 成百上千次 DML = 超限额。单个 Update Records 让 500 条记录的批量更新在几秒内完成,这是 O(n) DML 变成 O(1) 的关键。
用 Update Records 提交更改(2):完整 Flow 回顾
你的完整批量处理 flow:Start(计划)→ Get Records(过滤相关记录,存入集合)→ Loop → For Each(Decision 检查条件,各结果修改并加入集合,默认跳过)→ After Last(Update Records 一次提交)→ End。这个模式适用于折扣应用、状态更新、数据清理、字段填充、记录归档等几乎所有批量场景。掌握它,就掌握了 Flow 自动化的基础。
三、用 Repeater 创建和更新记录
本单元学习 Repeater 组件——让用户在一个屏幕上输入多条记录,把 screen flow 从单记录输入变成多记录输入体验。
用 Repeater 执行多个数据操作(1):什么是 Repeater
Repeater 是一个屏幕组件,让用户在一个屏幕上输入多条记录:它像一个动态表格,用户可以添加、编辑、移除行,每行就是一条记录的数据,所有行收集进单个记录集合变量。用例:订单录入(一个屏幕加多个行项目)、联系人导入(为一个账户录入多个联系人)、调查回答(一次收集多个答案)。在有 Repeater 之前,录入 10 个订单行项目需要用户填一个表单、点 Next、再填、再点 Next……重复十次;有了 Repeater,用户在一个屏幕填完所有数据、点一次 Next。
在一个屏幕上用 Repeater 执行多个数据操作(1):它是什么
向屏幕添加 Repeater:在 Screen 元素里把 Repeater 组件拖到画布,配置集合变量(行数据存哪)与 API 名称,然后向 Repeater 添加字段(文本、数字、日期、picklist),每个字段成为每行的一列。用户点 Add Row 创建新行并填字段,点 Next 时整张表序列化进集合变量。屏幕之后,用 Loop 遍历集合并逐行处理——创建记录、更新记录、做计算。Repeater + Loop 是 Flow 中多记录数据录入的标准方法。
在一个屏幕上用 Repeater 执行多个数据操作(2):配置步骤
配置 Repeater:添加集合变量,把字段作为列加入。每个字段成为动态表格的一列,用户动态增删行,所有行存入集合供下游循环处理。
创建 Screen Flow 并获取现有联系人(1):Flow 设置
构建联系人管理的 screen flow:创建 Screen Flow,用 Get Records 检索当前账户的现有 Contact(过滤 AccountId = {!recordId})。Repeater 屏幕既显示现有联系人(可编辑),又允许添加新联系人,所有更改收集进一个集合变量。这个屏幕把现有数据与新数据录入结合在一个界面里,既查看又编辑。
创建 Screen Flow 并获取现有联系人(2):Get Records
添加 Get Records 元素:检索 AccountId 等于 recordId 的 Contact,存入集合变量。这提供了下一屏 Repeater 预填充的现有联系人数据。
用重复字段创建屏幕(1):向 Repeater 添加字段
创建带 Repeater 的屏幕来一次捕获多个联系人:添加 Screen 元素(Label 填 Get Details),把 Repeater 拖到画布(API 名 ContactRepeater),然后在 Repeater 里添加输入字段——First Name、Last Name、Email、Business Phone,每个字段成为重复行的一列。
用户先看到一行,点 Add 可继续加行,所有行数据在点 Next 时收集进 ContactRepeater 集合变量。
用重复字段创建屏幕(2):Repeater 布局与视觉确认
配置 Repeater 最常见的错误是把字段放在 Repeater 组件之外。边界蓝框外的字段只出现一次、不会重复,也不进 Repeater 的集合。始终做视觉检查:悬停在 Add 按钮附近直到一个蓝框包住所有字段——蓝框内的一切按行重复,蓝框外的不会。这个快速检查能在激活 flow 前发现配置错误。
为现有记录配置默认字段值(1):预填充
在 Repeater 里展示现有记录时,设置默认值让用户看到当前数据:对每个字段,把默认值设为现有记录的对应值(如 Repeater 的 First Name 默认值 = {!Current_Contact.FirstName})。Repeater 预填充每一行,用户看到当前存储的数据、按需修改;新行默认值留空或设通用占位。预填充的 Repeater 让数据审查与编辑更高效。
上图展示了 Repeater Prepopulated Items 区,以及如何选中 Repeater 组件配置数据源。
为现有记录配置默认字段值(2):高级默认值
高级默认值模式:条件默认(用 IF() 公式按场景设不同默认,如 Account.Type 为 Customer 时 Contact.Role 默认 Buyer);跨字段默认(如 Email 默认 = FirstName + "." + LastName + "@company.com");查找默认(基于父记录预选 picklist 值);上下文默认(如 CloseDate 默认 TODAY+30、OwnerId 默认 {!$User.Id})。目标:尽量少让用户输入——每个用户不用填的字段,就是不会出错的字段。投入时间做好默认值,每次交互都会受益。
四、循环遍历 Repeater
本单元处理 Repeater 的输出:把行循环分离为新建与更新记录、验证数据、填充字段,并用完整 upsert 模式提交。
循环修改记录并加入集合(1):处理行
Repeater 屏幕之后,用 Loop 逐行处理:遍历 Repeater 的集合变量,对每行用 Decision 判断是现有记录(有 Id)还是新记录(无 Id)——现有记录来自 Get Records、有 Id;用户新加的行没有 Id。现有记录加入 To_Update 集合,新记录加入 To_Create 集合。循环后用 Update Records 更新现有、用 Create Records 创建新的,总共两次 DML,同时处理现有与新记录。
循环修改记录并加入集合(2):先验证
提交数据库前先验证 Repeater 数据。在循环内、加入 update/create 集合之前:用 Decision 检查必填字段是否为空、邮箱格式是否无效。验证失败就把错误消息加入集合、跳过加入;通过才加入集合。循环后若有错误就显示错误屏幕,无错误才提交(Update/Create)。绝不要信任用户输入——在创建/更新前验证每一行。
循环修改记录并加入集合(3):填充字段
提交前用循环填充额外字段。对每一行(新记录与现有记录都):用 Assignment 填 {!Current_Row.AccountId} = {!recordId}(链接父记录)、{!Current_Row.LastModifiedDate} = NOW()(审计时间戳)、{!Current_Row.DataSource} = "Repeater Flow"(跟踪)。这些是用户不该手动输入的系统字段、计算值与审计数据,循环期间自动填充。用户专注于有意义的业务数据,flow 处理"管道"。
Upsert 新的和已更改的联系人集合(1):Upsert 模式
Upsert = Update(更新)或 Insert(插入),取决于记录是否已存在。Flow 没有单一的 Upsert 元素,但用前面的模式就能实现:Get 现有记录 → 在 Repeater 中显示(可编辑)→ 用户修改并加行 → Loop 用 Decision 按 Id 路由到 Update 或 Create 集合 → Update Records + Create Records。这就是 upsert——用两次 DML 实现,而不是一次。Decision 的 Id 检查决定每行用哪个操作:有 Id → Update,无 Id → Create。两次 DML,完整 upsert 行为,无需自定义 Apex。
Upsert 新的和已更改的联系人集合(2):完整 Flow 回顾
你的完整基于 Repeater 的 upsert flow:Start(Screen Flow)→ Get Records(现有联系人)→ Screen + Repeater(预填充现有联系人,用户编辑并加新行)→ Loop(对每行:验证必填字段 → 填充系统字段 → Decision 判断有无 Id → 加入 Update 或 Create 集合)→ After Last(Update Records 更新、Create Records 创建)→ End。一个屏幕、多个操作、完整联系人管理 flow,从多记录数据录入到数据库提交,全程声明式。
这个模式——Get → 显示 → 循环 → 验证 → 填充 → 分离 → Update+Create——是任何多记录 screen flow 的蓝图,适配订单、库存、调查、团队成员管理等任何场景。










































