I tried to make a version more finalized than Balaji's example which also takes into account the multiline attributes.
The code uses the C# 7 local functions feature.
[CommandMethod("XPLODEBLOCK")]
public static void ExplodeBlock()
{
var doc = Application.DocumentManager.MdiActiveDocument;
var db = doc.Database;
var ed = doc.Editor;
var psr = ed.GetSelection(new SelectionFilter(new[] { new TypedValue(0, "INSERT") }));
if (psr.Status != PromptStatus.OK)
return;
using (var tr = db.TransactionManager.StartTransaction())
{
var curSpace = (BlockTableRecord)tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite);
// local functions
void append(Entity ent)
{
var id = curSpace.AppendEntity(ent);
tr.AddNewlyCreatedDBObject(ent, true);
}
DBText appendDBText(DBText source)
{
var text = new DBText
{
Normal = source.Normal,
Thickness = source.Thickness,
Oblique = source.Oblique,
Rotation = source.Rotation,
Height = source.Height,
WidthFactor = source.WidthFactor,
TextString = source.TextString,
TextStyleId = source.TextStyleId,
IsMirroredInX = source.IsMirroredInX,
IsMirroredInY = source.IsMirroredInY,
HorizontalMode = source.HorizontalMode,
VerticalMode = source.VerticalMode,
Position = source.Position
};
if (source.Justify != AttachmentPoint.BaseLeft)
{
text.Justify = source.Justify;
text.AlignmentPoint = source.AlignmentPoint;
}
text.SetPropertiesFrom(source);
append(text);
return text;
}
MText appendMtext(MText source)
{
var mtext = new MText
{
Contents = source.Contents,
FlowDirection = source.FlowDirection,
Attachment = source.Attachment,
TextHeight = source.TextHeight,
TextStyleId = source.TextStyleId,
Width = source.Width,
Rotation = source.Rotation,
Location = source.Location,
Normal = source.Normal,
LineSpacingStyle = source.LineSpacingStyle,
Height = source.Height,
LineSpacingFactor = source.LineSpacingFactor,
LineSpaceDistance = source.LineSpaceDistance
};
mtext.SetPropertiesFrom(source);
append(mtext);
return mtext;
}
// main
foreach (SelectedObject selectedObject in psr.Value)
{
var br = (BlockReference)tr.GetObject(selectedObject.ObjectId, OpenMode.ForWrite);
try
{
foreach (ObjectId id in br.AttributeCollection)
{
var att = (AttributeReference)tr.GetObject(id, OpenMode.ForRead);
if (!att.Invisible)
{
if (att.IsMTextAttribute)
appendMtext(att.MTextAttribute).Rotation += br.Rotation;
else
appendDBText(att);
}
}
var btr = (BlockTableRecord)tr.GetObject(br.BlockTableRecord, OpenMode.ForWrite);
btr.Explodable = true;
foreach (ObjectId id in btr)
{
if (id.ObjectClass.DxfName == "ATTDEF")
{
var att = (AttributeDefinition)tr.GetObject(id, OpenMode.ForRead);
if (att.Constant && !att.Invisible)
{
if (att.IsMTextAttributeDefinition)
appendMtext(att.MTextAttributeDefinition).TransformBy(br.BlockTransform);
else
appendDBText(att).TransformBy(br.BlockTransform);
}
}
}
var ents = new DBObjectCollection();
br.Explode(ents);
foreach (Entity ent in ents)
{
if (ent is AttributeDefinition)
ent.Dispose();
else
append(ent);
}
br.Erase();
}
catch
{
ed.WriteMessage($"\nFailed to explode a block named {br.Name}");
}
}
tr.Commit();
}
}