基於Python的ERP系統中能力需求計劃(CRP)的計算

一、目的

1、深入理解、掌握能力需求計劃理論, ERP中MRP、工作中心、工藝路線等相關模塊的關係,以及ERP系統信息集成的含義。
2、綜合運用能力需求計劃理論和程序設計技術,設計適合表示能力需求計劃參數及計劃結果的數據結構,並使用程序設計語言實現。
3、綜合運用能力需求計劃理論和程序設計技術,設計能力需求計劃計算的算法,並使用程序設計語言實現。
4、設計並實現能力需求計劃結果顯示形式。
5、對於給定的能力需求計劃參數實例,制定可行的能力需求計劃。

二、內容

1、設計並實現適合存儲能力需求計劃參數及計算結果的數據結構。
2、設計並實現能力需求計劃計算的算法。
3、設計並實現能力需求計劃結果顯示形式。
4、根據數據文件的說明完成數據文件的解析,讀取計算能力需求計劃的相關參數,根據讀入的參數完成能力需求計劃的計算(具體計算內容包括:已確認和計劃MRP的總負荷、餘/欠能力、累積餘/欠能力),並顯示(如表、圖等,也可以輸出到Excel中)計算結果

三、存儲相關參數的文件及說明

1、MRPConfirmed.txt:已確認的MRP。文件可能包含若干行。每行對應一種物料。每行的格式如下:
物料名稱 時段1需求量 時段2需求量 ... 時段n需求量
例如
X 10 8 6 12 5 8
表示物料X在 時段1到時段6的需求量分別爲10 8 6 12 5 8

2、MRPPredicted.txt:計劃的MRP。文件可能包含若干行。每行對應一種物料。每行的格式如下:
物料名稱 時段1需求量 時段2需求量 ... 時段n需求量
例如
X 0 4 5 3 0 2
表示物料X在 時段1到時段6的需求量分別爲10 8 6 12 5 8

3、Routing.txt:工藝路線文件。文件可能包含若干行。每行對應某種物料的一道工序。每行的格式如下:
物料名稱 工序總數 該工序的執行順序 該工序對應的工作中心 額定能力需求
例如
X 2 1 WC01 3
表示物料X一共有2道工序,第一道工序需要在工作中心WC01加工3個小時

4、WCRatedCapacity.txt:工作中心額定能力。文件可能包含若干行。每行對應一個工作中心。每行的格式如下:
工作中心名 額定能力(工時)
例如
WC01 90
表示工作中心WC01在一個時段內的額定能力爲90小時

四、相關理論知識

1. 能力需求計劃是對物料需求計劃(MRP)所需能力進行覈算的一種計劃管理方法。具體地講,CRP就是對各生產階段和各工作中心所需的各種資源進行精確計算,得出人力負荷、設備負荷等資源負荷情況,並做好生產能力負荷的平衡工作。

2. 能力需求計劃可以解決以下幾個問題:
(1)各個物料經過哪些工作中心加工?
(2)各工作中心的可用能力和負荷是多少?
(3)工作中心的各個時段的可用能力和負荷是多少

3. 考慮能力需求計劃的計算方式時,要把物料需求計劃的物料需求量轉換爲 負荷小時,即把物料需求轉換爲對能力的需求。不但要考慮MRP的計劃訂單,還要結合工作中心和生產日曆,同時還得考慮工作中心的停工及維修情況,最 後確定各工作中心在各時間段的可用能力,計算模型如圖所示。

4. 工作中心加工物品的負荷計算方法下所示:
*負荷=該物品產量X佔用該工作中心的標準工時(或臺時)
*若能力-負荷>=0,則滿足加工要求,能力富餘(或剛好)。
*若能力-負荷<0,則不能滿足加工要求,能力不足。

5. 編制能力需求計劃的步驟分述如下:
(1)收集數據
(2)計算負荷
(3)分析負荷情況
(4)能力/負荷調整
(5)確認能力需求計劃

6. 讀取數據文件的方法:

def ReadMatInfo(filepath):
  with open(filepath,'r') as file:
    data:List[str] = [line.strip() for line in file.readlines()]
    return data

 

五、源代碼

from typing import List
import xlsxwriter

#讀取txt信息函數:
def ReadMatInfo(filepath):
  with open(filepath,'r') as file:
    data:List[str] = [line.strip() for line in file.readlines()]
    return data

#將從文件讀取的物料X的已確定的MRP進行處理換行符
temp_confirmed_mrp_X = ReadMatInfo('./data_files/MRPConfirmed.txt')[0].split(' ',-1)

#讀取物料X的已確定MRP並加入數組
Confirmed_MRP_X = []
for i in range(len(temp_confirmed_mrp_X)-1):
  Confirmed_MRP_X.insert(i,int(temp_confirmed_mrp_X[i+1]))

#將從文件讀取的物料Y的已確定的MRP進行處理換行符
temp_confirmed_mrp_Y = ReadMatInfo('./data_files/MRPConfirmed.txt')[1].split(' ',-1)

#讀取物料Y的已確定MRP並加入數組
Confirmed_MRP_Y = []
for i in range(len(temp_confirmed_mrp_Y)-1):
  Confirmed_MRP_Y.insert(i,int(temp_confirmed_mrp_Y[i+1]))

#將從文件讀取的物料X的預測MRP進行處理換行符
temp_pre_mrp_X = ReadMatInfo('./data_files/MRPPredicted.txt')[0].split(' ',-1)

#讀取物料X的預測MRP
Predicted_MRP_X = []
for i in range(len(temp_pre_mrp_X)-1):
  Predicted_MRP_X.insert(i,int(temp_pre_mrp_X[i+1]))

#將從文件讀取的物料Y的預測MRP進行處理換行符
temp_pre_mrp_Y = ReadMatInfo('./data_files/MRPPredicted.txt')[1].split(' ',-1)

#讀取物料Y的預測MRP
Predicted_MRP_Y = []
for i in range(len(temp_pre_mrp_Y)-1):
  Predicted_MRP_Y.insert(i,int(temp_pre_mrp_Y[i+1]))

#讀取加工車間額定工作能力:

#讀取車間WC01的額定工作能力:
workshop01 = int((ReadMatInfo('./data_files/WCRatedCapacity.txt')[0].split(' ',-1))[1])

#讀取車間WC02的額定工作能力:
workshop02 = int((ReadMatInfo('./data_files/WCRatedCapacity.txt')[1].split(' ',-1))[1])

#讀取文件中工藝路線信息(一共有3條工藝路線)
#讀取第一條工藝路線X1
X1_process_num = int((ReadMatInfo('./data_files/Routing.txt')[0].split(' ',-1))[1])
X1_process_order = int((ReadMatInfo('./data_files/Routing.txt')[0].split(' ',-1))[2])
X1_workshop = (ReadMatInfo('./data_files/Routing.txt')[0].split(' ',-1))[3]
X1_precess_time = int((ReadMatInfo('./data_files/Routing.txt')[0].split(' ',-1))[4])
#讀取第二條工藝路線X2
X2_process_num = int((ReadMatInfo('./data_files/Routing.txt')[1].split(' ',-1))[1])
X2_process_order = int((ReadMatInfo('./data_files/Routing.txt')[1].split(' ',-1))[2])
X2_workshop = (ReadMatInfo('./data_files/Routing.txt')[1].split(' ',-1))[3]
X2_precess_time = int((ReadMatInfo('./data_files/Routing.txt')[1].split(' ',-1))[4])
#讀取第三條工藝路線Y
Y_process_num = int((ReadMatInfo('./data_files/Routing.txt')[2].split(' ',-1))[1])
Y_process_order = int((ReadMatInfo('./data_files/Routing.txt')[2].split(' ',-1))[2])
Y_workshop = (ReadMatInfo('./data_files/Routing.txt')[2].split(' ',-1))[3]
Y_precess_time = int((ReadMatInfo('./data_files/Routing.txt')[2].split(' ',-1))[4])

#計算過去需求負荷
#計算WC01的過去需求負載
past_demand_load1 = []
for i in range(len(Confirmed_MRP_X)):
  past_demand_load1.insert(i,Confirmed_MRP_X[i] * X1_precess_time + Confirmed_MRP_Y[i] * Y_precess_time)

#計算WC02的過去需求負載
past_demand_load2 = []
for i in range(len(Confirmed_MRP_X)):
  past_demand_load2.insert(i,Confirmed_MRP_X[i] * X2_precess_time)

#計算計劃需求負荷
#計算WC01的計劃需求負荷
plan_demand_load1 = []
for i in range(len(Confirmed_MRP_X)):
  plan_demand_load1.insert(i,Predicted_MRP_X[i] * X1_precess_time + Predicted_MRP_Y[i] * Y_precess_time)

#計算WC02的計劃需求負荷
plan_demand_load2 = []
for i in range(len(Confirmed_MRP_X)):
  past_demand_load2.insert(i,Predicted_MRP_X[i] * X2_precess_time)

#計算總負荷
#計算WC01的總負荷
total_load1 = []
for i in range(len(Confirmed_MRP_X)):
  total_load1.insert(i,past_demand_load1[i] + plan_demand_load1[i])

#計算WC02的總負荷
total_load2 = []
for i in range(len(Confirmed_MRP_X)):
  total_load2.insert(i,past_demand_load2[i] + plan_demand_load2[i])

#計算平均能力
#計算WC01的平均能力
average_process_time1 = []
for i in range(len(Confirmed_MRP_X)):
  average_process_time1.insert(i,workshop01)
#計算WC02的平均能力
average_process_time2 = []
for i in range(len(Confirmed_MRP_X)):
  average_process_time2.insert(i,workshop02)

#計算餘/欠能力
#計算WC01的餘/欠能力
surplus_capacity1 = []
for i in range(len(Confirmed_MRP_X)):
  surplus_capacity1.insert(i,total_load1[i] - average_process_time1[i])

#計算WC02的餘/欠能力
surplus_capacity2 = []
for i in range(len(Confirmed_MRP_X)):
  surplus_capacity2.insert(i,total_load2[i] - average_process_time2[i])

#計算累計能力
#計算WC01的累計能力
acc_capacity1 = []
acc_capacity1.insert(0,surplus_capacity1[0])
for i in range(1,len(Confirmed_MRP_X)):
  acc_capacity1.insert(i,surplus_capacity1[i] + surplus_capacity1[i-1])
#計算WC02的累計能力
acc_capacity2 = []
acc_capacity2.insert(0,surplus_capacity2[0])
for i in range(1,len(Confirmed_MRP_X)):
  acc_capacity2.insert(i,surplus_capacity2[i] + surplus_capacity2[i-1])


#將數據寫入到Excel並創建表格
#創建Excel文檔
print("正在進行Excel錄入中:")
wb = xlsxwriter.Workbook("/Users/jayphone/Desktop/calculation_of_CRP.xlsx")
#創建WC01計算結果的表單
ws1 = wb.add_worksheet(name="caculation_of_WC01")
calculation_item = ['過去需求量','計劃需求量','總負荷量','平均能力','餘/欠能力','累計能力']
headline = ['週數','1','2','3','4','5','6']
#將數據插入到表格中:
ws1.write_row('A1',headline)
ws1.write_column('A2',calculation_item)
ws1.write_row('B2',past_demand_load1)
ws1.write_row('B3',plan_demand_load1)
ws1.write_row("B4",total_load1)
ws1.write_row('B5',average_process_time1)
ws1.write_row('B6',surplus_capacity1)
ws1.write_row('B7',acc_capacity1)

#創建WC02計算結果的表單
ws2 = wb.add_worksheet(name="caculation_of_WC02")
calculation_item = ['過去需求量','計劃需求量','總負荷量','平均能力','餘/欠能力','累計能力']
headline = ['週數','1','2','3','4','5','6']
#將數據插入到表格中:
ws2.write_row('A1',headline)
ws2.write_column('A2',calculation_item)
ws2.write_row('B2',past_demand_load2)
ws2.write_row('B3',plan_demand_load2)
ws2.write_row("B4",total_load2)
ws2.write_row('B5',average_process_time2)
ws2.write_row('B6',surplus_capacity2)
ws2.write_row('B7',acc_capacity2)

print("Excel錄入完畢!!")
wb.close()

#在控制檯簡單輸出:
print("WC01結果:")
print("過去需求量是:")
print(past_demand_load1)
print("計劃需求量是:")
print(plan_demand_load1)
print("總負荷是:")
print(total_load1)
print("平均能力是:")
print(average_process_time1)
print("餘/欠能力是:")
print(surplus_capacity1)
print("累計能力是:")
print(acc_capacity1)

print("WC02結果:")
print("過去需求量是:")
print(past_demand_load2)
print("計劃需求量是:")
print(plan_demand_load2)
print("總負荷是:")
print(total_load2)
print("平均能力是:")
print(average_process_time2)
print("餘/欠能力是:")
print(surplus_capacity2)
print("累計能力是:")
print(acc_capacity2)

 

六、結果

1.在PyCharm控制檯輸出

2.WC01計算結果輸出Excel

3.WC02計算結果輸出Excel

七、所使用的數據文件

鏈接:https://pan.baidu.com/s/1YyhGcHkreHXq_ePR0R67Ew  密碼:byw2

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章