NX 도면 출도 전 자동검사|품번·재질·작성자·축척 누락 확인 Journal
NX Drafting에서 도면 출도 직전에 품번·재질·작성자·축척을 다시 확인하는 이유는 단순합니다. 모델 형상이 완성되어도 표제란의 관리 정보가 빠지거나 시트 축척이 잘못되면 협력사 전달·검사·BOM 대조 단계에서 작업이 멈출 수 있기 때문입니다.

이번 실습에서는 회사별로 다른 속성 이름을 구분하고, Part 사용자 속성 3개와 도면 시트 축척·뷰를 읽기 전용으로 점검하는 방법을 정리했습니다. 예시 입력을 바꿔보는 웹 검사기도 본문에 넣었습니다. 실제 NX에서 실행한 완성 검사기나 자동 출도 승인 도구는 아닙니다.
1. NX 도면 속성 검사기가 찾을 것과 찾지 못하는 것
사내 도면 표준은 회사마다 다릅니다. 아래 표의 속성명과 누락 조건은 학습을 위한 가상 사내 표준이며 Siemens NX의 공통 기본 규칙은 아닙니다.
| 검사 대상 | 예제 속성 이름 | 누락 판정 | 자동화의 한계 |
|---|---|---|---|
| 품번 | PART_NUMBER / DB_PART_NO | 공백 또는 없음 | 표제란의 품번 표시는 별도 확인 |
| 재질 | MATERIAL / MAT_SPEC | 공백 또는 없음 | 물리 Material 지정 여부와는 별개 |
| 작성자 | DRAWN_BY / DRAFTER | 공백 또는 없음 | 서명·검토·승인은 검사하지 않음 |
| 시트 축척 | DrawingSheet.GetScale() | 0, 음수, API 읽기 실패 | 개별 View 축척과 구분 |
| 뷰 존재 | GetDraftingViews() | 도면 시트에 뷰 0개 | 모델 갱신 상태·PMI는 별도 검토 |
중요한 구분이 하나 있습니다.

Part 사용자 속성의 MATERIAL에 값이 있다고 해서 물리 재질이 정확히 지정되었다고 증명되는 것은 아닙니다. 도면 표제란 역시 자유 텍스트나 다른 속성을 참조할 수 있어 Part 속성 확인과 표제란 육안 검증은 별도 단계로 두어야 합니다.
2. 품번·재질·작성자·축척 누락 검사기 체험
아래는 NX를 직접 실행하는 프로그램이 아닌 브라우저에서 동작하는 규칙 검증 시뮬레이터입니다.
품번, 재질, 작성자, 도면 축척과 뷰 수를 변경하고 결과를 확인할 수 있습니다. 데이터를 서버로 전송하지 않으며 실제 NX PRT를 읽지는 않습니다.
각 항목을 직접 바꾸거나 아래 예제를 선택하세요. 사용자의 PRT 파일을 읽지 않습니다.
| 검사 | 입력값 | 판정 |
|---|---|---|
| 품번 | BRK-101 | 입력됨 |
이 결과는 회사 표준의 속성 연결·실제 형상·표제란·승인 상태를 확인하지 않습니다.
3. 정상·오류 샘플과 검사 결과
아래 데이터는 실제 NX에서 추출한 로그가 아니라 독립 테스트 객체로 만든 가상 사례입니다. 브라우저 검사기와 Python 검증 규칙이 같은 항목을 점검하도록 구성했습니다.
| 가상 파일 | 품번 / 재질 / 작성자 | 시트·뷰 | 예상 결과 |
|---|---|---|---|
| BRK-101 | 정상 / 정상 / 정상 | 1:2, 1개 | ATTRIBUTE_CHECK_OK |
| BRK-102 | 정상 / 누락 / 정상 | 1:2, 1개 | MATERIAL_MISSING |
| BRK-103 | 정상 / 정상 / 누락 | 0:0, 0개 | DRAFTER_MISSING · INVALID_SHEET_SCALE · NO_DRAFTING_VIEW |
| BRK-104 | 정상 / 정상 / 정상 | 도면 시트 없음 | NO_DRAWING_SHEET |
오류가 발생하면 빈 값을 0으로 바꿔서 정상으로 만들지 않습니다. NX Open API 호출 자체가 실패한 경우에는 API_ERROR로 구분해야 속성 누락과 프로그램 인터페이스 문제를 혼동하지 않습니다.
4. NX Open Python Journal 읽기 전용 검사 코드
다음 코드는 NX Open에서 문서화된 GetUserAttributes(), DrawingSheets, GetScale(), GetDraftingViews()를 바탕으로 작성했습니다.
NX 2506의 사용자 속성 조회 사례와 NX Open 참조 문서를 참고했으며, 실제 NX 프로그램에서 실행 검증한 버전은 아닙니다. NX 빌드·라이선스·Python 래퍼 반환값을 확인한 뒤 시험용 PRT에서 사용하세요.
검사기는 현재 Work Part만 조회하고, Part 속성은 사용자가 실제 운용하는 제목으로 매핑해야 합니다.
출력은 NX Listing Window에 표시하며 모델 저장·속성 수정·도면 업데이트·출도 승인 명령은 사용하지 않습니다.
# -*- coding: utf-8 -*-
"""NXOpen 2506 reference-oriented READ-ONLY audit prototype.
NOT validated in an actual Siemens NX runtime.
The pure validator is independently tested with fake objects below.
This code NEVER saves, updates, changes attributes or approves a drawing.
"""
import csv
import io
import math
# Sample company mapping ONLY: adapt to your PRT/Teamcenter attributes.
ATTRIBUTE_ALIASES = {
'part_number': ('PART_NUMBER', 'DB_PART_NO'),
'material': ('MATERIAL', 'MAT_SPEC'),
'drafter': ('DRAWN_BY', 'DRAFTER'),
}
def attribute_map(obj):
result = {}
for item in obj.GetUserAttributes():
key = str(item.Title).strip().upper()
try:
val = str(item.StringValue).strip()
except Exception:
val = ''
if not val:
try:
val = str(item.RealValue).strip()
except Exception:
pass
if key and val:
result[key] = val
return result
def first_value(attributes, candidates):
return next((attributes.get(x.upper(), '') for x in candidates
if attributes.get(x.upper(), '').strip()), '')
def inspect_part(part):
"""Returns rows and issues; safe from all NX write calls."""
attributes = attribute_map(part)
part_name = str(getattr(part, 'Name', '(unnamed)'))
values = {k: first_value(attributes, a)
for k, a in ATTRIBUTE_ALIASES.items()}
base_issues = [k.upper() + '_MISSING' for k, v in values.items() if not v]
rows = []
try:
sheets = list(part.DrawingSheets.ToArray())
except Exception as exc:
return [{**values, 'part': part_name, 'sheet': '-', 'scale': '-',
'view_count': '-', 'status': 'API_ERROR',
'issues': 'DRAWING_SHEETS_READ_FAILED: ' + type(exc).__name__}]
if not sheets:
return [{**values, 'part': part_name, 'sheet': '-', 'scale': '-',
'view_count': 0, 'status': 'REVIEW',
'issues': ';'.join(base_issues + ['NO_DRAWING_SHEET'])}]
for sheet in sheets:
issues = list(base_issues)
name = str(getattr(sheet, 'Name', '(unnamed)'))
scale, view_count = '-', '-'
try:
ratio = sheet.GetScale() # Python binding: tuple of out parameters
if not isinstance(ratio, (tuple, list)) or len(ratio) != 2:
raise ValueError('unexpected scale result')
n, d = float(ratio[0]), float(ratio[1])
if not (math.isfinite(n) and math.isfinite(d) and n > 0 and d > 0):
issues.append('INVALID_SHEET_SCALE')
else:
scale = f'{n:g}:{d:g}'
except Exception as exc:
issues.append('SCALE_API_ERROR:' + type(exc).__name__)
try:
view_count = len(sheet.GetDraftingViews())
if view_count == 0:
issues.append('NO_DRAFTING_VIEW')
except Exception as exc:
issues.append('VIEW_API_ERROR:' + type(exc).__name__)
rows.append({**values, 'part': part_name, 'sheet': name,
'scale': scale, 'view_count': view_count,
'status': 'REVIEW' if issues else 'ATTRIBUTE_CHECK_OK',
'issues': ';'.join(issues) or '-'})
return rows
def csv_text(rows):
columns = ['part','sheet','part_number','material','drafter','scale',
'view_count','status','issues']
out = io.StringIO()
writer = csv.DictWriter(out, fieldnames=columns, lineterminator='\n')
writer.writeheader()
for row in rows:
safe = {k: str(row.get(k, '')) for k in columns}
# When opening the listing as a spreadsheet, avoid CSV formula injection.
for k, value in safe.items():
if value.lstrip().startswith(('=', '+', '-', '@')) and value != '-':
safe[k] = "'" + value
writer.writerow(safe)
return out.getvalue()
def main():
import NXOpen
session = NXOpen.Session.GetSession()
listing = session.ListingWindow
listing.Open()
part = session.Parts.Work
if part is None:
listing.WriteLine('NO_WORK_PART: open a drawing part first')
return
try:
rows = inspect_part(part)
for line in csv_text(rows).splitlines():
listing.WriteLine(line[:128])
listing.WriteLine('READ-ONLY: result is NOT approval to release drawing.')
except Exception as exc:
listing.WriteLine('AUDIT_FAILED: ' + type(exc).__name__ + ': ' + str(exc)[:80])
if __name__ == '__main__':
main()
실행 전 확인할 조건
- 회사 PRT의 속성 제목을 먼저 조사하고
ATTRIBUTE_ALIASES에 실제 값을 등록합니다. - NX에 Python Journal 실행 기능과 필요한 Drafting 라이선스가 제공되는지 확인합니다.
- 복제한 비기밀 PRT에서만 시험하고 처음에는 저장하지 않은 원본을 별도 백업합니다.
- 결과 창의
ATTRIBUTE_CHECK_OK는 사용자 속성과 시트 구조의 예비 검사 통과일 뿐, 최종 출도 승인 표시가 아닙니다.
5. 검사 이후 실제 출도 전 검증 절차
| 확인 단계 | 자동/수동 | 검토 기준 |
|---|---|---|
| 품번·재질·작성자 | 일부 자동 | Part 속성 값과 도면 표제란 표시 일치 |
| 시트 축척·뷰 유무 | 일부 자동 | 시트 축척과 개별 View 축척 별도 확인 |
| 도면 투영·치수·공차 | 수동 검토 | 모델 형상·PMI·치수 누락 여부 |
| 도면 개정·BOM | 수동·PLM 검토 | 품번·수량·개정번호·적용 시점 |
| PDF 최종 출력 | 수동 검토 | 도면 크기·문자 깨짐·투상·선굵기 |
| 승인/출도 | 회사 승인 절차 | 검토자 서명·결재·PDM 릴리스 상태 |
NX Drafting에서 시트·투영뷰·치수의 작성 흐름이 필요하면 UG NX 도면 작성 가이드를 참고하면 됩니다. 품번·재질·작성자 표제란을 자주 누락한다면 도면 템플릿·PAX 등록을 함께 점검하는 편이 효율적입니다.
또한 도면 표제란의 품번이 정상이어도 실제 조립품 BOM과 일치한다고 단정할 수 없습니다. NX BOM 파트리스트 작성과 개정 관리 정보를 별도로 대조해야 합니다.
NX 도면 출도 전 자동검사 FAQ
품번이 표시되어 있는데 검사 결과는 누락이라고 나옵니다.
Part 사용자 속성과 표제란이 참조하는 값이 다를 수 있습니다. 표제란이 자유 텍스트이거나 Teamcenter 속성인 경우 실제 매핑을 확인해야 합니다.
MATERIAL 값이 있으면 재질 검증이 끝난 건가요?
아닙니다. 문자열 속성에 값이 있는지 확인할 뿐이며 물리 재질 지정, 규격 적합성, 실제 질량은 별도 검증합니다.
시트 축척이 1:2면 모든 뷰도 1:2인가요?
그렇지 않습니다. 도면 시트와 개별 Drafting View는 서로 다른 축척을 사용할 수 있으므로 뷰별 표시도 확인해야 합니다.
검사기가 도면 속성을 자동으로 수정하나요?
하지 않습니다. 이 예제는 읽기 전용이며 모델 저장·수정·자동 승인 기능이 없습니다.
Teamcenter의 DB_PART_NO도 항상 조회할 수 있나요?
환경에 따라 해당 속성이 Work Part에 노출되거나 다른 속성명·공급 경로를 사용할 수 있습니다. 조직에서 사용하는 매핑과 권한을 확인해야 합니다.
Journal 실행 시 GetScale 오류가 나오면 축척 누락인가요?
아닙니다. API 반환 형식이나 호출 방식이 NX 버전마다 다를 수 있으므로 SCALE_API_ERROR와 값 자체의 오류를 구분해 확인해야 합니다.
검사 결과가 모두 정상이면 바로 출도해도 되나요?
안 됩니다. 치수·공차·뷰 갱신·PDF 출력·개정·승인 상태는 별도 검토해야 합니다.
검수 완료 기준: 자동 점검 결과를 확인하고 도면 표제란·뷰 축척·PDF·BOM·승인 정보를 검토자가 최종 대조해야 합니다. 이 글의 샘플과 결과는 교육용이며 특정 고객사의 출도 승인을 대체하지 않습니다.
참고한 API 근거: Siemens Getting Started with NX Open (2017) · NX Open DrawingSheet API (SC2306) · NX 2506 Python GetUserAttributes 사용 예(외부 개발자). 확인일: 2026-10-23.