【高手过招】—— Excel 表格 使用日期函数踏过的一个坑

流程背景:

前阵子做了个 RPA 流程,RPA 流程内容是从某平台查询当天数据(需要输入当天日期),执行计划是每天跑一次。出于容错考虑,假设某天程序执行失败,第二天需要补查前一天的数据。所以没将查询日期写死在程序里面。计划通过 excel 自带的日期函数【=TODAY()】完成,如果需要补查之前日期的数据,在 excel 里面改下日期即可(帖子有点啰嗦,可在贴末直接看总结)。


设计概要:

  • 如下图:假如当天是 5 月 10 号,无论是 WPS 或 Excel 打开表格,里面显示的是 5 月 10 日的日期,次天读取时就会读成 11 号,周而复始。如果程序哪天执行失败了,次日只需要给单元格的函数 -1 就好,如:=TODAY()-1,通过这样子的方式来补跑一天前乃至几天前的数据即可。

问题现象:

···································· 隔离两天后,这是日期分割线 ····································

  • 今天是 12 号了,通过运行程序发现,程序查询的还是 5 月 10 号的日期,也就是说程序出 bug 了,因为按照正常来说,程序今天查询应该是 12 号数据才对,但实际却是查询 10 号的数据,然后下面我就开始了排查 bug 的道路。

排查步骤:

排查 1:检查表格

  • 怀疑是 excel 日期出的问题。于是我先打开 excel 做检查,发现 excel 显示的日期是 5 月 12 号,如图,也就是说明 excel 显示没问题。

排查 2:检查代码

  • 检查程序流程代码。怀疑代码中某个获取日期数值的关键位置,可能在开发时为了方便测试,所以把日期写死为为 5 月 10 号的日期。逐一检查后,发现代码正常,不存在日期写死的情况。

排查 3:重试流程

  • 重新运行程序、重现问题。在程序运行后,恍然发现程序又运行正常了,可以查询的 12 号的数据。于是开始了一系列怀疑人生的道路。。。。

排查 4:对比输出

  • 经过再三反思和仔细推敲,怀疑程序是读取 excel 时出的问题。于是将程序执行到读取 excel 的数据的那一步,并将数据进行输出,结果如下:
[datetime.datetime(2020, 5, 12, 0, 0), datetime.datetime(2020, 5, 12, 0, 0), datetime.datetime(2020, 5, 12, 0, 0),,,,]
  • 显示读取日期数值是 5 月 12 号,结果正常。

  • 于是我又从回收站翻出了一个前两天测试的文件,用 Excel 打开看了一下内容,单元格依旧是使用函数显示 5 月 12 号。于是重新执行程序进行读取单元格输出。结果如下:

[datetime.datetime(2020, 5, 10, 0, 0), datetime.datetime(2020, 5, 10, 0, 0), datetime.datetime(2020, 5, 10, 0, 0),,,,]
  • 这回输出的日期却是 5 月 10 号,和 EXCEL 手动打开显示的内容完全不一致。

推断过程:

推断 1:

  • 通过程序读取的表格内容,和我们平时使用 Excel 或 Wps 查看的表格内容并不一样。

推断 2:

  • 如 Excel 在打开表格时,会对表格文件中单元格的函数重新进行计算,再显示给用户看。

推断 3:

  • 而程序读取表格时,并不会对单元格的函数重新进行计算,而是直接读取文件最后一次修改的数据值。

推断 4:

  • 排查步骤 3 中输出的日期数据是 12 号的,之所以会这样子是因为我在进行排查步骤 1 时,检查到日期正常,下意识按了 ctrl+s 进行保存,导致触发 Excel 重新计算 单元格的函数的各个值。(关于这点,我通过检查排除步骤 3 里面两个文件的属性,里面的修改时间确实一个为 10 号,一个为 12 号)

解决方案:

  • 在程序初始化的时候,更新一下表格的某个单元格(理论上只需要重新打开并保存下表格就行,并不需要重新写入),如图,我对表格的 A1 单元格进行重新写操作(自动保存),之后再在读取日期列时,日期列输出则变成了 5 月 12 号,即当前日期。完美解决问题。

[datetime.datetime(2020, 5, 12, 0, 0), datetime.datetime(2020, 5, 12, 0, 0), datetime.datetime(2020, 5, 12, 0, 0),,,,]

总结陈词:

  • 如果 Excel 表格里面的单元格使用到了日期函数,建议每次在读取相关数据之前,先打开和保存 (关闭) 下 Excel。之后再进行数据读取,防止读取的单元格数据为老数据。

至此,问题解决,good night!

活动传送门: 高手过招,邀你来“炫”技!