我们在实例10中介绍了工程部采购物料用于新产品开发,如何从杂乱的备注栏获取工程采购单号。获取到采购单号,只是第一步,随后还需要查询物料的交期和实际收货日期。

对于负责物料跟进的员工,每个新产品开发订单对应物料的交期都至关重要。物料清单中哪怕一个小小的物料无法即时到货,都可能导致成品无法准时交付,引起客户的抱怨及扣款,甚至丢掉生意。

公司的系统分为采购系统和物料接受系统。采购系统是采购部同事下单的时候使用的,里面会记录与供应商谈好的交期。当物料到厂后,货仓的同事会将物料收入库存之中,即在物料接受系统内登记物料名称及数量等信息。

每天公司都有一些新产品订单产生,每个订单对应一长串物料清单,这些物料的交期及实际收货日期需要跟进,如果逐个查询,将会花费大量的时间和精力。下面我们就演示使用Python来进行批量查询并写入到对应订单物料清单Excel表中。

我们的数据来源于两张Excel表,“采购信息表”和“收货信息表”。我们需要通过物料的编号和对应采购单号(EPR编号)去两张表中分别获取交期和实际收货日期。

#使用正则表达式获取EPR编号

from re import compile, IGNORECASE

def get_EPR_num(text):

#将问号'?' 替换成 '-'

changed_question_mark = text.replace('?','-')

#获取EPR编号

epr_num = compile(r'EPR-\d{2}-X\d{3}(\d)?',IGNORECASE)

match = epr_num.search(changed_question_mark)

#将小写EPR转换为大写并返回

return match.group().upper()

以上定义的函数来自实例10,用于从采购信息表乱七八糟的备注栏中提取出正确的EPR编号。详情可移步实例10:

PythonOffice:实例10:用Python正则表达式从不规则的备注栏获得采购申请单号zhuanlan.zhihu.comfrom openpyxl import load_workbook

#获取交期,并存入字典

def get_promise_date():

wb = load_workbook('data/采购信息表.xlsx')

ws = wb.active

promise_dates = {} #存储零件对应的EPR编号及交期

for row in range(2, ws.max_row+1): #从第2行开始遍历采购信息表

part_num = ws['A' + str(row)].value #A列为零件编号

promise_date = ws['B' + str(row)].value.date() #B列为交期

remark = str(ws['D' + str(row)].value) #D列为备注栏,其中包含EPR信息

promise_dates.setdefault(part_num, {}) #设置数据结构为字典套字典,外层字典的键为零件编号

EPR = get_EPR_num(remark)# 调用上面写好的正则表达式函数,从备注栏提取EPR编号

promise_dates[part_num].setdefault(EPR, promise_date)#内层字典以EPR编号为键,交期为值

return promise_dates

以上程序用于从“采购信息表”中提取交期信息。采购信息表如下图所示,它包含零件号,承诺交期,数量和备注栏。其中EPR编号就在备注栏中。当采购部门按照工程师的EPR申请下采购单后,就会在系统记录下这么一条采购信息,若系统无相关信息,则表示采购还未下单。

我们在提取交期信息的时候,必须同时对应到零件号和EPR编号。因为采购信息表里面可能存在相同的零件号对应多条信息。但是通过常规采购的,那就没有EPR编号(有EPR编号的都是工程部的特殊采购)。或者工程部对一个零件号特殊采购了两次,那就会有两个EPR编号。所以我们提取的信息的数据结构需要是这样子:

即一个大字典promise_dates内部含有嵌套字典。大字典的键全部为零件号,其值也是一个字典。嵌套的小字典用“EPR”编号作为键,值为“交期”,零件号对应的一条或多条EPR信息都放入这个字典。其中setdefault()函数在此非常关键,promise_dates.setdefault(part_num, {})的意思是,如果键part_num不存在于字典promise_dates中时,将会添加这个part_num为键,并将值设为空字典{};如果键part_num已经存在,将不会新建这个键,因为字典的键必须是唯一值,再新建会覆盖之前的数据。随后程序继续运行,我们通过写好的函数提取正确的EPR编号EPR = get_EPR_num(remark)。然后将对应的EPR和其交期放入嵌套的空字典{}中,即promise_dates[part_num].setdefault(EPR, promise_date)。此处嵌套字典也使用setdefault()函数是为了兼容多个交期对应一个EPR编号的情况。

比如采购信息表中的第一个零件号是'60022-5054001',因为这是第一个数据,'60022-5054001'肯定不在字典promise_dates中,所以此时就在字典promise_dates中新建了这个键'60022-5054001',其值为空字典{}。然后获取其第一个EPR编号,即'EPR-18-X1208',然后将其对应的交期一起作为键值对放入空字典中,这条信息就变为'60022-5054001': {'EPR-18-X1208': datetime.date(2018, 6, 15)}。随后for循环再检查下一行,这一行的零件号还是'60022-5054001',因此不用新建一个键,继续在之前的键'60022-5054001'里面追加数据即可,于是再将该零件号对应的第二个EPR对应的交期放入,信息变为'60022-5054001': {'EPR-18-X1208': datetime.date(2018, 6, 15), 'EPR-18-X1209': datetime.date(2018, 6, 16)}。然后继续遍历下一行,直到结束。我们可以调用一下这个函数,获取到的信息如下。

get_promise_date()

>>

{'60022-5054001': {'EPR-18-X1208': datetime.date(2018, 6, 15),

'EPR-18-X1209': datetime.date(2018, 6, 16)},

'8810020-01844': {'EPR-18-X713': datetime.date(2018, 6, 13)},

'8810030-01125': {'EPR-18-X713': datetime.date(2018, 8, 15)},

'8810140-00042': {'EPR-18-X713': datetime.date(2018, 6, 15)},

'8812121-02142': {'EPR-18-X941': datetime.date(2018, 8, 15)},

'8836012-04093': {'EPR-18-X942': datetime.date(2018, 8, 25)},

'8836032-02101': {'EPR-18-X942': datetime.date(2018, 6, 15)},

'8841001-00078': {'EPR-18-X684': datetime.date(2018, 8, 25)},

'8841002-00079': {'EPR-18-X684': datetime.date(2018, 6, 13)},

'8841019-00002': {'EPR-18-X449': datetime.date(2018, 6, 15)},

'8842001-00012': {'EPR-18-X688': datetime.date(2018, 8, 25)},

'8842002-00020': {'EPR-18-X708': datetime.date(2018, 6, 13)},

'8842008-00009': {'EPR-18-X897': datetime.date(2018, 4, 27)},

----------略---------#获取收货日期,并存入字典

def get_receive_date():

wb = load_workbook('data\收货信息表.xlsx')

ws = wb.active

receive_dates = {}

for row in range(2, ws.max_row+1):

part_num= ws['A' + str(row)].value

receive_date = ws['B' + str(row)].value.date()

epr_num = str(ws['D' + str(row)].value)

receive_dates.setdefault(part_num, {})

receive_dates[part_num].setdefault(epr_num, receive_date)

return receive_dates

然后我们从“收货信息表”中获取收货日期,并存入字典receive_dates,其数据结构和逻辑与获取采购信息一样。调用函数get_receive_date()可以看到收货信息的结果如下。

get_receive_date()

>>

{'8836012-04093': {'EPR-18-X942': datetime.date(2018, 8, 28)},

'8836032-02101': {'EPR-18-X942': datetime.date(2018, 6, 18)},

'8847006-00446': {'EPR-18-X1137': datetime.date(2018, 6, 16)},

'8812121-02142': {'EPR-18-X941': datetime.date(2018, 8, 18)},

'8860301-23560': {'EPR-18-X1086': datetime.date(2018, 5, 5)},

'8868707-00000': {'EPR-18-X572': datetime.date(2018, 8, 28),

'EPR-18-X676': datetime.date(2018, 8, 30)},

'60022-5054001': {'EPR-18-X1208': datetime.date(2018, 6, 18)},

'8874001-00001': {'EPR-18-X771': datetime.date(2018, 6, 16)},

'8862028-01010': {'EPR-18-X499': datetime.date(2018, 8, 18)},

'8863093-00000': {'EPR-18-X499': datetime.date(2018, 5, 5)},

------略----------#批量查询并写入采购信息和收货信息

from openpyxl import load_workbook

from os import walk, path

#调用以上两个函数,获取“交期”和“收货日期”

promise_date=get_promise_date() #交期

receive_date=get_receive_date() #收货日期

#遍历“订单”文件夹下的所有excel文件,根据零件编号,EPR编号,写入交期及收货日期,并存为新的文件

root = 'data/订单'

for dirpath, dirnames, filenames in walk(root):

for filename in filenames: #依次读取文件夹每个Excel文件进行操作

order = path.join(dirpath, filename)

print('处理订单:{}'.format(filename))

wb = load_workbook(order)

ws = wb.active

for row_number in range(5,ws.max_row+1):

part_num = ws.cell(row = row_number, column = 1).value

epr_num = ws.cell(row = row_number,column = 5).value

if epr_num: #判断该行是否有EPR编号,若有,才进一步查询交期及收货日期

# 判断采购信息表里是否有零件号和EPR编号,若都有,则写入其交期

if part_num in promise_date and epr_num in promise_date[part_num]:

ws.cell(row=row_number,column = 6).value = promise_date[part_num][epr_num]

else:

#零件号及EPR编号只要有一个未找到,就写入“未采购”

ws.cell(row=row_number,column = 6).value = '未采购'

#判断收货信息表里是否有零件号和EPR编号,若都有则写入收货日期

if part_num in receive_date and epr_num in receive_date[part_num]:

ws.cell(row=row_number, column=7).value = receive_date[part_num][epr_num]

else:

#零件号及EPR编号只要有一个未找到,就写入“未收到货”

ws.cell(row=row_number, column=7).value = '未收到货'

#搞定一行之后,在检查下一行,直到这个工作表全部检查完,然后保存,处理下一个Excel表

wb.save('data/订单更新/%s' % filepath)#在新的文件夹中使用原来文件名保存文件

print('完成!')

>>

处理订单:订单001.xlsx

处理订单:订单002.xlsx

处理订单:订单003.xlsx

处理订单:订单004.xlsx

处理订单:订单005.xlsx

完成!

采购信息和收货信息获取完成之后,就可以进行批量查询及在订单Excel表中写入数据了。用于获取文件路径的os模块,我们在实例2中有用到,可移步此链接查看:

PythonOffice:实例2 : 使用Python合并不同文件夹中的多个Excel文件zhuanlan.zhihu.com

我们利用它获取所有需要进行处理的Excel文件。此处,我们是将待处理文件存在data文件夹下面的订单文件夹内的。我们使用for循环,依次打开每个文件,然后进行数据的查询和写入。订单Excel文件的内容如下:

我们基于订单表中的零件编号和EPR编号,到采购信息和收货信息里面做匹配,只有当零件编号和EPR编号都匹配的时候,才写入数据。因为订单表从第5行开始才是我们需要匹配的数据,所以从第5行开始逐行查询并写入。我们先看EPR编号是否有内容,如果为空直接跳过,有内容,才进行下一步处理,if epr_num:即用于完成该判断。

EPR编号有内容,则epr_num为True,程序继续执行。我们先看零件号和EPR编号是否都在采购信息里,若是,就在承诺日期列对应的行写入承诺日期,if part_num in promise_date and epr_num in promise_date[part_num]。只要“零件号”和“EPR编号”有一个没在采购信息里,就写入“未采购”,即表示采购尚未下单。收货日期也是采用类似的逻辑。直到查询并写入订单表的最后一行,然后保存,并打开下一个文件进行同样的处理。为便于区分及不影响原始数据,我们将更新后的文件存到了“订单更新”文件夹。

需要注意的是,在运行程序之前,需要将所有Excel文件关闭,不然可能因为文件处于打开状态,无法存储而报错。最后写好的文件如下所示:

大功告成!

所有源代码和说明都在Jupyter notebook上完成,所用到的Excel 资料已上传GitHub, 欢迎Fork或下载到本地随意玩。。。转载请注明出处,谢谢。

GitHub链接:

https://github.com/weidylan/Office_Automation_by_Using_Python

python在采购中应用_实例13:用Python批量查询采购物料交期及实际收货日期相关推荐

  1. python实战扫码下载_实例:用 Python 做一个扫码工具

    原标题:实例:用 Python 做一个扫码工具 来自公众号: 新建文件夹X 链接:https://blog.csdn.net/ZackSock/article/details/108610957Pyt ...

  2. python识别视频中火焰_基于yolov3和python框架的火焰识别检测算法

    本算法识别的效果如下:有兴趣学习交流python 编程的伙伴可加群:1026352781 下面开始实际操作啦 一.配置环境 算法所需环境如下: Python: 3.7.4 Tensorflow-GPU ...

  3. python开发的程序中以电子表格显示数据_使用 Python 读取电子表格中的数据实例详解...

    Python 是最流行.功能最强大的编程语言之一.由于它是自由开源的,因此每个人都可以使用.大多数 Fedora 系统都已安装了该语言.Python 可用于多种任务,其中包括处理逗号分隔值(CSV)数 ...

  4. python包的中 _init _.py文件介绍

    python包的中 _init _.py文件介绍 我们新建python包时常常会看到一个__init _.py文件. 作用介绍: ​ 一:这个文件是属于python包的,这个文件用作于标识python ...

  5. python 算法教程 pdf 英文_上手实践《Python机器学习第2版》PDF中文+PDF英文+代码+Sebastian...

    学习机器学习,推荐学习<Python机器学习(第二版)>. <Python机器学习(第2版)>,图文并茂,代码详实,原理清晰,覆盖面适度,侧重算法实现和应用,作为入门级学习还是 ...

  6. python若干整数的最大值_实例讲解Python中整数的最大值输出

    在Python中可以存储很大的值,如下面的Python示例程序: x = 10000000000000000000000000000000000000000000; x = x + 1 print ( ...

  7. 趣学python教孩子学编程_《趣学Python——教孩子学编程》学习笔记第1-3章

    第1章 Python不是大蟒蛇 1.1 关于计算机语言 计算机程序是一组让计算机执行某种动作的指令.软件就是计算机程序的集合. 一种编程语言就是一种特定的与计算机交谈的方式,这种方式使用计算机和人都能 ...

  8. python阿凡提与国王下棋_实例:阿基米德与国王下棋的故事_【一图胜千言】以图讲解Python序列之语言基础与提升大合集详细讲解(含500条笔记)_Python视频-51CTO学院...

    课程亮点: 一图胜千言,让文科生都能看得懂的python教程!!!另外加详细的笔记作为辅助工具,500多条笔记帮助学员学习Python500多个知识点 课程内容: 1. Python3语言总体介绍以及 ...

  9. python编程入门单例_常见的在Python中实现单例模式的三种方法

    单例模式是一种常用的软件设计模式.在它的核心结构中只包含一个被称为单例类的特殊类.通过单例模式可以保证系统中一个类只有一个实例而且该实例易于外界访问,从而方便对实例个数的控制并节约系统资源.如果希望在 ...

最新文章

  1. Java动态代理与Cglib代理
  2. 项目背景介绍及文件系统基本概念简介
  3. 1085 PAT单位排行 (25 分
  4. 《UNIX编程艺术》--读书笔记
  5. windows本地破解用户口令
  6. can总线程序讲解_汽车can总线工作原理及测量方法详解
  7. ie8css无效,CSS 伪类在IE8中样式无法生效
  8. C++ emplace_back
  9. 将Excel数据转换为XML
  10. 1、关于百兆口、千兆口、万兆口端口和网线的小常识
  11. VMware CentOS6.5 安装VMware Tools
  12. 千岛湖-印象中的天堂游记
  13. POJ3614 [USACO07NOV]防晒霜Sunscreen
  14. Java集合(Collection)习题集锦
  15. 升级AndroidX
  16. 开水果店建议,对开水果店的建议
  17. MTK 平台编译指令集
  18. WinPE 安装 2003
  19. 用一个空置U盘(大白菜)PE重装系统
  20. Python Pandas条件筛选

热门文章

  1. android x86 修改器,烧饼修改器x86专属版
  2. windows10计算机无法启动不了,windows10不能开机怎么办
  3. 【ADRC】扩张状态观测器(ESO)
  4. 爬取京东网站前后一星期的笔记本电脑信息并可视化
  5. 周志明虚拟机最新版,大厂面试必备宝典
  6. 编程5分钟,命名2小时!聊聊命名规则!
  7. 医疗信息化与医院评审
  8. 实现图书增删改查和分页显示图书信息
  9. 制作android动态壁纸,如何使用LibGDx制作Android动态壁纸?
  10. Android: Kotlin 材料设计入门