这是我的代码,根据输入的名称选择dwg文件中的特定块。 但我想选择整个页面,只想要一个特定块的表。 而且标题部分也给我错误信息我有四个属性,但它只在标题部分打印一个。请提出解决方案。
namespace TableCreation
{
public class Commands
{
// Set up some formatting constants
// for the table
private const double colWidth = 15.0;
private const double rowHeight = 3.0;
private const double textHeight = 1.0;
private const CellAlignment cellAlign =
CellAlignment.MiddleCenter;
// Helper function to set text height
// and alignment of specific cells,
// as well as inserting the text
static public void SetCellText(Table tb, int row, int col, string value)
{
tb.SetAlignment(row, col, cellAlign);
tb.SetTextHeight(row, col, textHeight);
tb.SetTextString(row, col, value);
}
[CommandMethod("BAT")]
static public void BlockAttributeTable()
{
Document doc = Application.DocumentManager.MdiActiveDocument;
Database db = doc.Database;
Editor ed = doc.Editor;
PromptStringOptions opt = new PromptStringOptions("\nEnter name of block to list: ");
PromptResult pr = ed.GetString(opts);
if (pr.Status == PromptStatus.OK)
{
string blockToFind = pr.StringResult.ToUpper();
Transaction tr = doc.TransactionManager.StartTransaction();
using (tr)
{
// Let's check the block exists
BlockTable bt = (BlockTable)tr.GetObject(doc.Database.BlockTableId, OpenMode.ForRead);
if (!bt.Has(blockToFind))
{
ed.WriteMessage("\nBlock " + blockToFind + " does not exist.");
}
else
{
// And go through looking for
// attribute definitions
StringCollection colNames = new StringCollection();
BlockTableRecord bd = (BlockTableRecord)tr.GetObject(bt[blockToFind], OpenMode.ForRead);
foreach (ObjectId adId in bd)
{
DBObject adObj = tr.GetObject(adId, OpenMode.ForRead);
// For each attribute definition we find...
AttributeDefinition ad = adObj as AttributeDefinition;
if (ad != null)
{
// ... we add its name to the list
colNames.Add(ad.Tag);
}
}
if (colNames.Count == 0)
{
ed.WriteMessage("\nThe block " + blockToFind + " contains no attribute definitions.");
}
else
{
// Ask the user for the insertion point
// and then create the table
PromptPointResult ppr;
PromptPointOptions ppo = new PromptPointOptions("");
ppo.Message = "\n Select the place for print output:";
//get the coordinates from user
ppr = ed.GetPoint(ppo);
if (ppr.Status != PromptStatus.OK)
return;
Point3d startPoint = ppr.Value.TransformBy(ed.CurrentUserCoordinateSystem);
//Point3d startPoint1 = startPoint.Subtract();
Vector3d disp = new Vector3d(0.0, -2.0 * db.Textsize, 0.0);
Vector3d disp2 = new Vector3d(0.0, -2.0 * db.Textsize, 0.0);
if (ppr.Status == PromptStatus.OK)
{
Table tb = new Table();
tb.TableStyle = db.Tablestyle;
tb.NumRows = 1;
tb.NumColumns = colNames.Count;
tb.SetRowHeight(rowHeight);
tb.SetColumnWidth(colWidth);
tb.Position = startPoint;
// Let's add our column headings
for (int i = 0; i < colNames.Count; i++)
{
SetCellText(tb, 0, i, colNames[i]);
}
// Now let's search for instances of
// our block in the modelspace
BlockTableRecord ms = (BlockTableRecord)tr.GetObject(bt[BlockTableRecord.PaperSpace], OpenMode.ForRead);
int rowNum = 1;
foreach (ObjectId objId in ms)
{
DBObject obj = tr.GetObject(objId, OpenMode.ForRead);
BlockReference br = obj as BlockReference;
if (br != null)
{
BlockTableRecord btr = (BlockTableRecord)tr.GetObject(br.BlockTableRecord, OpenMode.ForRead);
using (btr)
{
if (btr.Name.ToUpper() == blockToFind)
{
// We have found one of our blocks,
// so add a row for it in the table
tb.InsertRows(rowNum, rowHeight, 1);
// Assume that the attribute refs
// follow the same order as the
// attribute defs in the block
int attNum = 0;
foreach (ObjectId arId in br.AttributeCollection)
{
DBObject arObj = tr.GetObject(arId, OpenMode.ForRead);
AttributeReference ar = arObj as AttributeReference;
if (ar != null)
{
// Embed or link the values
string strCell;
//if (embed)
//{
strCell = ar.TextString;
//}
//else
//{
string strArId = arId.ToString();
strArId = strArId.Trim(new char[] { '(', ')' });
SetCellText(tb, rowNum, attNum, strCell);
ed.WriteMessage(strCell);
}
attNum++;
}
rowNum++;
}
}
}
}
tb.GenerateLayout();
ms.UpgradeOpen();
ms.AppendEntity(tb);
tr.AddNewlyCreatedDBObject(tb, true);
tr.Commit();
}
}
}
}
}
}
}
}
答案 0 :(得分:0)
要让用户在屏幕上选择一个块,您可以使用PromptEntityOptions来选择BlockReference。我修改了部分代码以包含此内容:
[CommandMethod("BAT")]
static public void BlockAttributeTable()
{
Document doc = Application.DocumentManager.MdiActiveDocument;
Database db = doc.Database;
Editor ed = doc.Editor;
PromptEntityOptions opts = new PromptEntityOptions("\nSelect a block: ");
opts.SetRejectMessage("Only block references");
opts.AddAllowedClass(typeof(BlockReference), true);
PromptEntityResult pr = ed.GetEntity(opts);
if (pr.Status == PromptStatus.OK)
{
Transaction tr = doc.TransactionManager.StartTransaction();
using (tr)
{
BlockReference blockRef = tr.GetObject(pr.ObjectId, OpenMode.ForRead) as BlockReference;
BlockTableRecord bd = (BlockTableRecord)tr.GetObject(blockRef.BlockTableRecord, OpenMode.ForRead);
foreach (ObjectId adId in bd)
{
// ToDo: here you can handle entities inside the block definition
}
}
}
}