AutoCAD C#

도면 Block BOM 작성 C# 코드

데브프로그라 2025. 8. 27. 21:20
반응형


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}");
        }
    }
}

반응형

/* 코드복사 버튼 */ pre { position: relative; overflow: visible; } pre .copy-button { opacity: 0; position: absolute; right: 8px; top: 4px; padding: 6px 18px; color: rgb(255, 255, 255); background: rgba(255, 223, 0, 0.6); border-radius: 5px; transition: opacity .3s ease-in-out; } pre:hover .copy-button { opacity: 1; } pre .copy-button:hover { color: #eee; transition: all ease-in-out 0.3s; } pre .copy-button:active { color: #33f; transition: all ease-in-out 0.1s; } .copy-message:before { content: attr(copy-message); position: absolute; left: -95px; top: 0px; padding: 6px 18px; color: #fff; background: rgba(255, 223, 0, 0.6); border-radius: 5px; } /* 코드복사 버튼 END */