|
马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
希望 通过生产计划表和物料清单,自动生成物料需求计划表。
- import pandas as pd
- import xlwings as xw
- file = r"C:\Users\郝\Desktop\ERP.xlsm"
- # 导入xlwings模块,打开Excel程序,默认设置:程序可见,只打开不新建工作薄,屏幕更新关闭
- wb = xw.Book(file)
- wb.app.display_alerts = False
- # 文件位置:filepath,打开test文档,然后保存,关闭,结束程序
- sht_test = wb.sheets['base']
- sht_view = wb.sheets['view']
- RNG1 = sht_test[19, 0].api.currentregion
- RNG2 = sht_test[19, 5].api.currentregion
- # 命名Excel单元格区域名称
- RNG1.name = 'Bom'
- RNG2.name = 'Plan'
- '''
- Plan及Bom资料导入pandas的DataFrame中
- header=1表示单元格区第一行为列标题行
- index=True表示单元格区第一列为索引列,False表示自动索引(从0开始)
- '''
- dfsz5 = sht_test['Plan'].options(pd.DataFrame, header=1, index=True).value
- dfsz6 = sht_test['Bom'].options(pd.DataFrame, header=1, index=True).value
- '''
- 连接Plan和Bom,merge横向(列)连接,类似SQL SERVER数据库连接join,
- left_index=True,right_index=True表示左右两个DataFrame以索引列为基准进行连接
- how='inner'表示内连接
- Bom(bill of material)根据物料清单(递归)计算 MRP 物料需求计划
- 第二阶开始到最尾阶的物料分解,从第一阶分解后取得所需数据
- '''
- def eeBom(df4A,df4,df2,CX1):
- df5=df4[['CID','PCQT','PROCID']]
- df5.rename(columns={'CID': 'PID','PCQT': 'PQT','PROCID': 'PROPID'}, inplace=True)
- df5.reset_index(drop=True, inplace=True)
- df5.set_index('PID', inplace=True)
- df6=pd.merge(df5, df2, left_index=True,right_index=True, how='inner')
- if df6.empty:
- return df4A
- else:
- df6['PCQT'] = df6['PQT']*df6['CQT']
- df6['PROCID'] = df6['PROPID']+'-'+str(CX1+1)
- df6['LEVEL'] = CX1+1
- df4A=df4A.append(df6)
- return eeBom(df4A, df6, df2, CX1+1)
- # 第一阶的物料分解,从Plan取得所需数据
- # 首先调动eBom函数,eBom函数再调用eeBom,但是eeBom要定义在eBom之前,不然会出错,会显示找不到eeBom函数
- def eBom(df1,df2):
- df3=pd.merge(df1, df2, left_index=True, right_index=True, how='inner')
- df3['PCQT'] = df3['PQT']*df3['CQT']
- df3['PROCID'] = df3['PROPID']+'-'+str(1)
- df3['LEVEL'] = 1
- return eeBom(df3, df3, df2, 1)
- # 计算MRP,并按单据号,物料父项编号排序
- dfsz7 = eBom(dfsz5, dfsz6).sort_values(by = ['PROCID', 'PID'])
- # 'FC'列标志物料子项是否为:'F'-尾阶(最终件),'M'-非尾阶(中间件)
- # 全部先标注为'M'
- dfsz7['FC']='M'
- #获取Bom表中所有物料父项编号,取唯一值即可
- list1=list(dfsz6.index.unique())
- # print(list1)
- # 对MRP物料需求计划表中的最终件标识为'F'
- dfsz7.loc[~dfsz7['CID'].isin( list1),['FC']]='F'
- # 就这样完成啦!超简洁,有没有小伙伴们!
- print(dfsz7)
- # 导出到Excel,首先删除A:AA列,把格式也一起删除,用cells.delete或clear无法删除格式
- '''
- sht_view.api.columns('A:AA').delete
- sht_view.api.cells.delete
- sht_view.clear
- '''
- # 在Excel view表'A1'单元格的扩展位置显示dfsz5(即:Plan生产计划表)
- sht_view.range(1,1).expand().value = dfsz5
- # 在Excel view表'E1'单元格的扩展位置显示dfsz6(即:Bom物料清单表)
- sht_view.range(1,5).expand().value = dfsz6
- # 在Excel view表'I1'单元格的扩展位置显示dfsz7(即:MRP物料需求计划表)
- sht_view.range(1,9).expand().value = dfsz7
- # 在Excel view表'第4、8列设置列的颜色,便于在Excel中区分各个计算出来的数据集
- sht_view.cells.columns(4).color=(255,128,255)
- sht_view.cells.columns(8).color=(255,128,255)
- # 列自动调整宽度,如果要指定列宽可用 sht_view.range((1,1),(1,20)).api.ColumnWidth = 8
- # sht_view.api.columns('A:AA').autofit
复制代码 |
|