[DigiKey]複数のBOMファイルをまとめて、うまくbulk discountを活かしつつ一括で発注をかける
DigiKeyでは、BOMファイルから必要な部品をリストアップして自動的にカートに入れてくれる機能がある。
基板によっては100種類くらいの部品を使うこともあるから、この機能はマジで便利。
一つ一つ部品を検索してカートに入れていくとか正気の沙汰じゃねぇからな。
で、こいつはさらにbulk discountの提案も同時に行ってくれる。
これがまた便利で、何も考えなくても注文が安くなるように(しかももっと部品が手に入るように)仕向けてくれる。
ただ、この機能をフルに活用するには、注文する部品が一つのBOMファイルにまとまっている必要がある。
例えば、CRCW0603100KJNEACというチップ抵抗をそれぞれ45個、30個要求するBOMファイルA,Bがあったとし、同時に発注をかけたい場合を考える。
二つのBOMファイルの部品を同時に注文するためには、それぞれのファイルごとにカートに入れる作業をしないといけない。
この時、まずファイルAを処理しようとすると、この抵抗を100個で注文することを勧められる(45個だと144円だが、100個だと132円に下がるため)。
ここでは、まだBで追加するからと提案を無視しておく。
次にファイルBを処理する。特に提案は表示されず、そのまま30個カートに入る。
結果、CRCW0603100KJNEACは75個の注文になっており、これは100個注文するより高くなってしまっている(カートからはbulk discountの画面を表示できない)。
じゃあAを処理するときに提案を受け入れ、抵抗100個をカートに入れたとすると、最終的にカートには130個の注文が入ってしまう。そんなにいらない。
この状態からカート内で部品数を調整するのは困難を極める作業である(必要な部品がそもそも多いのか、それとも余分に入ってしまっているのか、すべて手で計算しなおさなければならない)。
そもそも部品の種類やBOMファイルの数が多いと、「この部品はさっき提案を受けなかったから今回は受け入れて、こっちの部品はこのBOMファイルにしかないから提案を受け入れて...」とかやってられない。
BOMファイルをマージする機能が用意されていたら良かったが、そんなものはない。
ということで、うまいことBOMファイルをマージして、bulk discountを最大限活かせるような注文用BOMファイルをPythonで生成することにした。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | import csv import sys args = sys.argv unique_label = "" quantity_label = "" order_bom = {} ''' Usage: python merge_bom.py [unique_label] [quantity_label] file.csv ... unique_label: CSV label name for ID of a part quantity_label: CSV label name for quantity path to csv: Path to CSV files. You can set multiple CSVs. e.g., python merge_bom.py DistributorPartNumber Quantity file1.bom.scv file2.bom.csv file3.bom.csv ''' if __name__ == '__main__': unique_label = args[1] quantity_label = args[2] # Collect data of items for csv_path in args[3:]: with open(csv_path, encoding='utf-8-sig') as f: print("Scanning " + csv_path + "...") reader = csv.DictReader(f) for row in reader: try: # print(row) # print(row[unique_label]) if row[unique_label] in order_bom: order_bom[row[unique_label]][quantity_label] += int(row[quantity_label]) else: order_bom[row[unique_label]] = row order_bom[row[unique_label]][quantity_label] = int(row[quantity_label]) # str to int except ValueError: print("Invalid fieldnames: " + row) tmp_part_id = list(order_bom.keys())[0] header = order_bom[tmp_part_id].keys() # print("header: " + ','.join(list(header))) # generate bom for ordering print("Generating order.bom.csv...") with open("./order.bom.csv", "w") as f: writer = csv.DictWriter(f, header) writer.writeheader() for row in order_bom.values(): writer.writerow(row) print("Done!") |
Python3.x系で動く。
例えば、以下のようなBOMファイルがあったとする。
1 2 3 | DistributorPartNumber,Quantity CRCW0603100KJNEAC, 45 RESISTOR, 50 |
1 2 3 | DistributorPartNumber,Quantity CRCW0603100KJNEAC, 30 CAPACITOR, 50 |
で、以下のコマンドを叩くと、下のようなcsvファイルが生成される。
1 | $ python3 merge_bom.py DistributorPartNumber Quantity A.bom.csv B.bom.csv |
1 2 3 4 | DistributorPartNumber,Quantity CRCW0603100KJNEAC,75 RESISTOR,50 CAPACITOR,50 |
CSVを一つにまとめたおかげで、CRCW0603100KJNEACは75個の注文になり、BOM Managerは「100個買え」という最適な提案をしてくれるはずである。
この記事へのコメントはこちら