背景:前阵子做了个RPA流程,RPA流程内容是从某平台查询当天数据(需要输入当天日期),执行计划是每天跑一次。出于容错考虑,假设某天程序执行失败,第二天需要补查前一天的数据。所以没将查询日期写死在程序里面。计划通过excel自带的日期函数【=TODAY()】完成,如果需要补查之前日期的数据,在excel里面改下日期即可(帖子有点啰嗦,可在贴末直接看总结)。
如图:假如当天是5月10号,无论是WPS或Excel打开表格,里面显示的是5月10日的日期,次天读取时就会读成11号,周而复始。如果程序哪天执行失败了,次日只需要给单元格的函数 -1 就好,如:=TODAY()-1,通过这样子的方式来补跑一天前乃至几天前的数据即可。
····································隔离两天后,这是日期分割线····································
BUG出现:今天是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!