Files
lark-sheets/references/lark-sheets-formula-verify.md

6.6 KiB
Raw Permalink Blame History

Lark Sheet Formula Verify(+formula-verify)

本文定位:飞书表格"公式写入后是否真的零错误"的诊断入口。公式的书写规则与 Excel→飞书迁移的语义规则一律以 lark-sheets-formula-translation 为唯一权威,本文不重复;本文聚焦"写完之后如何用一次调用发现公式错误"。

边界:本文不讲公式怎么写(去 lark-sheets-formula-translation),也不讲公式怎么写入表格(去 lark-sheets-write-cells / lark-sheets-batch-update)。本文只讲一件事:任务里发生公式落表、批量填充公式、--copy-to-range 扩展公式、导入含公式 workbook 时,如何用 +formula-verify 做诊断并决定是否修复。

为什么需要自检

飞书在线表格已经实时算好结果,但"算出来"和"算对了"是两件事。常见缺口:

  • 公式编译失败 → 单元格落成文本(写入类 shortcut 返回的 formula_errors[] 是编译失败信号)。
  • 公式编译成功但运行时错误:#REF! / #DIV/0! / #VALUE! / #NAME? / #NULL! / #NUM! / #N/A——这一类只看 formula_errors[] 看不到,必须扫单元格值。

+formula-verify 把两路信号合并成一份统一 JSON:一次调用聚合全表错误清单 + 编译失败清单 + 每类错误的定位与样本,AI 一眼就能定位修复。G2 分支中,它提供诊断信号,不再作为默认交付前置条件。

调用契约

最小调用形态:

入参 含义
--url / --spreadsheet-token 表格定位(XOR 二选一,必填)
--sheet-id / --sheet-name 限定子表(mutually exclusive;省略则扫全部可见子表)
--range 限定 A1 范围;省略则用各 sheet 的 current_region
--max-locations 每类错误样本上限,默认 20
--exit-on-error status='errors_found' 时返回非 0 退出码(CI 网关用)

返回核心字段:

  • status ∈ success / errors_found / partial——唯一可机读的健康度判据。
  • total_errors / total_formulas / scanned_cells——本次扫描规模指标。
  • has_more——为 true 表示扫描被内部上限截断(详见后文「截断与续读」),未覆盖完整范围。
  • error_summary[<错误类型>]——每类错误的 count / locations[] / samples[].{address,formula,depends_on}。
  • compile_errors[]——合并最近一次写入留下的编译失败清单,与运行时错误并存时同时出现。
  • warning_message——仅在 has_more=true 时出现,告知调用方需要缩小 --range / 拆 --sheet-id 续读。

写入后诊断规则

任何批量公式 / 含公式列写入完成后,都可以调用 +formula-verify 做一次诊断。不要等用户显式说"校验一下公式"才想到这里;只要任务动作包含写公式,这一步就有较高价值。触发场景:

  • +cells-set / +csv-put
  • +cells-set --copy-to-range / 模板单元格向整列或整块扩展公式
  • +workbook-import
  • +batch-update 中含写入子操作
  • +table-put(任意列含公式时)
  • +workbook-import(导入的 xlsx 含公式时)

处置规则:

  1. status='success' → 记录诊断通过。
  2. status='partial' → 扫描被内部上限截断。若该公式区是关键输出,可缩小 --range 或拆 --sheet-id 续扫;否则在交付说明中标明诊断覆盖不完整。
  3. status='errors_found' 且 compile_errors[] 非空 → 根据 compile_errors[].reason 修正公式语法(飞书函数名 / 范围语法 / 引用样式),或在成本过高时降级为静态值并说明原因。
  4. status='errors_found' 且只剩运行时错误 → 按 error_summary 的 samples[].formula + depends_on 排查根因(零除?空值参与运算?引用越界?日期差写法?数组语义?),优先修复关键输出区。
  5. 同一处错误连续修复 3 次仍未通过 → 改用 IFERROR 包裹兜底,或退回纯值写入,并在交付说明写清不随源数据更新。

注意:

  • 在 status='errors_found' 的状态下调用 +cells-set --copy-to-range 继续扩展会把错误复制放大,建议先处理关键错误。
  • "编译失败但运行时无报错"不是 zero-error(编译失败的单元格此刻是文本不是公式,源数据一变就再也算不出值)。
  • 只靠肉眼读首末 5 行确认不可靠——表中段、隐藏行、合并区里的错误这样根本看不到;+formula-verify 可补充这一诊断视角。
  • 只验证写入区首行不够:批量填公式后同时抽查首行、中段、尾部和汇总行;目标是发现“只填到前 N 行”“把明细公式写进合计行”“尾部仍是空/错误值”这类问题。
  • 修公式时先定位根因格,再看下游链路。不要把被上游错误污染的下游格全部重写;同型公式优先从相邻正确单元格复制/改引用,写完回读下游关键格是否仍有 #VALUE! / #REF!。
  • 查找/匹配公式必须有错误处理:不要裸写 VLOOKUP / XLOOKUP。未匹配时返回明确文本(如“未匹配到”),不要静默空串,除非用户明确要求空值。
  • 排名/排序公式要处理空值、0 值和不参与排名项;这些项应保持空/0,而不是进入通用排名公式得到正整数名次。

截断与续读

后端有一个内部硬上限对总扫描单元格数做截断(不暴露给调用方),超过后立即返回 has_more=true + warning_message,error_summary / compile_errors 仅覆盖已扫描部分。处理路径:

  • 关键输出区优先按 --sheet-id / --sheet-name 拆成多次调用。
  • 同 sheet 内按 --range 切片(如先 A1:Z200 再 AA1:AZ200),逐块诊断。
  • 如时间不足,说明已诊断范围和未覆盖范围。

常见陷阱

坑 应对
错误字符串本地化 后端按内部 error_kind / compute_status 字段识别错误类别,不走字符串匹配;调用方拿到的 7 类英文错误代码由后端统一规范输出,与 locale 无关。
formatted_value 可能隐藏错误 某些条件格式 / 自定义数字格式会把 #DIV/0! 显示成空白。后端直接读 cell error_kind,不依赖 formatted_value,绕开此类被遮蔽。
把 partial 当全量健康 partial 仅表示已扫描部分无错误,剩余区域未知。关键公式区应继续缩小范围诊断;非关键区可在交付说明标明覆盖不足。
编译失败 vs 运行时错误 同一份报告里 compile_errors[] 与 error_summary 并存。语义层先解决 compile_errors[]、再做运行时自检。