【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; }
}