
Xuất BOM đầy đủ ra CSV: tên, số lượng, vật liệu, khối lượng đơn và khối lượng tổng
#Python#BOM#CSV1 lượt xem
Quản trị viênQuản trị· 0 điểm
Câu hỏi ·
Đây là bản BOM hoàn chỉnh hơn: gom theo part, đếm số lượng, đọc vật liệu và khối lượng từ thuộc tính, rồi tính khối lượng tổng và ghi CSV mở được bằng Excel.
Xuất BOM đầy đủ ra CSVCác bước thực hiện
- Gom theo part gốc. Đường dẫn đầy đủ làm khóa.
- Đọc thuộc tính. Vật liệu và khối lượng đơn.
- Tính tổng. Khối lượng đơn nhân số lượng.
- Ghi CSV. Cột STT, tên, SL, vật liệu, KL đơn, KL tổng.
- Tổng kết. Tổng khối lượng cả assembly.
Code tham khảo (Python)
import csv import os from collections import OrderedDict import NXOpen def duyet_la(root): ngan_xep = list(root.GetChildren()) while ngan_xep: c = ngan_xep.pop() con = c.GetChildren() if con: ngan_xep.extend(con) else: yield c def doc_attr(p, ten): for a in p.GetUserAttributes(): if a.Title.upper() == ten: try: return a.StringValue except Exception: return str(a.RealValue) return "" def lap_bom(root): bom = OrderedDict() for c in duyet_la(root): p = c.Prototype if p is None: continue khoa = p.FullPath if khoa not in bom: kl = doc_attr(p, "KHOI_LUONG") try: kl = float(kl) except ValueError: kl = 0.0 bom[khoa] = {"ten": p.Leaf, "sl": 0, "vat_lieu": doc_attr(p, "VAT_LIEU"), "kl": kl} bom[khoa]["sl"] += 1 return bom def main(): session = NXOpen.Session.GetSession() lw = session.ListingWindow lw.Open() part = session.Parts.Display root = part.ComponentAssembly.RootComponent if part else None if root is None: lw.WriteLine("Không phải assembly") return bom = lap_bom(root) os.makedirs("D:/NXLab_xuat", exist_ok=True) duong_dan = "D:/NXLab_xuat/BOM_%s.csv" % part.Leaf tong = 0.0 with open(duong_dan, "w", newline="", encoding="utf-8-sig") as f: w = csv.writer(f) w.writerow(["STT", "Ten", "SL", "Vat_lieu", "KL_don_kg", "KL_tong_kg"]) for i, d in enumerate(sorted(bom.values(), key=lambda x: x["ten"].lower()), 1): kl_tong = d["kl"] * d["sl"] tong += kl_tong w.writerow([i, d["ten"], d["sl"], d["vat_lieu"], "%.4f" % d["kl"], "%.4f" % kl_tong]) lw.WriteLine("Đã ghi BOM: %s (%d dòng, tổng %.3f kg)" % (duong_dan, len(bom), tong)) if __name__ == "__main__": main()Giải thích code
OrderedDictgiữ thứ tự gặp để thuận cho việc kiểm tra, rồi sắp xếp theo tên khi ghi.- Khối lượng lấy từ thuộc tính
KHOI_LUONG; nếu chưa có, coi là 0 (có thể thay bằng tính từ MeasureManager). - Số lượng tính theo số lần xuất hiện trong cây, không cộng dồn với quantity khai báo.
Lỗi thường gặp
- Tên thuộc tính trong công ty có thể khác; chỉnh
KHOI_LUONG,VAT_LIEUcho khớp. - Nếu file CSV đang mở trong Excel, ghi sẽ lỗi
PermissionError; thông báo người dùng đóng file.
Code mang tính tham khảo, viết cho NX 12 trở lên (Python journal). Tên menu và một số lớp có thể khác theo phiên bản NX; hãy chạy thử trên bản sao của chi tiết trước khi dùng cho dữ liệu thật.
Điểm: 0
Trả lời
Đăng nhập để tham gia thảo luận.