NX Lab

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

  1. 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 CSV Xuất BOM đầy đủ ra CSV

    Các bước thực hiện

    1. Gom theo part gốc. Đường dẫn đầy đủ làm khóa.
    2. Đọc thuộc tính. Vật liệu và khối lượng đơn.
    3. Tính tổng. Khối lượng đơn nhân số lượng.
    4. Ghi CSV. Cột STT, tên, SL, vật liệu, KL đơn, KL tổng.
    5. 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

    • OrderedDict giữ 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_LIEU cho 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.