分析 NetSuite 财务数据:从连接到损益表
约 45 分钟 · 一个可用的 NetSuite 连接、一张已加载的总账、一张月度损益表、一份应收账款账龄,以及一个计划刷新
这是财务总监或 FP&A 分析师的入门路径:完成后,您将直接从 NetSuite 提取总账,将其转换为可像报表一样阅读的月度损益表,构建应收账款账龄,把两者放到仪表板上,并让整个流程自动刷新。无需导出电子表格,也无需手动重新录入,数据来自 NetSuite 并保持最新。
您只需连接一次、提取一次,然后做真正重要的部分:将原始总账行整理成业务人员周一早上要看的汇总。
- 一个 PlaidCloud 工作区和一个用于操作的项目(如果需要,请开始试用)。
- 一个可用的 NetSuite 连接。请先按照连接到 NetSuite 操作:需要在 NetSuite 中启用 OAuth 2.0 和 REST Web 服务,并准备好集成的客户端 ID、证书 ID、账户 ID 和私钥 PEM。开始之前,请确认发送测试请求显示为绿色。
- 整理数据无需 SQL,使用标准转换步骤即可完成。唯一的查询文本是从 NetSuite 提取数据的部分,所有提取查询都已提供。请在另一个标签页中打开 NetSuite SuiteQL 查询示例,本教程的内容取自该页面。
步骤 1:创建工作流
Section titled “步骤 1:创建工作流”工作流是提取并整理数据的管道。
- 打开项目,切换到工作流选项卡。
- 单击新建工作流,将其命名为例如
NetSuite Financials,然后打开。
步骤 2:提取总账
Section titled “步骤 2:提取总账”一条 SuiteQL 查询即可得到一整年的过账活动(每个科目、每个月),足以构建损益表,以及之后的其他报表。
-
添加一个 REST 请求步骤。在请求选项卡上,将连接设为您的 NetSuite 连接,将方法设为
POST,将端点设为/services/rest/query/v1/suiteql。 -
在正文中,放入以下 SuiteQL,并包装为
{"q": "…"}:SELECTTO_CHAR(t.trandate, 'YYYY-MM') AS period,a.accttype AS account_type,a.acctnumber AS account_number,BUILTIN.DF(a.id) AS account_name,tal.amount AS amountFROM transactionaccountingline talJOIN transaction t ON t.id = tal.transactionJOIN account a ON a.id = tal.accountWHERE tal.posting = 'T'AND tal.accountingbook = 1AND t.trandate BETWEEN TO_DATE('2026-01-01', 'YYYY-MM-DD')AND TO_DATE('2026-12-31', 'YYYY-MM-DD')ORDER BY period, a.acctnumber -
在响应选项卡上,将目标设为表,命名为
netsuite_gl,并设置列类型:amount→ 货币,其余 → 文本。(SuiteQL 将数字和日期作为文本返回;设置类型后amount才能求和。) -
单击发送测试请求确认可以运行,然后运行该步骤。现在您有了一张
netsuite_gl表:每个科目每个月一行,带有带符号的过账金额。
步骤 3:将总账整理为损益表
Section titled “步骤 3:将总账整理为损益表”接下来是分析,只需一次点选式转换,无需 SQL。损益表其实就是汇总后的总账:收入和费用科目归入几个项目,并翻转符号,使收入显示为正数。Table Extract 步骤可以在其表数据选择和数据筛选器选项卡上完成全部操作。
-
添加一个 Table Extract 步骤。将其源设为
netsuite_gl,目标设为新表netsuite_pnl。 -
在数据筛选器选项卡上,仅保留收入和费用科目(排除资产负债表科目):添加一个筛选器,条件为
account_type属于其中之一Income、OthIncome、COGS、Expense、OthExpense。 -
在表数据选择选项卡上,单击汇总以启用聚合,然后设置三个目标列:
period:直接从源映射。汇总方式为分组依据。pnl_line:一个表达式(见下文),将每种科目类型转换为一个报表项目。汇总方式为分组依据。amount:表达式为netsuite_gl.amount * -1(翻转符号)。汇总方式为求和。
对于
pnl_line,双击其表达式单元格并输入以下内容(编辑器允许您点选各列,以及条件分组中的case函数):case((netsuite_gl.account_type.in_(['Income', 'OthIncome']), '1 - Revenue'),(netsuite_gl.account_type == 'COGS', '2 - Cost of Goods Sold'),(netsuite_gl.account_type.in_(['Expense', 'OthExpense']), '3 - Operating Expenses'),) -
运行该步骤。
amount * -1 表达式是唯一的会计处理:将借方为正的金额取反,使收入为正、成本为负,因此每个月的三个项目相加即为净利润。随后以 period 和 pnl_line 为分组依据并求和,即可将所有科目汇总为每月三个项目。表达式使用 PlaidCloud 的点选式编辑器,参见高级数据映射器用法和表达式参考。
步骤 4:像财务人员一样阅读
Section titled “步骤 4:像财务人员一样阅读”打开 netsuite_pnl 表。每个月有三个数字:
| period | pnl_line | amount |
|---|---|---|
| 2026-01 | 1 - Revenue | 486,200.00 |
| 2026-01 | 2 - Cost of Goods Sold | -190,540.00 |
| 2026-01 | 3 - Operating Expenses | -212,880.00 |
可以直接从中读出:
- 毛利润 = 收入 + 销货成本(销货成本已是负数)→
486,200 − 190,540 = 295,660。 - 净利润 = 三个项目之和 →
82,780。 - 毛利率 = 毛利润 ÷ 收入 → 约 61%。
首先要做的是核对:针对同一个月运行 NetSuite 自带的损益表,确认收入和净利润一致。如果不一致,几乎总是范围不同:子公司或货币筛选器,或者过账期间与交易日期未对齐(参见关于期间的说明)。只有核对一致后,才能信任这条管道。
步骤 5:构建应收账款账龄
Section titled “步骤 5:构建应收账款账龄”这是第二个入门成果,遵循同样的“连接、提取、整理”模式。从未结应收账款的查询开始,然后按每张发票的逾期时间分档。
-
再添加一个 REST 请求步骤(相同的连接,
POST,suiteql 端点),正文如下:SELECTt.tranid AS invoice_number,BUILTIN.DF(t.entity) AS customer,TO_CHAR(t.trandate, 'YYYY-MM-DD') AS invoice_date,TO_CHAR(t.duedate, 'YYYY-MM-DD') AS due_date,t.foreigntotal AS invoice_total,t.foreignamountunpaid AS amount_unpaidFROM transaction tWHERE t.type = 'CustInvc'AND t.foreignamountunpaid <> 0ORDER BY t.tranid将其加载为
netsuite_open_ar,其中invoice_total和amount_unpaid→ 货币,invoice_date和due_date→ 日期,其余 → 文本。 -
添加一个 Table Extract 步骤,读取
netsuite_open_ar并写入新表netsuite_ar_aging。在表数据选择选项卡上,单击汇总并设置三个目标列:aging_bucket:一个表达式(见下文),根据每张发票的逾期时间为其打标签。汇总方式为分组依据。invoices:任意列,例如invoice_number。汇总方式为计数。balance:从amount_unpaid映射。汇总方式为求和。
对于
aging_bucket,输入以下表达式,它计算逾期天数(日期减日期得到天数)并标记所属区间:case(((func.today() - netsuite_open_ar.due_date) <= 0, '0 - Current'),((func.today() - netsuite_open_ar.due_date) <= 30, '1 - 1-30 days'),((func.today() - netsuite_open_ar.due_date) <= 60, '2 - 31-60 days'),((func.today() - netsuite_open_ar.due_date) <= 90, '3 - 61-90 days'),else_='4 - Over 90 days',) -
运行。
netsuite_ar_aging现在用五行告诉您,有多少款项未到期,有多少款项逾期 30/60/90 天以上,这是业务人员首先查看的催收视图。(due_date必须设为日期类型,日期相减才能生效,您已在上面 REST 请求步骤的响应选项卡上完成了设置。)
步骤 6:放到仪表板上
Section titled “步骤 6:放到仪表板上”表中的数字尚可,但发给首席财务官的应当是图表。发布 netsuite_pnl 和 netsuite_ar_aging,然后按照构建仪表板添加:
- 按
period显示净利润(或收入)的条形图,以及 - 按
aging_bucket显示应收账款balance的饼图或条形图。
这就是一个实时的 NetSuite 财务仪表板,无需导出,每次运行工作流时都会刷新。
步骤 7:计划刷新
Section titled “步骤 7:计划刷新”- 从头到尾运行整个工作流一次,确认每个步骤都显示为绿色。
- 为工作流设置计划:按结账节奏每月运行,或者如果希望每天早晨都有最新的应收账款账龄,则每晚运行。
由于每次提取都会完整替换整张表,每次运行都会重新提取其 WHERE 子句定义的数据范围,因此请将范围限制在所需的时间窗口内(当年、仅未结发票),而不是全部历史数据。
您已构建的内容
Section titled “您已构建的内容”从一个空工作流开始,您提取了实时的 NetSuite 总账和应收账款,使用两个标准转换步骤(无需 SQL)将其整理为月度损益表和应收账款账龄,放到仪表板上,并设置为自动刷新。这是财务团队运行的核心报表循环,现在已经实现自动化。
- NetSuite SuiteQL 查询示例:试算平衡表、资产负债表、未结销售订单、采购订单和库存,可添加到同一个工作流中。
- Table Extract 步骤和高级数据映射器用法:用于更深入分析的分组、筛选和计算列。
- 设计维度层次结构:将会计科目表汇总为由您控制的报表分组。
- 构建仪表板:完整的仪表板演练。