【AutoCAD】ダイナミックブロックまとめ記事10選 について図面がダウンロードできない不具合を修正しました。

C#コード参考

C#
using Autodesk.AutoCAD.DatabaseServices;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace LineListEx
{
    public class PipeGroupData
    {
        public string LineInfo { get; set; }
        public string Remarks { get; set; }

        // 内部管理用
        public List<ObjectId> ObjectIds { get; set; }

        public PipeGroupData(string lineInfo, string remarks = "")
        {
            LineInfo = lineInfo;
            Remarks = remarks;
            ObjectIds = new List<ObjectId>();
        }

        // LineInfo が同じなら同一グループ
        public bool EqualsAttributes(string lineInfo)
        {
            return this.LineInfo == lineInfo;
        }
    }
}

C#
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Runtime;
using App = Autodesk.AutoCAD.ApplicationServices.Application;
//using System.Windows.Forms;

namespace LineListEx
{
    public class LineListCommand
    {
        [CommandMethod("AddPipeLine")]
        public void AddPipeline()
        {
            Document doc = App.DocumentManager.MdiActiveDocument;
            Database db = doc.Database;
            Editor ed = doc.Editor;

            try
            {
                // 1. 入力方法の選択
                PromptKeywordOptions pKeyOpts = new PromptKeywordOptions(
                    "\nラインナンバー入力方法を選んでください [Input(直接入力)/Select(図面上の文字列を選択)]: ",
                    "Input Select"
                );
                pKeyOpts.AllowNone = false;
                PromptResult pKeyRes = ed.GetKeywords(pKeyOpts);
                if (pKeyRes.Status != PromptStatus.OK) return;

                string lineNo = "";

                if (pKeyRes.StringResult == "Input")
                {
                    // 2. 直接入力
                    PromptStringOptions pStrOpts = new PromptStringOptions("\nラインナンバーを入力してください: ");
                    pStrOpts.AllowSpaces = false;
                    PromptResult pStrRes = ed.GetString(pStrOpts);
                    if (pStrRes.Status != PromptStatus.OK) return;
                    lineNo = pStrRes.StringResult;
                }
                else if (pKeyRes.StringResult == "Select")
                {
                    // 3. 図面上のテキスト選択
                    PromptEntityOptions peo = new PromptEntityOptions("\nラインナンバーとして使用するテキストを選択してください: ");
                    peo.SetRejectMessage("\nテキストを選択してください。");
                    peo.AddAllowedClass(typeof(DBText), true);
                    peo.AddAllowedClass(typeof(MText), true);
                    PromptEntityResult per = ed.GetEntity(peo);
                    if (per.Status != PromptStatus.OK) return;

                    using (Transaction tr = db.TransactionManager.StartTransaction())
                    {
                        Entity ent = tr.GetObject(per.ObjectId, OpenMode.ForRead) as Entity;
                        if (ent is DBText dbText)
                            lineNo = dbText.TextString;
                        else if (ent is MText mText)
                            lineNo = mText.Text;

                        tr.Commit();
                    }
                }

                if (string.IsNullOrEmpty(lineNo))
                {
                    ed.WriteMessage("\nラインナンバーが取得できませんでした。");
                    return;
                }

                // 4. オブジェクト選択
                PromptSelectionOptions selOpts = new PromptSelectionOptions();
                selOpts.MessageForAdding = "\nラインナンバーを付与するオブジェクトを選択してください: ";
                PromptSelectionResult selRes = ed.GetSelection(selOpts);
                if (selRes.Status != PromptStatus.OK) return;

                using (Transaction tr = db.TransactionManager.StartTransaction())
                {
                    // 既存のRemarksを取得
                    string existingRemarks = GetExistingRemarks(db, tr, lineNo);

                    // 選択されたオブジェクトに保存
                    foreach (SelectedObject selObj in selRes.Value)
                    {
                        if (selObj == null) continue;
                        SaveLineInfoAndRemarks(tr, selObj.ObjectId, lineNo, existingRemarks);
                    }

                    tr.Commit();
                }

                ed.WriteMessage("\n選択した全てのオブジェクトにラインナンバーを保存しました。");
            }
            catch (System.Exception ex)
            {
                ed.WriteMessage($"\nエラー: {ex.Message}");
            }
        }

        // ★ 既存 LineInfo があれば Remarks を返す(なければ空)
        private string GetExistingRemarks(Database db, Transaction tr, string lineNo)
        {
            BlockTable bt = tr.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable;
            BlockTableRecord btr = tr.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForRead) as BlockTableRecord;

            foreach (ObjectId id in btr)
            {
                Entity ent = tr.GetObject(id, OpenMode.ForRead) as Entity;
                if (ent?.ExtensionDictionary.IsValid != true) continue;

                DBDictionary extDict = tr.GetObject(ent.ExtensionDictionary, OpenMode.ForRead) as DBDictionary;
                if (extDict.Contains("LineInfo"))
                {
                    Xrecord xrec = tr.GetObject(extDict.GetAt("LineInfo"), OpenMode.ForRead) as Xrecord;

                    // ★ 修正版 TypedValue 配列アクセス
                    TypedValue[] values = xrec?.Data?.AsArray();
                    string info = "";
                    if (values != null && values.Length > 0)
                        info = values[0].Value?.ToString() ?? "";

                    if (info == lineNo && extDict.Contains("Remarks"))
                    {
                        Xrecord xrecRem = tr.GetObject(extDict.GetAt("Remarks"), OpenMode.ForRead) as Xrecord;
                        TypedValue[] remValues = xrecRem?.Data?.AsArray();
                        if (remValues != null && remValues.Length > 0)
                            return remValues[0].Value?.ToString() ?? "";
                        else
                            return "";
                    }
                }
            }

            return ""; // 新規の場合は空
        }

        // ★ LineInfo と Remarks を保存する共通関数
        private void SaveLineInfoAndRemarks(Transaction tr, ObjectId objId, string lineNo, string remarks)
        {
            if (!objId.IsValid) return;

            Entity ent = tr.GetObject(objId, OpenMode.ForWrite) as Entity;
            if (ent == null) return;

            if (!ent.ExtensionDictionary.IsValid)
                ent.CreateExtensionDictionary();

            DBDictionary extDict = tr.GetObject(ent.ExtensionDictionary, OpenMode.ForWrite) as DBDictionary;

            // LineInfo 保存
            SaveOrUpdateXrecord(tr, extDict, "LineInfo", lineNo);

            // Remarks 保存
            SaveOrUpdateXrecord(tr, extDict, "Remarks", remarks);
        }

        // ★ 既存 Xrecord を削除して上書き
        private void SaveOrUpdateXrecord(Transaction tr, DBDictionary extDict, string key, string value)
        {
            if (extDict.Contains(key))
            {
                ObjectId oldId = extDict.GetAt(key);
                tr.GetObject(oldId, OpenMode.ForWrite).Erase();
            }

            Xrecord xrec = new Xrecord
            {
                Data = new ResultBuffer(new TypedValue((int)DxfCode.Text, value ?? ""))
            };
            extDict.SetAt(key, xrec);
            tr.AddNewlyCreatedDBObject(xrec, true);
        }


        [CommandMethod("GetPipeLine")]
        public void GetPipeLine()
        {
            Document doc = App.DocumentManager.MdiActiveDocument;
            Database db = doc.Database;
            Editor ed = doc.Editor;

            try
            {
                PromptEntityOptions peo = new PromptEntityOptions("\nラインナンバーを確認するオブジェクトを選択してください: ");
                PromptEntityResult per = ed.GetEntity(peo);
                if (per.Status != PromptStatus.OK) return;

                string targetLineNo = null;

                using (Transaction tr = db.TransactionManager.StartTransaction())
                {
                    Entity ent = tr.GetObject(per.ObjectId, OpenMode.ForRead) as Entity;
                    if (ent != null && ent.ExtensionDictionary.IsValid)
                    {
                        DBDictionary extDict = tr.GetObject(ent.ExtensionDictionary, OpenMode.ForRead) as DBDictionary;
                        if (extDict.Contains("LineInfo"))
                        {
                            Xrecord xrec = tr.GetObject(extDict.GetAt("LineInfo"), OpenMode.ForRead) as Xrecord;

                            // ★ 修正版 TypedValue 配列アクセス
                            TypedValue[] values = xrec?.Data?.AsArray();
                            if (values != null && values.Length > 0)
                                targetLineNo = values[0].Value?.ToString() ?? "";
                        }
                    }
                    tr.Commit();
                }

                if (string.IsNullOrEmpty(targetLineNo))
                    ed.WriteMessage("\n選択したオブジェクトにはラインナンバーがありません。");
                else
                    ed.WriteMessage($"\n選択オブジェクトのラインナンバー: {targetLineNo}");
            }
            catch (System.Exception ex)
            {
                ed.WriteMessage($"\nエラー: {ex.Message}");
            }
        }

        [CommandMethod("ShowPipeInfo")]
        public void ShowPipeInfo()
        {
            Document doc = App.DocumentManager.MdiActiveDocument;
            Database db = doc.Database;

            List<PipeGroupData> pipeGroups = new List<PipeGroupData>();

            try
            {
                using (Transaction tr = db.TransactionManager.StartTransaction())
                {
                    BlockTable bt = tr.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable;
                    BlockTableRecord btr = tr.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForRead) as BlockTableRecord;

                    foreach (ObjectId id in btr)
                    {
                        Entity ent = tr.GetObject(id, OpenMode.ForRead) as Entity;
                        if (ent == null) continue;

                        string lineInfo = "";
                        string remarks = "";

                        if (ent.ExtensionDictionary.IsValid)
                        {
                            DBDictionary extDict = tr.GetObject(ent.ExtensionDictionary, OpenMode.ForRead) as DBDictionary;

                            // LineInfo 読み取り
                            if (extDict.Contains("LineInfo"))
                            {
                                Xrecord xrec = tr.GetObject(extDict.GetAt("LineInfo"), OpenMode.ForRead) as Xrecord;
                                if (xrec != null && xrec.Data != null)
                                {
                                    TypedValue[] values = xrec.Data.AsArray();
                                    if (values.Length > 0)
                                        lineInfo = values[0].Value.ToString();
                                }
                            }

                            // Remarks 読み取り
                            if (extDict.Contains("Remarks"))
                            {
                                Xrecord xrec = tr.GetObject(extDict.GetAt("Remarks"), OpenMode.ForRead) as Xrecord;
                                if (xrec != null && xrec.Data != null)
                                {
                                    TypedValue[] values = xrec.Data.AsArray();
                                    if (values.Length > 0)
                                        remarks = values[0].Value.ToString();
                                }
                            }
                        }

                        // ★ LineInfo が空ならスキップ
                        if (string.IsNullOrEmpty(lineInfo)) continue;

                        // 既存グループを探す
                        var group = pipeGroups.FirstOrDefault(g => g.EqualsAttributes(lineInfo));
                        if (group == null)
                        {
                            group = new PipeGroupData(lineInfo, remarks);
                            pipeGroups.Add(group);
                        }
                        group.ObjectIds.Add(id);
                    }

                    tr.Commit();
                }

                // フォームを非モーダルで表示
                LineInfoForm form = new LineInfoForm(pipeGroups);
                form.Show(new WindowWrapper(App.MainWindow.Handle));
            }
            catch (System.Exception ex)
            {
                App.ShowAlertDialog("エラー: " + ex.Message);
            }
        }

    }
    // AutoCAD のウィンドウを親にするためのラッパー
    public class WindowWrapper : IWin32Window
    {
        private readonly System.IntPtr _hwnd;
        public WindowWrapper(System.IntPtr handle) { _hwnd = handle; }
        public System.IntPtr Handle => _hwnd;
    }
}

C#
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Runtime;
using App = Autodesk.AutoCAD.ApplicationServices.Application;
//using System.Windows.Forms;

namespace LineListEx
{
    public class LineListCommand
    {
        [CommandMethod("AddPipeLine")]
        public void AddPipeline()
        {
            Document doc = App.DocumentManager.MdiActiveDocument;
            Database db = doc.Database;
            Editor ed = doc.Editor;

            try
            {
                // 1. 入力方法の選択
                PromptKeywordOptions pKeyOpts = new PromptKeywordOptions(
                    "\nラインナンバー入力方法を選んでください [Input(直接入力)/Select(図面上の文字列を選択)]: ",
                    "Input Select"
                );
                pKeyOpts.AllowNone = false;
                PromptResult pKeyRes = ed.GetKeywords(pKeyOpts);
                if (pKeyRes.Status != PromptStatus.OK) return;

                string lineNo = "";

                if (pKeyRes.StringResult == "Input")
                {
                    // 2. 直接入力
                    PromptStringOptions pStrOpts = new PromptStringOptions("\nラインナンバーを入力してください: ");
                    pStrOpts.AllowSpaces = false;
                    PromptResult pStrRes = ed.GetString(pStrOpts);
                    if (pStrRes.Status != PromptStatus.OK) return;
                    lineNo = pStrRes.StringResult;
                }
                else if (pKeyRes.StringResult == "Select")
                {
                    // 3. 図面上のテキスト選択
                    PromptEntityOptions peo = new PromptEntityOptions("\nラインナンバーとして使用するテキストを選択してください: ");
                    peo.SetRejectMessage("\nテキストを選択してください。");
                    peo.AddAllowedClass(typeof(DBText), true);
                    peo.AddAllowedClass(typeof(MText), true);
                    PromptEntityResult per = ed.GetEntity(peo);
                    if (per.Status != PromptStatus.OK) return;

                    using (Transaction tr = db.TransactionManager.StartTransaction())
                    {
                        Entity ent = tr.GetObject(per.ObjectId, OpenMode.ForRead) as Entity;
                        if (ent is DBText dbText)
                            lineNo = dbText.TextString;
                        else if (ent is MText mText)
                            lineNo = mText.Text;

                        tr.Commit();
                    }
                }

                if (string.IsNullOrEmpty(lineNo))
                {
                    ed.WriteMessage("\nラインナンバーが取得できませんでした。");
                    return;
                }

                // 4. オブジェクト選択
                PromptSelectionOptions selOpts = new PromptSelectionOptions();
                selOpts.MessageForAdding = "\nラインナンバーを付与するオブジェクトを選択してください: ";
                PromptSelectionResult selRes = ed.GetSelection(selOpts);
                if (selRes.Status != PromptStatus.OK) return;

                using (Transaction tr = db.TransactionManager.StartTransaction())
                {
                    // 既存のRemarksを取得
                    string existingRemarks = GetExistingRemarks(db, tr, lineNo);

                    // 選択されたオブジェクトに保存
                    foreach (SelectedObject selObj in selRes.Value)
                    {
                        if (selObj == null) continue;
                        SaveLineInfoAndRemarks(tr, selObj.ObjectId, lineNo, existingRemarks);
                    }

                    tr.Commit();
                }

                ed.WriteMessage("\n選択した全てのオブジェクトにラインナンバーを保存しました。");
            }
            catch (System.Exception ex)
            {
                ed.WriteMessage($"\nエラー: {ex.Message}");
            }
        }

        // ★ 既存 LineInfo があれば Remarks を返す(なければ空)
        private string GetExistingRemarks(Database db, Transaction tr, string lineNo)
        {
            BlockTable bt = tr.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable;
            BlockTableRecord btr = tr.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForRead) as BlockTableRecord;

            foreach (ObjectId id in btr)
            {
                Entity ent = tr.GetObject(id, OpenMode.ForRead) as Entity;
                if (ent?.ExtensionDictionary.IsValid != true) continue;

                DBDictionary extDict = tr.GetObject(ent.ExtensionDictionary, OpenMode.ForRead) as DBDictionary;
                if (extDict.Contains("LineInfo"))
                {
                    Xrecord xrec = tr.GetObject(extDict.GetAt("LineInfo"), OpenMode.ForRead) as Xrecord;

                    // ★ 修正版 TypedValue 配列アクセス
                    TypedValue[] values = xrec?.Data?.AsArray();
                    string info = "";
                    if (values != null && values.Length > 0)
                        info = values[0].Value?.ToString() ?? "";

                    if (info == lineNo && extDict.Contains("Remarks"))
                    {
                        Xrecord xrecRem = tr.GetObject(extDict.GetAt("Remarks"), OpenMode.ForRead) as Xrecord;
                        TypedValue[] remValues = xrecRem?.Data?.AsArray();
                        if (remValues != null && remValues.Length > 0)
                            return remValues[0].Value?.ToString() ?? "";
                        else
                            return "";
                    }
                }
            }

            return ""; // 新規の場合は空
        }

        // ★ LineInfo と Remarks を保存する共通関数
        private void SaveLineInfoAndRemarks(Transaction tr, ObjectId objId, string lineNo, string remarks)
        {
            if (!objId.IsValid) return;

            Entity ent = tr.GetObject(objId, OpenMode.ForWrite) as Entity;
            if (ent == null) return;

            if (!ent.ExtensionDictionary.IsValid)
                ent.CreateExtensionDictionary();

            DBDictionary extDict = tr.GetObject(ent.ExtensionDictionary, OpenMode.ForWrite) as DBDictionary;

            // LineInfo 保存
            SaveOrUpdateXrecord(tr, extDict, "LineInfo", lineNo);

            // Remarks 保存
            SaveOrUpdateXrecord(tr, extDict, "Remarks", remarks);
        }

        // ★ 既存 Xrecord を削除して上書き
        private void SaveOrUpdateXrecord(Transaction tr, DBDictionary extDict, string key, string value)
        {
            if (extDict.Contains(key))
            {
                ObjectId oldId = extDict.GetAt(key);
                tr.GetObject(oldId, OpenMode.ForWrite).Erase();
            }

            Xrecord xrec = new Xrecord
            {
                Data = new ResultBuffer(new TypedValue((int)DxfCode.Text, value ?? ""))
            };
            extDict.SetAt(key, xrec);
            tr.AddNewlyCreatedDBObject(xrec, true);
        }


        [CommandMethod("GetPipeLine")]
        public void GetPipeLine()
        {
            Document doc = App.DocumentManager.MdiActiveDocument;
            Database db = doc.Database;
            Editor ed = doc.Editor;

            try
            {
                PromptEntityOptions peo = new PromptEntityOptions("\nラインナンバーを確認するオブジェクトを選択してください: ");
                PromptEntityResult per = ed.GetEntity(peo);
                if (per.Status != PromptStatus.OK) return;

                string targetLineNo = null;

                using (Transaction tr = db.TransactionManager.StartTransaction())
                {
                    Entity ent = tr.GetObject(per.ObjectId, OpenMode.ForRead) as Entity;
                    if (ent != null && ent.ExtensionDictionary.IsValid)
                    {
                        DBDictionary extDict = tr.GetObject(ent.ExtensionDictionary, OpenMode.ForRead) as DBDictionary;
                        if (extDict.Contains("LineInfo"))
                        {
                            Xrecord xrec = tr.GetObject(extDict.GetAt("LineInfo"), OpenMode.ForRead) as Xrecord;

                            // ★ 修正版 TypedValue 配列アクセス
                            TypedValue[] values = xrec?.Data?.AsArray();
                            if (values != null && values.Length > 0)
                                targetLineNo = values[0].Value?.ToString() ?? "";
                        }
                    }
                    tr.Commit();
                }

                if (string.IsNullOrEmpty(targetLineNo))
                    ed.WriteMessage("\n選択したオブジェクトにはラインナンバーがありません。");
                else
                    ed.WriteMessage($"\n選択オブジェクトのラインナンバー: {targetLineNo}");
            }
            catch (System.Exception ex)
            {
                ed.WriteMessage($"\nエラー: {ex.Message}");
            }
        }

        [CommandMethod("ShowPipeInfo")]
        public void ShowPipeInfo()
        {
            Document doc = App.DocumentManager.MdiActiveDocument;
            Database db = doc.Database;

            List<PipeGroupData> pipeGroups = new List<PipeGroupData>();

            try
            {
                using (Transaction tr = db.TransactionManager.StartTransaction())
                {
                    BlockTable bt = tr.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable;
                    BlockTableRecord btr = tr.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForRead) as BlockTableRecord;

                    foreach (ObjectId id in btr)
                    {
                        Entity ent = tr.GetObject(id, OpenMode.ForRead) as Entity;
                        if (ent == null) continue;

                        string lineInfo = "";
                        string remarks = "";

                        if (ent.ExtensionDictionary.IsValid)
                        {
                            DBDictionary extDict = tr.GetObject(ent.ExtensionDictionary, OpenMode.ForRead) as DBDictionary;

                            // LineInfo 読み取り
                            if (extDict.Contains("LineInfo"))
                            {
                                Xrecord xrec = tr.GetObject(extDict.GetAt("LineInfo"), OpenMode.ForRead) as Xrecord;
                                if (xrec != null && xrec.Data != null)
                                {
                                    TypedValue[] values = xrec.Data.AsArray();
                                    if (values.Length > 0)
                                        lineInfo = values[0].Value.ToString();
                                }
                            }

                            // Remarks 読み取り
                            if (extDict.Contains("Remarks"))
                            {
                                Xrecord xrec = tr.GetObject(extDict.GetAt("Remarks"), OpenMode.ForRead) as Xrecord;
                                if (xrec != null && xrec.Data != null)
                                {
                                    TypedValue[] values = xrec.Data.AsArray();
                                    if (values.Length > 0)
                                        remarks = values[0].Value.ToString();
                                }
                            }
                        }

                        // ★ LineInfo が空ならスキップ
                        if (string.IsNullOrEmpty(lineInfo)) continue;

                        // 既存グループを探す
                        var group = pipeGroups.FirstOrDefault(g => g.EqualsAttributes(lineInfo));
                        if (group == null)
                        {
                            group = new PipeGroupData(lineInfo, remarks);
                            pipeGroups.Add(group);
                        }
                        group.ObjectIds.Add(id);
                    }

                    tr.Commit();
                }

                // フォームを非モーダルで表示
                LineInfoForm form = new LineInfoForm(pipeGroups);
                form.Show(new WindowWrapper(App.MainWindow.Handle));
            }
            catch (System.Exception ex)
            {
                App.ShowAlertDialog("エラー: " + ex.Message);
            }
        }

    }
    // AutoCAD のウィンドウを親にするためのラッパー
    public class WindowWrapper : IWin32Window
    {
        private readonly System.IntPtr _hwnd;
        public WindowWrapper(System.IntPtr handle) { _hwnd = handle; }
        public System.IntPtr Handle => _hwnd;
    }
}