ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Power BI 4-4-5零售财务日历:Power Query可配置实现方案

Power BI 4-4-5零售财务日历:Power Query可配置实现方案 做了快十年数据我接过最多的需求大概就是“把财务口径的账期搬进Power BI”。很多业务部门发来的Excel里都有这样的列FiscalMonth、Period、WeekNo看起来人畜无害但当你试图用Power BI自带的日期表去对齐它们时才知道什么叫鸡同鸭讲。4-4-5日历就是其中最有代表性的一种。这篇文章不绕弯子直接解决一个问题如何在Power BI里实现一套自定义的4-4-5财务日历。所谓自定义不是写死某个财年而是可以随时调整财年起始规则、期间拆分方式换一家公司换一套财年规则改一个参数就能跑。内容适合正在做零售、电商、连锁、快消或财务分析的读者尤其是被“本期同比到底怎么算”折磨过的人。看完你可以直接复制代码回Power BI跑出物理日期表再接上度量值整套账期体系落地。1. 4-4-5日历到底特殊在哪账期和自然日历为何对不上1.1 4-4-5不是“四年四个月五周”而是财务期的排布规则4-4-5是零售和快消行业常用的财务日历结构。它把一年分成四个季度每个季度再拆成三个会计期间每个期间的周数分别是4周、4周、5周。四个季度加起来正好是一年的52周。用表格看更清楚财季第1期第2期第3期季度周数合计Q14周4周5周13周Q24周4周5周13周Q34周4周5周13周Q44周4周5周13周这个结构最大的价值在于每一期都包含完整的周不会把一个周从中间劈开。比如你对比今年第1期和去年第1期两个期间不仅天数大致相等而且包含的周末数、工作日数也完全一致甚至每天是星期几都对得上。这对门店零售、线上电商、库存周转这类受周末影响的业务来说是最公平的同比口径。自然月做不到这件事。同样是1月2024年1月有4个周末2025年1月可能就有5个周末线下零售一天一个样你拿自然月做同比前两年可能还说得过去一旦周末分布漂移报表里的增长波动就分不清是经营变好还是日历差异造成的了。1.2 漂移的会计期间为什么普通日期表标不了账期4-4-5日历有一个让数据人头疼的特点会计期间和自然日期是错位的而且每年都会漂移。举个具体例子。如果财年规定“包含1月1日的那一周是第1周”那么2024财年的第1周可能从2023年12月31日就开始而2025财年的第1周又可能从2024年12月29日开始。每年12月底的几天在自然日历上属于2024年在4-4-5日历里却已经进入了2025财年的第1期。这就是问题所在。Power BI自带的日期表只认自然年、季度、月、周它不会告诉你某一天属于财务上的第几期。你拿“月份”字段去划分账期得到的结果会把各期边界切得乱七八糟拿“年”去做同比12月最后几天的销售会被归到错误的财年。普通日期表不是不好而是它的业务口径里根本没有“财务期间”这个概念。1.3 谁会用到这个日历以及自定义到底指什么真正需要4-4-5日历的是那些看“账期”不看“月份”的行业。零售、电商、快消、连锁门店、供应链结算甚至一些上市公司的对外财报到财季层面也用类似结构。财务关账时他们说的“本期”“上期”“当月累计”指的都是会计期间而不是自然月。你要是在模型里没把账期表建出来这些需求没有一个能做对。“自定义”两个字也有具体含义。不同企业的财年起止规则不一样有的按“包含1月1日的那周”作为第1周有的按“12月最后一个周日的次日”作为第1周更常见的是把1月前的几周算进上一财年。期间拆分也有差异4-4-5只是最普及的一种还有人用4-5-4、5-4-4甚至13个4周的“13期结构”。所以这套日历的实现方案必须能通过改配置适配不同规则而不是写成死代码。2. 三种实现路线对比为什么我坚持用Power Query生成物理表2.1 选项A手工维护一张445日历表最早我看到很多公司的做法是财务人员手工在Excel里维护一张日历表从哪年哪周开始每一期落在哪个区间全都手敲进去再导入Power BI。优点是足够直观任何人都能看懂缺点也致命——手工表一旦跨年就容易出错。期间起始日写错一天后面所有周全都错位。而且维护频率低公司改一次记账规则整张表就要重做。你让财务每个月去更新一张几千行的日期表他们迟早会来骂你。这种方案只适合一次性项目不适合做成长期报表基建。2.2 选项BDAX在报表层动态生成另一种思路是不建物理表用DAX在Power BI内部动态生成一个虚拟日期表。写一组ADDCOLUMNS、CALENDAR、WEEKNUM公式把4-4-5的期间逻辑塞进去。听起来很酷但实际使用中我踩过不少坑。第一DAX代码非常长调试难度高稍不注意就是上下文错误第二动态生成的表每次刷新都要重新计算数据量上来之后报表打开会变慢第三很多DAX生成的方式其实是“表表达式”没法作为真正的维度表被多个度量稳定引用。日期表在模型里的定位应该是物理维度表而不是运行时虚拟表这是我在若干个项目里被性能问题教育出来的结论。2.3 选项CPower Query M脚本生成物理维度表我最终选的是Power Query M语言生成物理日期表这也是本文的核心方案。它有几个其他方案替代不了的好处表生成一次就是静态的之后所有DAX计算都变成离散的单行查列性能最好。整个逻辑集中在一个M脚本里改财年规则、改期间拆分改一行配置就行。刷新时自动重建日期表只要起止日期设置合理永远不会越界。代价是M语言对新手有学习门槛。但别担心这个脚本是完整可复制的你不需要从头写M只要会用Power Query的高级编辑器粘贴就行。2.4 整体实现思路一句话做4-4-5日历核心逻辑可以压缩成五个步骤生成连续的日期列表把日期按“周”聚合确定每周的财年归属在每个财年内给周排序编号得到第1周到第52或53周把13周切成4-4-5得到会计期间根据期间规则反推出每个期间和每周的起止日。后面的内容就是把这五步掰开揉碎讲清楚。3. 核心公式拆解先做“周”再用三天偏移修跨年3.1 为什么第一步先按“周”聚合而不是直接按“天”切账期做4-4-5最容易犯的错误就是一上来就按日期一行一行去判断属于哪个账期。我最早就是这么干的结果代码写出来又长又绕每个日期都要算它是4-4-5里的第几周最后还要处理跨年整个公式一团乱麻。正确的做法是先把日期提升到“周”这个粒度把每一周当成一个最小业务单位。为什么因为4-4-5的结构是按周定义的不是按天定义的。一个期间到底是5周还是4周本质上是周的编号问题。只要我们在“周”的层面上把编号编对了再把每一周展开到它包含的每一天所有的日期自然就落在正确的账期里。这个顺序反过来做就会非常痛苦。M语言里有一个现成的函数可以拿到周起始日Date.StartOfWeek([Date], Day.Sunday)Day.Sunday表示把周日作为一周的起点。这一步做完同属一周的日期会共享同一个WeekStartDate后续就能按这个字段分组聚合。3.2 跨年那几天该算哪个财年三天偏移的奥妙跨年周归属是整个实现里最容易搞错的地方。2025年1月3日自然属于2025年但它的那一周是从2024年12月29日开始的。在4-4-5日历里这整周会被算成2025财年的第1周还是2024财年的最后一周答案取决于企业怎么定义财年第1周。最常见的规则是包含1月1日的那一周就是这个财年的第1周。按照这个规则2024年12月29日到2025年1月4日那一周因为包含了1月1日应该属于2025财年。如果用日期自身的年份来判断12月29日、30日、31日会被归到2024财年1月1日后三天归到2025财年同一个周被劈成两半4-4-5直接废掉。解决方法是取该周中间日的年份。以周日为起点的一周中间日是周四也就是WeekStartDate加3天。你可以简单理解成一个周归属于“它中间那天”所在的自然年。这个“三天偏移”能保证包含1月1日的那一周其中间日一定落在1月1日到1月4日之间不会跑出当年的范围而它前面的那一周中间日落在12月末还会稳稳待在旧财年。M表达式如下FiscalYear Date.Year(Date.AddDays([WeekStartDate], 3))这里要特别说明一下为什么不能偏移到第6天周日加6天拿到那个周的周六。因为如果1月1日恰好是周一那一周的周六就是1月7日已经跑到下一年去了财年归属就会判断错误。选中间日而不是选周末日是为了让归属逻辑对任何1月1日的星期几都稳定成立。3.3 13周如何干净地切出4-4-5每个财年内周已经被连续编号成FiscalWeekNumber从1一直到52或53。4-4-5的季度规律是每13周一组13周内部再按“4、4、5”拆成三个期间。具体映射关系是财周范围财季会计期间第1-4周Q1第1期第5-8周Q1第2期第9-13周Q1第3期第14-17周Q2第4期第18-21周Q2第5期第22-26周Q2第6期...以此类推......公式上财季可以用FiscalWeekNumber除以13向上取整得到期间号则是在季度内判断落在第1段、第2段还是第3段。这里有一个小技巧第3段是5周所以判断条件分别是1-4、5-8、9-13。这样切出来的账期和业务口径完全一致。3.4 会计期间起止日期是怎么自动算出来的有了期间编号还差每个期间的起始日和结束日。这里我用了一个很关键的配置列表PeriodPattern {4, 4, 5, 4, 4, 5, 4, 4, 5, 4, 4, 5}这个列表就是4-4-5的结构本身。第1个元素是第1期的周数第2个元素是第2期的周数依次类推。有了它任何一个会计期间的起始日都能算出来一个会计期间的起始日 财年第一周起始日 该期间之前所有期间的累计周数 × 7天用M语言写是这样的weeksBefore List.Sum(List.FirstN(PeriodPattern, [FiscalPeriod] - 1)) FiscalMonthStart Date.AddDays([FiscalYearStartDate], weeksBefore * 7)为什么要用这种“从财年第一周往后推”的方式而不是硬编码每个期间的日期因为4-4-5日历的财年起始日是漂移的今年12月底开始明年可能12月29日开始硬编码一定会出错。用相对周数向后推无论财年起始日怎么变期间边界都会自动跟着走。第12期的结束日则稍微特殊它等于财年第一周起始日 该财年总周数 × 7天 - 1天。这样设计是为了兼容53周年的年份不用单独写判断。4. 完整M代码和四个必经的操作步骤4.1 可以直接复制的完整M代码以下是完整的Power Query M脚本。你不需要理解每一行但建议把注释读一遍它会帮你定位需要改的配置。let // 1. 可配置参数 StartDate #date(2024, 12, 29), // 业务数据最早日期 EndDate #date(2026, 1, 3), // 业务数据最晚日期跨年周需要留到财年最后一周结束 PeriodPattern { 4, 4, 5, 4, 4, 5, 4, 4, 5, 4, 4, 5 }, // 4-4-5结构改成4-5-4就替换对应位置的数字 // 2. 生成自然日历年全量日期 WholeStart #date(Date.Year(StartDate), 1, 1), WholeEnd #date(Date.Year(EndDate), 12, 31), DateList List.Dates( WholeStart, Duration.Days(WholeEnd - WholeStart) 1, #duration(1, 0, 0, 0) ), RawTable Table.FromList( DateList, Splitter.SplitByNothing(), {Date}, null, null ), // 3. 计算每个日期的周起始日周日为一周起点 WithWeekStart Table.AddColumn( RawTable, WeekStartDate, each Date.StartOfWeek([Date], Day.Sunday), Date.Type ), // 4. 先按周聚合确定周的财年归属 WeekGroups Table.Group( WithWeekStart, {WeekStartDate}, {{WeekRows, each _, type table}} ), // 跨年周归属取每周中间日周日3天周四所在的自然年作为财年 WithFiscalYear Table.AddColumn( WeekGroups, FiscalYear, each Date.Year(Date.AddDays([WeekStartDate], 3)), Int64.Type ), // 5. 按财年分组财年内给周排序编号 YearGroups Table.Group( WithFiscalYear, {FiscalYear}, { { YearRows, each Table.AddIndexColumn( Table.Sort(_, {{WeekStartDate, Order.Ascending}}), FiscalWeekNumber, 1, 1, Int64.Type ), type table }, {FiscalYearTotalWeeks, each Table.RowCount(_), Int64.Type}, {FiscalYearStartDate, each List.Min(_[WeekStartDate]), Date.Type} } ), // 6. 展开周还原到日 ExpandedDates Table.ExpandTableColumn( YearGroups, YearRows, {WeekStartDate, WeekRows}, {WeekStartDate, WeekRows} ), ExpandedDates2 Table.ExpandTableColumn( ExpandedDates, WeekRows, {Date}, {Date} ), // 7. 计算财季、会计期间 // 财季前13周为Q114-26周为Q227-39周为Q340-52周为Q4 // 53周年份的第53周并入第4季度第12期 WithQuarter Table.AddColumn( ExpandedDates2, FiscalQuarter, each if [FiscalWeekNumber] 52 then Number.RoundUp([FiscalWeekNumber] / 13.0, 0) else 4, Int64.Type ), // 会计期间季度内前4周第1期5-8周第2期9-13周第3期 WithPeriod Table.AddColumn( WithQuarter, FiscalPeriod, each let q if [FiscalWeekNumber] 52 then Number.RoundUp([FiscalWeekNumber] / 13.0, 0) else 4, w [FiscalWeekNumber] - (q - 1) * 13 in if [FiscalWeekNumber] 52 then (q - 1) * 3 ( if w 4 then 1 else if w 8 then 2 else 3 ) else 12, Int64.Type ), // 8. 计算会计期间起止日 WithPeriodStart Table.AddColumn( WithPeriod, FiscalMonthStart, each let weeksBefore List.Sum(List.FirstN(PeriodPattern, [FiscalPeriod] - 1)) in Date.AddDays([FiscalYearStartDate], weeksBefore * 7), Date.Type ), WithPeriodEnd Table.AddColumn( WithPeriodStart, FiscalMonthEnd, each if [FiscalPeriod] 12 then let weeksIntoNext List.Sum(List.FirstN(PeriodPattern, [FiscalPeriod])) in Date.AddDays(Date.AddDays([FiscalYearStartDate], weeksIntoNext * 7), -1) else Date.AddDays([FiscalYearStartDate], [FiscalYearTotalWeeks] * 7 - 1), Date.Type ), // 9. 过滤业务范围并整理输出列 FilteredRows Table.SelectRows( WithPeriodEnd, each [Date] StartDate and [Date] EndDate ), Final Table.SelectColumns( FilteredRows, { Date, WeekStartDate, FiscalYear, FiscalWeekNumber, FiscalQuarter, FiscalPeriod, FiscalMonthStart, FiscalMonthEnd, FiscalYearStartDate, FiscalYearTotalWeeks } ), WithDateKey Table.AddColumn( Final, DateKey, each Date.Year([Date]) * 10000 Date.Month([Date]) * 100 Date.Day([Date]), Int64.Type ), WithPeriodKey Table.AddColumn( WithDateKey, FiscalPeriodKey, each [FiscalYear] * 100 [FiscalPeriod], Int64.Type ), WithWeekKey Table.AddColumn( WithPeriodKey, FiscalWeekKey, each [FiscalYear] * 100 [FiscalWeekNumber], Int64.Type ), SortedResult Table.Sort(WithWeekKey, {{Date, Order.Ascending}}) in SortedResult运行这个脚本后你会得到一张包含日期、财年、财周、财季、期间、期间起止日的完整日历表。4.2 从Power Query回填到模型的三个动作脚本跑出表之后要做三件事才能让它真正成为日期维度。第一步右键查询表选择“关闭并加载”让表进入Power BI的数据模型。这里我建议直接把查询命名为DimFiscalCalendar后面写度量会好引用很多。第二步选中Date列确保数据类型是日期然后在表工具里点击“标记为日期表”。会弹出一个提示让你指定哪一列是日期列选Date就行。第三步如果你希望期间能按正确顺序排列而不是按文本排序可以给FiscalPeriod建一个排序依据列。比如给每个期间加一个0-11的数值列或者直接用已有的FiscalPeriodKey当作排序字段。这三步做完一张可以用的4-4-5日期表就算正式落库了。4.3 怎么用四组数验证5000行日期表是对的别急着连事实表。日期表这种基础设施错一个数后面全错建议先做四组验证。第一组每个财年内FiscalWeekNumber从1开始连续递增到52或53中间不能有跳号这是“周完整”的保证。第二组每个财季包含13个FiscalWeekNumber且第4季度一定是从第40周开始。再看FiscalPeriod在每个财季内严格按4、4、5周分布。第三组任意一天的FiscalMonthEnd加1天应该正好等于下一个期间的FiscalMonthStart。如果中间出现断档说明期间边界算错了。第四组把FiscalYear加上标签肉眼检查跨年那几天。例如2024年12月29日那周在表里应该归到2025财年第1周而不是2024财年第52周。大多数错误都藏在这个地方。4.4 关于起止日期不要在12月31日截断要留出跨年尾巴这里有个实战中特别容易掉的坑生成日期表时EndDate不要只写到业务数据截止的那一天。因为4-4-5财年的最后一周经常跨到下一年。假设你要覆盖2025财年全年而2025财年的最后一周是2026年1月3日结束那么EndDate至少要填到2026年1月3日。如果你偷懒填成2025年12月31日这最后一周会被过滤掉2025财年就缺了5天数据。我自己的习惯是StartDate从“要覆盖的最早一个完整财年第一周”开始EndDate写到“要覆盖的最晚一个完整财年最后一周”的下一个周末。哪怕宽出来几天事实表里没有数据也不影响结果但日期表的完整性对标记日期表请求非常关键。5. 接入模型后的DAX期间同比、周期累计与第53周处理5.1 维度表和事实表的关系与筛选方向日期表建好之后第一步是把DimFiscalCalendar[Date]和事实表的交易日期建立一对多关系筛选方向是单向DimFiscalCalendar筛FactSales。有一点要注意Power BI模型里通常只有一个日期表会被“标记为日期表”。如果你同时保留了自然日历年表又加了这套4-4-5表两个表都可以存在但不要把同一个事实表的日期列同时连到两张表上否则模型会出现歧义关系很多度量会报“表之间存在多条路径”的错误。实际项目中零售财务口径通常直接用4-4-5表当唯一日期表自然日期表只在业务确需自然月对比时才单独保留。5.2 本期、上期、同比的DAX写法最简单的“本期销售”就是普通求和本期销售 SUM(FactSales[SalesAmount])关键在于“上期”。因为4-4-5的期间不是自然月不能靠DATEADD的本月上月来算。正确做法是把筛选上下文里的FiscalPeriod减1同时保持FiscalYear不变。上期销售 VAR CurrentYear SELECTEDVALUE(DimFiscalCalendar[FiscalYear]) VAR CurrentPeriod SELECTEDVALUE(DimFiscalCalendar[FiscalPeriod]) RETURN CALCULATE( SUM(FactSales[SalesAmount]), FILTER( ALL(DimFiscalCalendar), DimFiscalCalendar[FiscalYear] CurrentYear DimFiscalCalendar[FiscalPeriod] CurrentPeriod - 1 ) )这里有个细节当期1的时候CurrentPeriod - 1 0会算出空值。更严谨的写法是先判断 CurrentPeriod 1 时转到上一年第12期上期销售 VAR CurrentYear SELECTEDVALUE(DimFiscalCalendar[FiscalYear]) VAR CurrentPeriod SELECTEDVALUE(DimFiscalCalendar[FiscalPeriod]) VAR PrevYear IF(CurrentPeriod 1, CurrentYear - 1, CurrentYear) VAR PrevPeriod IF(CurrentPeriod 1, 12, CurrentPeriod - 1) RETURN CALCULATE( SUM(FactSales[SalesAmount]), FILTER( ALL(DimFiscalCalendar), DimFiscalCalendar[FiscalYear] PrevYear DimFiscalCalendar[FiscalPeriod] PrevPeriod ) )同比的逻辑也一样只是把期间号保持不变财年减1上年同期销售 VAR CurrentYear SELECTEDVALUE(DimFiscalCalendar[FiscalYear]) VAR CurrentPeriod SELECTEDVALUE(DimFiscalCalendar[FiscalPeriod]) RETURN CALCULATE( SUM(FactSales[SalesAmount]), FILTER( ALL(DimFiscalCalendar), DimFiscalCalendar[FiscalYear] CurrentYear - 1 DimFiscalCalendar[FiscalPeriod] CurrentPeriod ) )5.3 财年周期累计PTD的DAX写法周期累计是“从财年第一天累到当前日期”缩写叫PTD。4-4-5下不能直接用DATESYTD因为DATESYTD认自然年会让12月底的数据和1月初的数据混在一起。推荐用过滤方式写财年累计销售 VAR MaxDate MAX(DimFiscalCalendar[Date]) VAR FiscalYearStart CALCULATE( MIN(DimFiscalCalendar[Date]), ALL(DimFiscalCalendar), DimFiscalCalendar[FiscalYear] SELECTEDVALUE(DimFiscalCalendar[FiscalYear]) ) RETURN CALCULATE( SUM(FactSales[SalesAmount]), DATESBETWEEN(DimFiscalCalendar[Date], FiscalYearStart, MaxDate) )这个写法的好处是无论当前筛选到了某个日期、某一周还是某个期间累计范围都是从该财年第一天到当前可见的最后一天逻辑不会串。5.4 53周年年份的度量口径怎么定53周年是4-4-5日历里绕不开的话题。大约每5到6年会出现一个含53周的财年因为自然年365天除以7每年会多出1天多几年积累下来就多出整整一周。第53周怎么处理业务上一般有两种口径一种是并月把第53周并进第12会计期间让当年12月变成6周。这种口径下没必要做特别处理因为日期表在第12期里自然包含27天左右的跨度度量值直接用就行。另一种是独立期把第53周单独标记出来不进入任何期间专门用来做库存盘点或异常调整。此时需要在日期表里加一列IsLeapWeek标记第53周并在期间维度上把它单列。无论如何报表里遇到53周年时同比口径要提前和财务对清楚。不然你会发现今年第12期是6周去年第12期是5周销售额同比突然高出一截看起来像业绩大涨其实是日历多出来一周。6. 后续维护与变体改造从4-4-5到4-5-4只需改一行6.1 53周年份第53周去哪再展开说一下第53周。在标准4-4-5规则下不是每年都有53周。通常当财年的1月1日落在某个特定星期时这个财年就会包含53周。具体哪一年会多一周不同企业有不同约定最稳妥的做法是让财务提供一个“未来五年的财年日历”反推自己的规则。我的M脚本里已经做了并月处理当FiscalWeekNumber 53时强制归入第4季度第12期。此时FiscalYearTotalWeeks 53第12期的结束日会自动落到第53周的周末不需要额外改代码。如果你想把第53周单独拆出来只需要把第7步里的判断条件改成“当FiscalWeekNumber 53时FiscalPeriod设为13”并把PeriodPattern的12个元素扩展为13个最后一位写1。6.2 改成4-5-4或5-4-4只动一行配置这套方案最讨喜的地方在于变体改造极其简单。比如公司改用4-5-4结构每个季度变成4周、5周、4周你只需要把PeriodPattern改成PeriodPattern {4, 5, 4, 4, 5, 4, 4, 5, 4, 4, 5, 4}改成5-4-4同理PeriodPattern {5, 4, 4, 5, 4, 4, 5, 4, 4, 5, 4, 4}其它逻辑一概不用动。因为期间起始日的计算完全依赖这个列表的累加列表一变起止日、期间号、财季划分全部自动重算。这也是“自定义”两个字落到实处的关键设计业务规则和算法逻辑彻底分离。6.3 性能考量为什么物理表优于动态生成我见过不少人在DAX里用表函数硬算4-4-5报表一打开就要扫描整个日历范围每切换一个维度都要重新计算一遍数据量一大就卡。而这种用Power Query生成的物理日期表发布到云端或本地网关后只是一张几千行的静态表所有过滤、聚合都走索引查找速度完全不是一个量级。10年日期也才3650行四年加一个闰年维度表非常小。后期就算加几十列辅助字段也不会对模型体积产生可感知的影响。基础表做得越厚重语义层越薄整个报表的维护成本反而越低。6.4 给报告加“第几周”标签与行级权限的延伸实际做报告时用户通常不想看到一堆数字他们想知道“这是财年的第几周”。你可以在查询里再加一列友好标签WithWeekLabel Table.AddColumn( WithWeekKey, FiscalWeekLabel, each Text.From([FiscalYear]) W Text.From([FiscalWeekNumber]), type text )如果需要做行级权限比如某些区域只看2025财年也可以直接用FiscalYear列做RLS规则比用自然年过滤更贴合财务口径。还有一个很容易忽略的小点报告里放“期间对比”图表时建议用FiscalPeriodKey当主筛选而不是用文本的期间名。数值键在排序和筛选时都更稳定不会出现“第10期排在‘第2期’前面”这种文本排序悲剧。最后说一个我自己的使用习惯日期表生成后我一般会顺手在 Excel 里打开做一次目测重点看每年的12月28日到次年1月7日那几天确认跨年周归属、期间起止日都符合财务给的日历。前面代码再怎么完美都不如这一眼核验来得安心。你做这个功能的时候也一样先让懂业务的人确认口径再让数据表落地口径对了后面的报表自然就活了。
返回列表