全部文档
文档中心财务模型deepcubepython-deepcube模式示例

python-deepcube模式示例

本文提供一组面向业务场景的 python-deepcube 示例,帮助用户在已有语法说明基础上,更快理解 BLOCKSCOPECLEAR_DATAIIFROUNDDISPLAY_DATAROLLUPCROSS_DIMENSION 等写法在实际计算中的使用方式。

这些示例采用 python-deepcube 模式在前端实际编写的形式展示,代码从计算语句开始,不包含导出脚本中的 def main(...) 等外围包装。

说明 1:以下代码中的维度成员均使用示意编码,便于体现 python-deepcube 的实际写法;中文仅用于解释业务含义。

说明 2:示例中使用 AccountEntityYearPeriodScenario 等作为示意字段名。实际编写时,应以当前财务模型中自动生成的字段名为准。

下面的示例表示结果科目 A_REVENUE_TOTAL 等于 A_REVENUE_ROOMA_REVENUE_FNB 之和,可用于表达“营业收入 = 客房收入 + 餐饮收入”这类基础汇总关系。

Copy
BLOCK[Account['A_REVENUE_TOTAL']] = BLOCK[Account['A_REVENUE_ROOM']] + BLOCK[Account['A_REVENUE_FNB']]

适用场景:

  • 口径汇总

  • 派生指标计算

  • 基础科目之间的加减乘除计算


下面的示例在 2024 年、东区末级组织、预算来源 SR00 的范围内,计算结果科目 A_MGMT_FEE_INCOME

Copy
SCOPE(
    Year['2024'],
    Base(Entity['EAST']),
    Source['SR00']
)

BLOCK[Account['A_MGMT_FEE_INCOME']] = BLOCK[Account['A_REVENUE_TOTAL']] * BLOCK[Account['A_MGMT_FEE_RATE']]

说明:

  • 当前计算范围由 SCOPE(...) 决定。

  • BLOCK 中未指定的维度,会继承当前范围。

适用场景:

  • 按年度、区域、版本分范围执行计算

  • 不同组织或来源使用不同计算规则


下面的示例先清除结果科目 A_MGMT_FEE_INCOME,再重新计算结果,避免旧数据影响本次计算。

Copy
SCOPE(
    Year['2024'],
    Base(Entity['EAST']),
    Source['SR00']
)

CLEAR_DATA(Account['A_MGMT_FEE_INCOME'])

BLOCK[Account['A_MGMT_FEE_INCOME']] = BLOCK[Account['A_REVENUE_TOTAL']] * BLOCK[Account['A_MGMT_FEE_RATE']]

适用场景:

  • 预算重算

  • 版本重新初始化

  • 调整规则后覆盖写回结果


下面的示例计算结果科目 A_OP_MARGIN。当收入科目 A_REVENUE_TOTAL 为空或接近 0 时,结果直接返回 0,避免出现除零错误。

Copy
# 先给科目 `A_OP_MARGIN`全部赋值为0
BLOCK[Account['A_OP_MARGIN']] = 0
# 当`A_REVENUE_TOTAL`不是一个极小数时,计算除法
BLOCK[Account['A_OP_MARGIN']] = IIF(
    BLOCK_VAL[Account['A_REVENUE_TOTAL']] > 0.005,
    BLOCK[Account['A_OP_PROFIT']] / BLOCK[Account['A_REVENUE_TOTAL']]
)

适用场景:

  • 利润率

  • 费率

  • 单价

  • 占比类指标


下面的示例将 Q1 的自身及其基础成员,与 Q2 合并为一个新的期间范围,在该范围内将实际科目 A_REVENUE_ACTUAL 复制到预算科目 A_REVENUE_BUDGET

Copy
SCOPE(
    IBase(Period['Q1']) + Period['Q2'],
    Entity['E01']
)

BLOCK[Account['A_REVENUE_BUDGET']] = BLOCK[Account['A_REVENUE_ACTUAL']]

适用场景:

  • 季度与单月组合计算

  • 多个区域或门店集合统一计算

  • 按组合范围进行预算复制或测算


下面的示例只对东区中 ud6 = ST0102 的组织执行计算,生成结果科目 A_FRANCHISE_MGMT_FEE

Copy
SCOPE(
    Base(Entity['EAST'], Attr('ud6') == 'ST0102'),
    BusinessLine['BL010407'],
    Source['SR00']
)

CLEAR_DATA(Account['A_FRANCHISE_MGMT_FEE'])

BLOCK[Account['A_FRANCHISE_MGMT_FEE']] = BLOCK[Account['A_FRANCHISE_REVENUE']] * BLOCK[Account['A_MGMT_FEE_RATE']]

适用场景:

  • 按门店类型区分计算规则

  • 按组织属性筛选目标范围

  • 加盟店、自营店、区域中心等差异化计算


下面的示例在 2025 年第一季度范围内,先重算预算收入,再计算管理费收入,最后计算含税管理费收入并保留两位小数。这个示例展示了一个较完整的业务计算链路。

Copy
SCOPE(
    Year['2025'],
    IBase(Period['Q1']),
    Base(Entity['EAST']),
    Scenario['BUDGET'],
    Source['SR00']
)

CLEAR_DATA(
    Account['A_REVENUE_BUDGET', 'A_MGMT_FEE_INCOME', 'A_MGMT_FEE_INCOME_TAX']
)

BLOCK[Account['A_REVENUE_BUDGET']] = BLOCK[Account['A_REVENUE_ROOM_BUDGET']] + BLOCK[Account['A_REVENUE_FNB_BUDGET']]
BLOCK[Account['A_MGMT_FEE_INCOME']] = BLOCK[Account['A_REVENUE_BUDGET']] * BLOCK[Account['A_MGMT_FEE_RATE']]
BLOCK[Account['A_MGMT_FEE_INCOME_TAX']] = ROUND(
    BLOCK[Account['A_MGMT_FEE_INCOME']] * BLOCK[Account['A_TAX_RATE'], Period['NoPeriod']],
    2
)

说明:

  • 一个脚本中可以串联多个结果科目的重算过程。

  • 固定属性类参数,如税率,常见做法是从 NoPeriod 这类固定期间取值。

适用场景:

  • 季度预算重算

  • 预算编制后批量派生结果科目

  • 含税/不含税金额联动计算


下面的示例先汇总全年可售间夜和已售间夜,再计算全年入住率。这样可以避免直接对月度入住率做平均,导致结果失真。

Copy
SCOPE(
    Year['2025'],
    Period['TotalPeriod'],
    Base(Entity['EAST']),
    Scenario['ACTUAL'],
    Source['SR00']
)

CLEAR_DATA(
    Account['A_ROOM_NIGHT_AVAIL_YEAR', 'A_ROOM_NIGHT_SOLD_YEAR', 'A_OCC_RATE_YEAR']
)

BLOCK[Account['A_ROOM_NIGHT_AVAIL_YEAR']] = SUM(
    BLOCK[Base(Period['TotalPeriod']), Account['A_ROOM_NIGHT_AVAIL']]
)
BLOCK[Account['A_ROOM_NIGHT_SOLD_YEAR']] = SUM(
    BLOCK[Base(Period['TotalPeriod']), Account['A_ROOM_NIGHT_SOLD']]
)
BLOCK[Account['A_OCC_RATE_YEAR']] = 0
BLOCK[Account['A_OCC_RATE_YEAR']] = IIF(
    BLOCK_VAL[Account['A_ROOM_NIGHT_AVAIL_YEAR']] > 0.005,
    BLOCK[Account['A_ROOM_NIGHT_SOLD_YEAR']] / BLOCK[Account['A_ROOM_NIGHT_AVAIL_YEAR']]
)

说明:

  • 率类指标通常先汇总基础量,再计算最终结果。

  • 如果直接汇总率值或平均率值,往往不能准确反映年度口径。

适用场景:

  • 入住率

  • 毛利率

  • 费用率

  • 单价、占比等衍生指标


下面的示例根据组织属性 ud2 的不同,分别执行两套计算规则。TYPE_A 组织按固定费率计算,TYPE_B 组织按保底值和比例值二选一。

Copy
SCOPE(
    Year['2025'],
    Base(Entity['EAST']),
    Scenario['BUDGET'],
    Source['SR00']
)

CLEAR_DATA(Account['A_SERVICE_FEE'])

BLOCK[Account['A_SERVICE_FEE'], Base(Entity['EAST'], Attr('ud2') == 'TYPE_A')] = \
    BLOCK[Account['A_REVENUE_TOTAL']] * BLOCK[Account['A_SERVICE_RATE_STD']]

BLOCK[Account['A_SERVICE_FEE'], Base(Entity['EAST'], Attr('ud2') == 'TYPE_B')] = IIF(
    BLOCK_VAL[Account['A_REVENUE_TOTAL']] < BLOCK_VAL[Account['A_REVENUE_THRESHOLD']],
    BLOCK[Account['A_SERVICE_FEE_MIN']],
    BLOCK[Account['A_REVENUE_TOTAL']] * BLOCK[Account['A_SERVICE_RATE_STD']]
)

说明:

  • 当规则按成员属性分流时,可以直接拆成多个目标数据块分别计算。

  • 这种写法比在一个公式里叠加过多分支更容易维护。

适用场景:

  • 不同门店类型使用不同费率

  • 不同组织层级使用不同预算规则

  • 业务规则按属性分段执行


下面的示例用于检查“集团总部 2025 年第一季度预算总额”这一类结果是否正确。这里假设 E_HEAD_OFFICE 表示集团总部,结果科目为 A_BUDGET_TOTAL

Copy
SCOPE(
    Entity['E_HEAD_OFFICE'],
    Year['2025'],
    Period['Q1'],
    Scenario['BUDGET'],
    Source['SR00']
)

DISPLAY_DATA(
    BLOCK[Account['A_BUDGET_TOTAL']],
    max_rows=20,
    sort_by='Account'
)

说明:

  • 这种写法适合把业务语言先映射为维度成员编码,再快速核对结果。

  • 在调试阶段,也可以先打印来源科目,再打印结果科目,对比计算前后数据。

适用场景:

  • 快速核对某个组织、期间、版本下的结果值

  • 校验成员编码是否选择正确

  • 检查预算、实际、预测等不同场景口径


下面的示例先在底层组织计算结果科目 A_MGMT_FEE_INCOME,再将结果向上汇总到父级组织,最后打印父级结果进行检查。

Copy
SCOPE(
    Year['2025'],
    Base(Entity['EAST']),
    Base(Period['TotalPeriod']),
    Scenario['BUDGET'],
    Source['SR00']
)

CLEAR_DATA(Account['A_MGMT_FEE_INCOME'])

BLOCK[Account['A_MGMT_FEE_INCOME']] = BLOCK[Account['A_REVENUE_TOTAL']] * BLOCK[Account['A_MGMT_FEE_RATE']]

ROLLUP(Entity['EAST'])

DISPLAY_DATA(
    BLOCK[Account['A_MGMT_FEE_INCOME'], Entity['EAST']],
    max_rows=20,
    sort_by='Entity'
)

适用场景:

  • 底层门店先算,区域节点后汇总

  • 汇总后立即校验父级结果

  • 预算或分析指标逐级上卷


下面的示例用于计算关联方服务收入。计算时,来源科目 A_INTERCOMPANY_PRICEEntityPartner 维度需要互换后再参与运算。

Copy
SCOPE(
    Year['2025'],
    Base(Partner['P_TOTAL']),
    Scenario['ACTUAL'],
    Source['SR00']
)

BLOCK[Account['A_INTERCOMPANY_SERVICE_INCOME']] = \
    BLOCK[Account['A_INTERCOMPANY_VOLUME']] * \
    CROSS_DIMENSION(
        BLOCK[Account['A_INTERCOMPANY_PRICE'], Base(Entity['E_TOTAL'])],
        {'Entity': 'Partner'}
    )

说明:

  • CROSS_DIMENSION(...) 适合处理需要跨维度映射成员的场景。

  • 这类计算通常出现在关联交易、内部往来、对手方匹配等业务中。

适用场景:

  • 关联方交易

  • 内部结算

  • 对手方口径计算


下面的示例从全年期间中剔除第四季度,再与试点月份范围做交集,只在筛选后的期间集合内执行预算复制。

Copy
SCOPE(
    (IDescendant(Period['Y2025']) - Base(Period['Q4'])) & Period['1', '2', '3', '4', '5', '6'],
    Entity['E_HEAD_OFFICE'],
    Scenario['BUDGET']
)

BLOCK[Account['A_EXPENSE_PLAN']] = BLOCK[Account['A_EXPENSE_BASELINE']]

说明:

  • - 可用于剔除某些期间或组织范围。

  • & 可用于从较大的集合中进一步筛选出交集部分。

适用场景:

  • 剔除停业月份

  • 只对试点组织或试点期间执行测算

  • 在已有大范围中再精确圈定执行范围


下面的示例根据收入规模分三档计算激励金额:低于基准时取 0,处于中间区间时按标准费率,高于目标值时按奖励费率。

Copy
BLOCK[Account['A_INCENTIVE_AMOUNT']] = IIF(
    BLOCK_VAL[Account['A_REVENUE_TOTAL']] < BLOCK_VAL[Account['A_REVENUE_BASE']],
    0,
    IIF(
        BLOCK_VAL[Account['A_REVENUE_TOTAL']] < BLOCK_VAL[Account['A_REVENUE_TARGET']],
        BLOCK[Account['A_REVENUE_TOTAL']] * BLOCK[Account['A_INCENTIVE_RATE_STD']],
        BLOCK[Account['A_REVENUE_TOTAL']] * BLOCK[Account['A_INCENTIVE_RATE_BONUS']]
    )
)

适用场景:

  • 阶梯提成

  • 分档奖励

  • 超额完成激励


下面的示例先通过 ABS 将偏差值转为绝对值,再使用 MINMAX 限定最终调整金额的上下限。

Copy
BLOCK[Account['A_VARIANCE_ABS']] = ABS(BLOCK[Account['A_VARIANCE']])

BLOCK[Account['A_ADJUSTMENT_AMOUNT']] = MAX(
    BLOCK[Account['A_ADJUSTMENT_MIN']],
    MIN(
        BLOCK[Account['A_VARIANCE_ABS']] * BLOCK[Account['A_ADJUSTMENT_RATE']],
        BLOCK[Account['A_ADJUSTMENT_MAX']]
    )
)

说明:

  • ABS 适合处理偏差、差异额等可能为负数的场景。

  • MINMAX 可用于控制结果的上下边界。

适用场景:

  • 保底值、封顶值控制

  • 差异额绝对值处理

  • 调整金额限制


下面的示例先打印收入和费率来源,再打印管理费收入结果,便于定位问题出现在来源数据还是计算逻辑。

Copy
SCOPE(
    Year['2025'],
    IBase(Period['Q1']),
    Entity['E_HEAD_OFFICE'],
    Scenario['BUDGET'],
    Source['SR00']
)

DISPLAY_DATA(
    BLOCK[Account['A_REVENUE_TOTAL']],
    max_rows=20,
    sort_by='Period'
)

DISPLAY_DATA(
    BLOCK[Account['A_MGMT_FEE_RATE'], Period['NoPeriod']],
    max_rows=20,
    sort_by='Account'
)

BLOCK[Account['A_MGMT_FEE_INCOME']] = BLOCK[Account['A_REVENUE_TOTAL']] * BLOCK[Account['A_MGMT_FEE_RATE'], Period['NoPeriod']]

DISPLAY_DATA(
    BLOCK[Account['A_MGMT_FEE_INCOME']],
    max_rows=20,
    sort_by='Period'
)

适用场景:

  • 排查来源数据是否正确加载

  • 对比计算前后结果

  • 定位是取数范围问题还是公式问题


  • 建议先用 SCOPE(...) 明确当前计算范围,再编写 BLOCK 计算语句。

  • 对目标结果重算时,通常先执行 CLEAR_DATA(...)

  • 对比率、费率、单价类指标,建议先汇总基础量,再计算最终结果。

  • 当规则需要按组织属性、门店类型、品牌类型等分流时,可拆分多个数据块分别计算。

  • 当结果需要统一精度时,可使用 ROUND(...)

  • 当需要控制保底值、封顶值或绝对值时,可结合 MAX(...)MIN(...)ABS(...) 使用。

  • 编写完成后,可先通过 DISPLAY_DATA(...) 检查来源数据块,再检查结果数据块。

回到顶部

咨询热线

400-821-9199

我们使用 ChatGPT,基于文档中心的内容以及对话上下文回答您的问题。

ctrl+Enter to send