모델 정리 도구
일람표 이름 정리
지정한 도면에 붙어 있는 표를 찾아, 여러 파일에서 표 이름을 하나로 맞춥니다
왜 필요한가
다른 파일에서 표를 복사해 오면, 그 파일에 같은 이름의 표가 이미 있을 때 Revit이 이름 뒤에 숫자를 자동으로 붙입니다.
ROOM FINISH SCHEDULE → ROOM FINISH SCHEDULE1
ROOM FINISH SCHEDULE 2
표 이름은 도면에 인쇄되는 표 제목입니다. 그래서 이름 끝의 숫자가 도면에 그대로 찍힙니다. 이름을 되돌리려면 그 이름을 쓰고 있는 옛날 표를 먼저 지워야 하는데, 파일이 열 개 스무 개면 손으로 하기 어렵습니다.
🖱 쓰는 법
- YoonDream 탭 → Admin 패널 → 모델 정리 → 일람표 이름 정리 버튼 클릭
- 대상 도면 번호 입력 (예:
24-451) — 이 도면 위에 놓인 표가 대상입니다 - 최종 표 이름 입력 (예:
ROOM FINISH SCHEDULE) - 파일 담기 — 폴더 추가 · 파일 추가 · 열린 문서 세 가지 방법
- 이름 정리 실행 클릭 → 확인 창에서 한 번 더 확인
- 결과 창에서 파일별로 무엇을 바꿨고 무엇을 건너뛰었는지 확인
📋 입력하는 값 세 가지
| 입력 | 예시 | 뜻 |
|---|---|---|
| 대상 도면 번호 | 24-451 |
이 번호의 도면에 붙어 있는 표가 대상입니다. 도면 번호가 파일마다 다르면 쉼표로 여러 개 넣습니다 |
| 최종 표 이름 | ROOM FINISH SCHEDULE |
이 이름으로 바꿉니다. 도면에 인쇄되는 제목이 바로 이 이름입니다 |
| 이름 힌트 | ROOM FINISH |
그 도면에 표가 두 개 이상일 때만 씁니다. 이 글자가 들어간 표 하나만 고릅니다 |
표 이름으로 찾지 않고 도면 번호로 찾습니다
이름이 …SCHEDULE1인 것도 있고 … 2인 것도 있고, 아예 다른 이름인 것도 있어서
이름으로는 찾을 수가 없습니다. 반면 "24-451 도면에 붙어 있다"는 사실은
이름이 아무리 망가져 있어도 그대로입니다. 그래서 위치로 찾습니다.
🛡 지우기 전에 확인하는 것
이 도구는 표를 지웁니다. 그래서 지우기 전에 아래를 확인하고, 하나라도 걸리면 그 파일은 손대지 않고 건너뜁니다. 건너뛴 이유는 결과 창에 전부 적힙니다.
| 확인 항목 | 걸리면 |
|---|---|
| 같은 이름의 표가 다른 도면에 붙어 있는가 | 건너뜀 — 지우면 그 도면의 표가 사라집니다 |
| 같은 이름의 표가 키 일람표인가 | 건너뜀 — 키 일람표는 표가 아니라 값을 담아두는 곳입니다 |
| 닫혀 있는 워크셋이 있는가 | 건너뜀 — 닫힌 워크셋 안의 도면은 안 보여서, 붙어 있는 표가 안 붙어 있는 것처럼 보입니다 |
| 그 도면에 표가 여러 개인데 하나로 좁혀지지 않는가 | 건너뜀 — 잘못 고르면 엉뚱한 표 이름이 바뀝니다 |
| 대상 표를 다른 사람이 편집 중인가 | 건너뜀 — 누가 잡고 있는지 이름이 표시됩니다 |
| 대상 표 이름이 이미 맞는가 | 아무것도 하지 않음 |
강제로 지우는 기능은 없습니다
"그래도 지우기" 같은 선택지를 일부러 넣지 않았습니다. 선택지가 있으면 언제고 한 번은 눌리게 되고, 그때 도면이 사라집니다.
💡 이럴 때 쓰세요
- 표 제목에 숫자가 붙은 채로 도면이 나가는 것을 열 개 스무 개 파일에서 한 번에 잡을 때
- 여러 동에서 같은 표 이름을 하나로 통일해야 할 때
- 표를 복사해 넣은 뒤 이름이 어긋난 파일이 어디인지 모를 때 — 결과 창이 파일별로 알려줍니다
안전 처리
- 중앙파일은 직접 열지 않습니다. 로컬 복사본을 만들어 고친 뒤 동기화합니다
- 이미 열어 둔 파일은 바꾸기만 하고 저장하지 않습니다. 직접 저장하시면 됩니다
- 바뀐 것이 없으면 동기화하지 않습니다
- 지우기와 이름 바꾸기는 한 묶음입니다. 이름 바꾸기가 실패하면 지운 것도 되돌아갑니다
- 작업이 끝나면 잡고 있던 편집 권한을 반납합니다
처음에는 사본 하나로
모델을 실제로 고치는 도구입니다. 여러 파일에 돌리기 전에 사본 폴더의 파일 하나로 먼저 확인해 보세요.
🔍 UI 미리보기
결과 창에서 보는 것
파일마다 한 줄씩, 아래 내용이 표로 나옵니다.
| 칸 | 내용 |
|---|---|
| 상태 | 변경됨 · 이미 정상 · 건너뜀 · 실패 |
| 도면 | 대상 도면 번호 |
| 이전 이름 / 새 이름 | 무엇이 무엇으로 바뀌었는지 |
| 지운 표 | 이름을 넘겨받기 위해 지운 표가 있으면 표시 |
| 저장 | 저장됨 · 직접 저장 필요 · 변경 없음 |
| 비고 | 건너뛴 이유, 실패했다면 Revit이 알려준 이유 그대로 |
건너뛰거나 실패한 파일은 아래에 "확인이 필요한 파일" 로 다시 모아서 보여줍니다.
🔧 개발자 정보 (API · 경로 · 내부 로직)
파일 위치
Admin.panel/modelcleanup.pulldown/schedulenamefixer.pushbutton/script.py— Revit 조회 · 수정 · UIlib/snf_core.py— 순수 판정 로직 (Revit 비의존, CPython 단위테스트 42건)ui.xaml
- 설계·리뷰 기록:
dev/active/schedule-name-fixer/ - 함정 노트:
ERROR/schedule_name_fixer_notes.md(18개 항목)
대상 특정 — 이름이 아니라 위치로
inst.OwnerViewId # 일람표가 놓인 시트의 Id
inst.ScheduleId # 그 인스턴스가 표시하는 ViewSchedule 의 Id
FilteredElementCollector(doc).OfClass(ScheduleSheetInstance) 전수 순회 →
OwnerViewId 의 SheetNumber 로 색인. 제외 조건:
IsTitleblockRevisionSchedule == True— 타이틀블럭 리비전 표ViewSchedule.IsTemplate— 뷰 템플릿- 분할(segment) 일람표는 한 시트에 인스턴스가 여러 개 →
ScheduleId로 dedupe
삭제 방어 2중
| 관문 | 함수 | 막는 것 |
|---|---|---|
| 1 | core.dup_placement(placed, id) |
시트 인스턴스가 있으면 번호를 못 읽었어도 배치된 것으로 본다. 키 존재 여부가 신호이고, 번호 유효성으로 대체하면 미배치로 둔갑한다 |
| 2 | core.delete_block_reason(is_key, closed_ws) |
키 스케줄(Definition.IsKeySchedule) + 닫힌 워크셋. OpenAllWorksets 는 우리가 직접 연 파일에만 걸리므로, 이미 열린 문서는 배치된 표가 미배치로 보인다 |
삭제 후보는 정확히 같은 이름만. 대소문자만 다른 것은 지우지 않고 리포트에만 노출한다.
트랜잭션
tg = TransactionGroup(doc, "일람표 이름 정리"); tg.Start()
try:
_run_txn(doc, "동명 일람표 삭제", lambda: doc.Delete(dup_id))
_run_txn(doc, "일람표 이름 변경", lambda: _set_name(sched, target))
tg.Assimilate() # 전부 성공했을 때만
except Exception:
tg.RollBack() # 롤백 실패 시 사유를 비고에 노출
_run_txn 은 commit_or_raise 로 커밋 상태를 검증 — 점유된 요소는 Delete/Set
자체는 통과하고 Commit 에서 조용히 롤백되므로 검증이 없으면 거짓 성공이 된다.
워크셰어링 (lib/yoon_workshare.py)
| 함수 | 역할 |
|---|---|
open_for_edit |
이미 열림 판정 → 중앙이면 CreateNewLocal → 열기. (doc, we_opened, opened_path) |
save_or_sync |
SynchronizeWithCentral 또는 Save. (ok, 실패사유원문) |
release_and_close |
점유 반납 후 닫기 (우리가 연 것만) |
edit_block_reason |
편집 전 차단 판정 (아래 2종) |
make_edit_open_options |
detach 금지 + OpenAllWorksets |
edit_block_reason() 사전 차단 2종:
doc.IsLinked— 다른 문서에 링크로 로드됨. Transaction 불가, 닫으면 호스트 링크가 풀림- 워크셰어링인데 연 경로 == 원본 경로 — 로컬을 직접 열었거나 중앙을 직접 열었음. 그대로 Sync 하면 그 로컬의 미동기화 작업까지 발행된다
SuppressDialogsAndFailures 는 열기 + 편집 구간만 감싼다 —
ResolveFailure() 가 Sync 중 살아 있으면 링크 이름 충돌을 삭제로 해결할 수 있다.
단위 테스트
cd YoonDream.extension/YoonDream.tab/Admin.panel/modelcleanup.pulldown/schedulenamefixer.pushbutton
PYTHONIOENCODING=utf-8 python ../../../../../dev/active/schedule-name-fixer/test_snf_core.py lib