diff --git a/DwgExtractorManual.csproj b/DwgExtractorManual.csproj
index b4fa5d0..c694940 100644
--- a/DwgExtractorManual.csproj
+++ b/DwgExtractorManual.csproj
@@ -54,30 +54,21 @@
-
-
+
+
-
+
-
+
-
+
-
+
-
+
@@ -87,18 +78,10 @@
-
+
-
+
diff --git a/MainWindow.xaml b/MainWindow.xaml
index 5e1ebba..9708447 100644
--- a/MainWindow.xaml
+++ b/MainWindow.xaml
@@ -1,7 +1,7 @@
@@ -12,6 +12,7 @@
+
@@ -89,6 +90,7 @@
+
@@ -171,11 +173,32 @@
+
+
+
+
+
-
-
+
diff --git a/MainWindow.xaml.cs b/MainWindow.xaml.cs
index 2fc80dc..405f86a 100644
--- a/MainWindow.xaml.cs
+++ b/MainWindow.xaml.cs
@@ -1651,6 +1651,88 @@ namespace DwgExtractorManual
}
}
+ ///
+ /// DWG 전용 폴더별 추출 버튼 클릭 이벤트
+ ///
+ private async void BtnDwgOnly_Click(object sender, RoutedEventArgs e)
+ {
+ try
+ {
+ // 경로 검증
+ string sourceFolder = txtSourceFolder.Text;
+ string resultFolder = txtResultFolder.Text;
+
+ if (string.IsNullOrWhiteSpace(sourceFolder) || !Directory.Exists(sourceFolder))
+ {
+ ShowMessageBox("올바른 소스 폴더를 선택해주세요.", "경로 오류", MessageBoxButton.OK, MessageBoxImage.Warning);
+ return;
+ }
+
+ if (string.IsNullOrWhiteSpace(resultFolder) || !Directory.Exists(resultFolder))
+ {
+ ShowMessageBox("올바른 결과 저장 폴더를 선택해주세요.", "경로 오류", MessageBoxButton.OK, MessageBoxImage.Warning);
+ return;
+ }
+
+ // 리프 폴더 찾기
+ var leafFolders = FindLeafFolders(sourceFolder);
+ if (leafFolders.Count == 0)
+ {
+ ShowMessageBox("처리할 리프 폴더가 없습니다.", "정보", MessageBoxButton.OK, MessageBoxImage.Information);
+ return;
+ }
+
+ LogMessage($"🔍 발견된 리프 폴더: {leafFolders.Count}개");
+ foreach (var folder in leafFolders)
+ {
+ LogMessage($" - {folder}");
+ }
+
+ // 사용자 확인
+ var result = ShowConfirmationDialog(
+ $"총 {leafFolders.Count}개의 리프 폴더에서 DWG만 추출하시겠습니까?\n\n" +
+ "각 폴더마다 DWG 추출 작업이 실행되고, 폴더별로 Excel 파일이 생성됩니다.",
+ "DWG 전용 추출 확인");
+
+ if (result != MessageBoxResult.Yes)
+ {
+ return;
+ }
+
+ // UI 상태 변경
+ SetButtonsEnabled(false);
+ progressBar.Value = 0;
+ UpdateStatus("🔧 DWG 전용 폴더별 추출 시작...");
+
+ // 자동 처리 모드 활성화
+ isAutoProcessing = true;
+
+ await ProcessLeafFoldersDwgOnly(leafFolders, resultFolder);
+
+ ShowMessageBox(
+ $"DWG 전용 추출이 완료되었습니다!\n\n" +
+ $"처리된 폴더: {leafFolders.Count}개\n" +
+ $"결과 저장 위치: {resultFolder}",
+ "완료",
+ MessageBoxButton.OK,
+ MessageBoxImage.Information);
+ }
+ catch (Exception ex)
+ {
+ LogMessage($"❌ DWG 전용 추출 중 오류: {ex.Message}");
+ ShowMessageBox($"DWG 전용 추출 중 오류가 발생했습니다:\n{ex.Message}", "오류", MessageBoxButton.OK, MessageBoxImage.Error);
+ }
+ finally
+ {
+ SetButtonsEnabled(true);
+ progressBar.Value = 0;
+ UpdateStatus("✅ 준비");
+
+ // 자동 처리 모드 비활성화
+ isAutoProcessing = false;
+ }
+ }
+
///
/// 폴더에서 리프 폴더들(하위 폴더가 없는 폴더)을 재귀적으로 찾습니다.
///
@@ -1803,6 +1885,163 @@ namespace DwgExtractorManual
UpdateStatus("✅ 자동 처리 완료");
}
+ ///
+ /// 리프 폴더들에 대해 DWG 전용 추출을 수행합니다.
+ ///
+ /// 처리할 리프 폴더 목록
+ /// 결과 파일 저장 기본 폴더
+ private async Task ProcessLeafFoldersDwgOnly(List leafFolders, string resultBaseFolder)
+ {
+ int totalFolders = leafFolders.Count;
+ int currentFolderIndex = 0;
+
+ LogMessage($"🔧 DWG 전용 폴더별 추출 시작: {totalFolders}개 폴더");
+
+ foreach (string leafFolder in leafFolders)
+ {
+ currentFolderIndex++;
+ progressBar.Value = (double)currentFolderIndex / totalFolders * 100;
+
+ try
+ {
+ LogMessage($"📁 [{currentFolderIndex}/{totalFolders}] DWG 추출 시작: {leafFolder}");
+
+ // 1. DWG 추출만 수행
+ await ProcessFilesDwgOnly(leafFolder);
+ LogMessage($"✅ [{currentFolderIndex}/{totalFolders}] DWG 추출 완료");
+
+ // 2초 대기
+ await Task.Delay(2000);
+
+ // 2. DWG 전용 Excel 파일 생성 및 이름 변경
+ await RenameDwgOnlyExcelFile(resultBaseFolder, leafFolder);
+ LogMessage($"📋 [{currentFolderIndex}/{totalFolders}] Excel 파일 생성 완료");
+
+ // 1초 대기
+ await Task.Delay(1000);
+ }
+ catch (Exception ex)
+ {
+ LogMessage($"❌ [{currentFolderIndex}/{totalFolders}] 폴더 처리 실패 ({leafFolder}): {ex.Message}");
+ LogMessage($"⏭️ [{currentFolderIndex}/{totalFolders}] 다음 폴더로 계속 진행");
+
+ // 오류 발생 시 잠시 대기 후 다음 폴더 처리
+ await Task.Delay(2000);
+ continue;
+ }
+ }
+
+ LogMessage($"🎉 DWG 전용 추출 완료! 총 {totalFolders}개 폴더 처리됨");
+ UpdateStatus("✅ DWG 전용 추출 완료");
+ }
+
+ ///
+ /// 지정된 폴더에서 DWG 파일들만 처리합니다.
+ ///
+ /// 처리할 폴더 경로
+ private async Task ProcessFilesDwgOnly(string sourceFolderPath)
+ {
+ try
+ {
+ string resultFolder = txtResultFolder.Text;
+
+ if (!Directory.Exists(sourceFolderPath))
+ {
+ LogMessage($"❌ 소스 폴더가 존재하지 않습니다: {sourceFolderPath}");
+ return;
+ }
+
+ var dwgFiles = Directory.GetFiles(sourceFolderPath, "*.dwg", SearchOption.TopDirectoryOnly);
+
+ if (dwgFiles.Length == 0)
+ {
+ LogMessage($"📄 처리할 DWG 파일이 없습니다: {sourceFolderPath}");
+ return;
+ }
+
+ LogMessage($"📊 처리할 DWG 파일 수: {dwgFiles.Length}개");
+ LogMessage($"📋 출력 모드: Excel");
+ LogMessage($"📂 소스 폴더: {sourceFolderPath}");
+ LogMessage($"💾 결과 폴더: {resultFolder}");
+
+ LogMessage("📊 Excel 내보내기 모드로 시작합니다...");
+ LogMessage("📝 Excel 애플리케이션을 초기화합니다...");
+
+ _exportExcel = new ExportExcel();
+
+ // UI 응답성을 위한 양보
+ await Task.Yield();
+
+ // 각 DWG 파일 처리
+ foreach (string dwgFile in dwgFiles)
+ {
+ LogMessage($"📄 DWG 파일 처리 중: {Path.GetFileName(dwgFile)}");
+ _exportExcel.ExportDwgToExcel(dwgFile);
+
+ // UI 응답성을 위한 양보
+ await Task.Yield();
+ }
+
+ // DWG 전용 워크북 저장
+ LogMessage("💾 DWG 전용 Excel 파일 저장 중...");
+ _exportExcel.SaveDwgOnlyMappingWorkbook(resultFolder);
+
+ LogMessage("✅ DWG 전용 Excel 파일 저장 완료");
+ }
+ catch (Exception ex)
+ {
+ LogMessage($"❌ DWG 처리 중 치명적 오류: {ex.Message}");
+ throw;
+ }
+ finally
+ {
+ _exportExcel?.Dispose();
+ _exportExcel = null;
+ }
+ }
+
+ ///
+ /// DWG 전용 Excel 파일을 목표 경로로 이름 변경
+ ///
+ /// 결과 폴더
+ /// 리프 폴더 경로
+ private async Task RenameDwgOnlyExcelFile(string resultFolder, string leafFolderPath)
+ {
+ try
+ {
+ // 최신 *_DwgOnly_Mapping.xlsx 파일 찾기
+ var excelFiles = Directory.GetFiles(resultFolder, "*_DwgOnly_Mapping.xlsx")
+ .Where(f => !Path.GetFileName(f).StartsWith("~$"))
+ .OrderByDescending(f => File.GetCreationTime(f))
+ .ToList();
+
+ if (excelFiles.Any())
+ {
+ string latestFile = excelFiles.First();
+
+ // 리프 폴더 경로를 기반으로 파일명 생성
+ string relativePath = Path.GetRelativePath(txtSourceFolder.Text, leafFolderPath);
+ string safePath = relativePath.Replace('\\', '_').Replace('/', '_').Replace(':', '_');
+ string targetFileName = $"{safePath}_DwgMapping.xlsx";
+ string targetPath = Path.Combine(resultFolder, targetFileName);
+
+ // 목표 파일이 이미 존재하면 삭제
+ if (File.Exists(targetPath))
+ {
+ File.Delete(targetPath);
+ }
+
+ // 파일 이름 변경
+ File.Move(latestFile, targetPath);
+ LogMessage($"📋 DWG Excel 파일 이름 변경됨: {targetFileName}");
+ }
+ }
+ catch (Exception ex)
+ {
+ LogMessage($"⚠️ DWG Excel 파일 이름 변경 실패: {ex.Message}");
+ }
+ }
+
///
/// 최신 Excel 파일을 목표 경로로 이름 변경
///
@@ -1849,6 +2088,7 @@ namespace DwgExtractorManual
btnPdfExtract.IsEnabled = enabled;
btnMerge.IsEnabled = enabled;
btnAuto.IsEnabled = enabled;
+ btnDwgOnly.IsEnabled = enabled;
}
protected override void OnClosed(EventArgs e)
diff --git a/Models/ExportExcel.cs b/Models/ExportExcel.cs
index 8c0c8ce..c4ba073 100644
--- a/Models/ExportExcel.cs
+++ b/Models/ExportExcel.cs
@@ -841,6 +841,94 @@ namespace DwgExtractorManual.Models
}
}
+ ///
+ /// DWG 전용 매핑 워크북을 생성하고 저장합니다 (PDF 컬럼 제외).
+ ///
+ /// 결과 파일 저장 폴더 경로
+ public void SaveDwgOnlyMappingWorkbook(string resultFolderPath)
+ {
+ try
+ {
+ string timestamp = DateTime.Now.ToString("yyyyMMdd_HHmmss");
+ string savePath = Path.Combine(resultFolderPath, $"{timestamp}_DwgOnly_Mapping.xlsx");
+
+ Debug.WriteLine($"[DEBUG] DWG 전용 매핑 워크북 생성 시작: {savePath}");
+
+ // Excel 애플리케이션 초기화 확인
+ if (excelApplication == null)
+ {
+ excelApplication = new Excel.Application();
+ excelApplication.Visible = false;
+ Debug.WriteLine("[DEBUG] 새 Excel 애플리케이션 생성됨 (DWG 전용)");
+ }
+
+ // DWG 전용 워크북 생성
+ var dwgOnlyWorkbook = excelApplication.Workbooks.Add();
+ var dwgOnlyWorksheet = (Excel.Worksheet)dwgOnlyWorkbook.Worksheets[1];
+ dwgOnlyWorksheet.Name = "DWG Mapping Data";
+
+ // 헤더 생성 (PDF Value 컬럼 제외)
+ dwgOnlyWorksheet.Cells[1, 1] = "파일명";
+ dwgOnlyWorksheet.Cells[1, 2] = "Map Key";
+ dwgOnlyWorksheet.Cells[1, 3] = "AI Label";
+ dwgOnlyWorksheet.Cells[1, 4] = "DWG Tag";
+ dwgOnlyWorksheet.Cells[1, 5] = "DWG Value";
+
+ // 헤더 스타일 적용
+ var headerRange = dwgOnlyWorksheet.Range["A1:E1"];
+ headerRange.Font.Bold = true;
+ headerRange.Interior.Color = System.Drawing.ColorTranslator.ToOle(System.Drawing.Color.LightGray);
+ headerRange.Borders.LineStyle = Excel.XlLineStyle.xlContinuous;
+
+ // 데이터 입력
+ int row = 2;
+ foreach (var fileEntry in FileToMapkeyToLabelTagValuePdf)
+ {
+ string fileName = fileEntry.Key;
+ foreach (var mapEntry in fileEntry.Value)
+ {
+ string mapKey = mapEntry.Key;
+ var (aiLabel, dwgTag, dwgValue, pdfValue) = mapEntry.Value;
+
+ dwgOnlyWorksheet.Cells[row, 1] = fileName;
+ dwgOnlyWorksheet.Cells[row, 2] = mapKey;
+ dwgOnlyWorksheet.Cells[row, 3] = aiLabel;
+ dwgOnlyWorksheet.Cells[row, 4] = dwgTag;
+ dwgOnlyWorksheet.Cells[row, 5] = dwgValue;
+
+ row++;
+ }
+ }
+
+ // 컬럼 자동 크기 조정
+ dwgOnlyWorksheet.Columns.AutoFit();
+
+ // 파일 저장
+ string directory = Path.GetDirectoryName(savePath);
+ if (!string.IsNullOrEmpty(directory) && !Directory.Exists(directory))
+ {
+ Directory.CreateDirectory(directory);
+ }
+
+ dwgOnlyWorkbook.SaveAs(savePath,
+ FileFormat: Excel.XlFileFormat.xlOpenXMLWorkbook,
+ AccessMode: Excel.XlSaveAsAccessMode.xlNoChange);
+
+ Debug.WriteLine($"✅ DWG 전용 매핑 워크북 저장 완료: {Path.GetFileName(savePath)}");
+
+ // 워크북 정리
+ dwgOnlyWorkbook.Close(false);
+ System.Runtime.InteropServices.Marshal.ReleaseComObject(dwgOnlyWorksheet);
+ System.Runtime.InteropServices.Marshal.ReleaseComObject(dwgOnlyWorkbook);
+ }
+ catch (System.Exception ex)
+ {
+ Debug.WriteLine($"❌ DWG 전용 매핑 워크북 저장 중 오류: {ex.Message}");
+ Debug.WriteLine($" 스택 트레이스: {ex.StackTrace}");
+ throw;
+ }
+ }
+
///
/// 현재 Excel 워크북을 지정된 경로에 저장하고 Excel 애플리케이션을 종료합니다.
///