using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Runtime;
using System;
using System.Collections.Generic;
using System.Linq;
using System.IO;
public class BlockBOMExtractor
{
[CommandMethod("ExtractBlockBOM")]
public void ExtractBlockBOM()
{
Document doc = Application.DocumentManager.MdiActiveDocument;
Database db = doc.Database;
Editor ed = doc.Editor;
// BOM 데이터를 저장할 딕셔너리 (블록 이름, 개수)
Dictionary<string, int> blockCounts = new Dictionary<string, int>();
// 블록 속성 정보를 저장할 딕셔너리 (블록 참조 ID, 속성 정보)
Dictionary<ObjectId, Dictionary<string, string>> blockAttributes = new Dictionary<ObjectId, Dictionary<string, string>>();
try
{
using (Transaction tr = db.TransactionManager.StartTransaction())
{
// 현재 공간(모델 또는 레이아웃)의 블록테이블 레코드를 가져옴
BlockTableRecord btr = (BlockTableRecord)tr.GetObject(
SymbolUtilityServices.GetBlockModelSpaceId(db), OpenMode.ForRead);
// 모든 엔티티를 순회하며 블록 참조 검색
foreach (ObjectId objId in btr)
{
if (objId.ObjectClass.DxfName == "INSERT")
{
BlockReference blockRef = tr.GetObject(objId, OpenMode.ForRead) as BlockReference;
if (blockRef != null)
{
// 블록 정의 가져오기
BlockTableRecord blockDef = tr.GetObject(blockRef.BlockTableRecord, OpenMode.ForRead) as BlockTableRecord;
string blockName = blockDef.Name;
// 시스템 블록 제외 (*로 시작하는 블록)
if (!blockName.StartsWith("*"))
{
// 블록 개수 카운트
if (blockCounts.ContainsKey(blockName))
blockCounts[blockName]++;
else
blockCounts[blockName] = 1;
// 블록 속성 정보 수집
Dictionary<string, string> attributes = new Dictionary<string, string>();
// 블록의 속성 수집
foreach (ObjectId attId in blockRef.AttributeCollection)
{
AttributeReference attRef = tr.GetObject(attId, OpenMode.ForRead) as AttributeReference;
if (attRef != null)
{
attributes[attRef.Tag] = attRef.TextString;
}
}
blockAttributes[objId] = attributes;
}
}
}
}
tr.Commit();
}
// BOM 결과 출력
ed.WriteMessage("\n===== 블록 BOM 결과 =====\n");
ed.WriteMessage("블록 이름\t\t개수\n");
foreach (var item in blockCounts)
{
ed.WriteMessage($"{item.Key}\t\t{item.Value}\n");
}
// CSV 파일로 내보내기
ExportToCSV(blockCounts, blockAttributes);
}
catch (System.Exception ex)
{
ed.WriteMessage($"\n오류 발생: {ex.Message}");
}
}
private void ExportToCSV(Dictionary<string, int> blockCounts,
Dictionary<ObjectId, Dictionary<string, string>> blockAttributes)
{
Document doc = Application.DocumentManager.MdiActiveDocument;
string fileName = Path.GetFileNameWithoutExtension(doc.Name);
string filePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop),
$"{fileName}_BOM_{DateTime.Now.ToString("yyyyMMdd_HHmmss")}.csv");
try
{
using (StreamWriter sw = new StreamWriter(filePath))
{
// 헤더 작성
sw.WriteLine("블록 이름,개수,추가 정보");
// 데이터 작성
foreach (var block in blockCounts)
{
sw.WriteLine($"{block.Key},{block.Value}");
}
// 상세 속성 정보 작성
sw.WriteLine("\n\n블록 상세 속성 정보");
sw.WriteLine("블록 ID,블록 이름,속성 태그,속성 값");
foreach (var blockAttr in blockAttributes)
{
ObjectId blockId = blockAttr.Key;
string blockName = string.Empty;
using (Transaction tr = doc.Database.TransactionManager.StartTransaction())
{
BlockReference blockRef = tr.GetObject(blockId, OpenMode.ForRead) as BlockReference;
if (blockRef != null)
{
BlockTableRecord blockDef = tr.GetObject(blockRef.BlockTableRecord, OpenMode.ForRead) as BlockTableRecord;
blockName = blockDef.Name;
}
tr.Commit();
}
foreach (var attr in blockAttr.Value)
{
sw.WriteLine($"{blockId},{blockName},{attr.Key},{attr.Value}");
}
}
}
doc.Editor.WriteMessage($"\nBOM이 성공적으로 저장되었습니다: {filePath}");
}
catch (Exception ex)
{
doc.Editor.WriteMessage($"\nCSV 파일 저장 중 오류 발생: {ex.Message}");
}
}
}
'AutoCAD C#' 카테고리의 다른 글
[AutoCAD C#]폴리선의 좌표를 표시한다. (0) | 2024.12.21 |
---|---|
[AutoCAD C#]AutoCAD Palette 배경색상 설정 (0) | 2024.11.09 |
[AutoCAD C#]AutoCAD에서 C# 코드를 이용하여 선택한 블록들의 위치 출력 (0) | 2024.10.09 |
[AutoCAD C#]원 그리기 (Layer, Color) 예제 (2) | 2024.04.26 |
[AutoCAD C#]오토캐드에서 선택한 객체 정보를 보여준다. (0) | 2024.02.28 |