Put in a value after inserting block with attribute

Put in a value after inserting block with attribute

kebby70
Contributor Contributor
594 Views
4 Replies
Message 1 of 5

Put in a value after inserting block with attribute

kebby70
Contributor
Contributor

I'd like to put in a value after inserting block with attribute.

Attribute is Number.

Insert 5 block, each number is automatically increasing.

 

Below is my code.

Inserted block is success, I'dont know how to put in a value to attribute.

 

[CommandMethod("uuu", CommandFlags.NoHistory)]
public void BlockSimple()
{
Document acDoc = Application.DocumentManager.MdiActiveDocument;
Database acDocDb = acDoc.Database;
Editor acDocEd = acDoc.Editor;
Database workingDB = HostApplicationServices.WorkingDatabase;

string fpFile = @"C:\LIBRARY\FP_TEST.dwg";
string fpBlock = @"FP_TEST";

using (DocumentLock acLckDoc = acDoc.LockDocument())
{
using (Transaction acTrans = acDocDb.TransactionManager.StartTransaction())
{
Database db = null;
db = new Database(false, false);
db.ReadDwgFile(fpFile, System.IO.FileShare.Read, true, null);

ObjectId NewBlkId = new ObjectId();
NewBlkId = acDocDb.Insert(fpBlock, db, false);

BlockTable bt = (BlockTable)acTrans.GetObject(acDocDb.BlockTableId, OpenMode.ForWrite, true);
BlockTableRecord btr = (BlockTableRecord)acTrans.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite);
BlockReference blkRef = new BlockReference(new Autodesk.AutoCAD.Geometry.Point3d(0, 0, 0), NewBlkId);

btr.AppendEntity(blkRef);
acTrans.AddNewlyCreatedDBObject(blkRef, true);

AcadApplication acadApp = (AcadApplication)acApplication.Application.AcadApplication;
acadApp.ActiveDocument.SendCommand("_.ATTSYNC N " + fpBlock + "\n");
acDocEd.Regen();

db.Dispose();

acTrans.Commit();
}
}

}

0 Likes
Accepted solutions (1)
595 Views
4 Replies
Replies (4)
Message 2 of 5

norman.yuan
Mentor
Mentor
Accepted solution

Since your code create the block reference, you do not call "ATTSYNC" to add attribute. Instead, your code should create AttributeReference based on the BlockTableRecord. Following quick code does it:

 

[CommandMethod("UUU", ...)]

public static CreateBlock()

{

  Document acDoc = Application.DocumentManager.MdiActiveDocument;
  Database acDocDb = acDoc.Database;

  using (acDoc.LockDocument())

  {

    InsertBlock(acDocDb, "C:\\LIBRARY\\BlockFile.dwg");

  }

}

private static InsertBlock(Database docDb, string fileName)

{

  // create block definition from external block file

  ObjectId blockDefId=InsertBlockDefinition(docDb, fileName);

 

  // insert block reference

  using (var tran=db.TransactionManager.StartTransaction())

  {

     BlockTable bt = (BlockTable)acTrans.GetObject(acDocDb.BlockTableId, OpenMode.ForWrite, true);
     BlockTableRecord space =

           (BlockTableRecord)acTrans.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite);

    BlockTableRecord blockDef=

           (BlockTableRecord)tran.GetObject(blockDefId, OpenMode.ForRead)

    // create the block reference 5 times

    for int i=1; i<=5; i++)

    {

       var insPt=newPoint3d(0.0, i * 10.0, 0.0);

       InsertBlockReference(blockDef, insPt, space, tran, i);

    }

    tran.Commit();

  }

}

 

private ObjectId InsertBlockDefinition(Database docDb, string fileName)

{

  var id=ObjectId.Null;

  using (var db=new Datyabase(false, true))

  {

     db.ReadDwgFile(fileName,.......);

     id=docDb.Insert(

        System.IO.Path.GetFielNameWithoutExtension(fileName), db, false);

  }

  return id;

}

 

private static void InsertBlockReference(

             BlockTableRecord blockDef, Point3d insPt, BlockTableRecord space, Transaction tran, int num)

{

    var blockRef=new BlockTableRecord(insPt, blockDef.ObjectId);

    blockRef.SetDatabaseDefault();

    space.Append(blockRef);

    tran.AddNewlyCreatedDBObject(blockRef, true);

 

    // following code add attributereference to the block reference, based 

    // on block definition

   foreach (ObjectId id in blockDef)

   {

      var att=trans.GetObject(id, OpenMode.ForRead)  as AttributeDefinition;

      if (att!=null && !att.Constant)

      {

         var attRef=new AttributeReference();

         attRef.SetAttributeFromBlock(att, blockReference.BlockTransform);

         if (att.Tag.ToUpper()=="NUMBER") att.TextString=num.ToString();

         blockRef.AttributeCollection.Append(attRef);

         tran.AddNewlyCreatedDBObject(attRef, true);

      }

  }

}

 

The code is not tested, but you get the idea.

 

HTH.

Norman Yuan

Drive CAD With Code

EESignature

0 Likes
Message 3 of 5

kebby70
Contributor
Contributor

Thanks a lot for your code.

I tested and found that the first block is missing attribute value.

kebby70_0-1617403096399.png

 

[CommandMethod("UUU", CommandFlags.NoHistory)]
public void CreateBlock()
{
Document acDoc = Application.DocumentManager.MdiActiveDocument;
Database acDocDb = acDoc.Database;

using (acDoc.LockDocument())
{
InsertBlock(acDocDb, @"C:\LIBRARY\FP_J02-019.dwg");
}
}

private void InsertBlock(Database acDocDb, string fileName)
{
// create block definition from external block file
ObjectId blockDefId = InsertBlockDefinition(acDocDb, fileName);

// insert block reference
using (var acTrans = acDocDb.TransactionManager.StartTransaction())
{
BlockTable bt = (BlockTable)acTrans.GetObject(acDocDb.BlockTableId, OpenMode.ForWrite, true);
BlockTableRecord space = (BlockTableRecord)acTrans.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite);
BlockTableRecord blockDef = (BlockTableRecord)acTrans.GetObject(blockDefId, OpenMode.ForWrite);

// create the block reference 5 times
for (int i = 1; i <= 5; i++)
{
var insPt = new Point3d(-20.0, i * 20.0, 0.0);
InsertBlockReference(blockDef, insPt, space, acTrans, i);
}
acTrans.Commit();
}
}

private ObjectId InsertBlockDefinition(Database docDb, string fileName)
{
var id = ObjectId.Null;

using (var db = new Database(false, true))
{
db.ReadDwgFile(fileName, System.IO.FileShare.Read, true, null);
id = docDb.Insert(System.IO.Path.GetFileNameWithoutExtension(fileName), db, false);
}

return id;
}

private static void InsertBlockReference(BlockTableRecord blockDef, Point3d insPt, BlockTableRecord space, Transaction acTrans, int num)
{
var blockRef = new BlockReference(insPt, blockDef.ObjectId);

blockRef.SetDatabaseDefaults();
space.AppendEntity(blockRef);
acTrans.AddNewlyCreatedDBObject(blockRef, true);

// following code add attributereference to the block reference, based
// on block definition
foreach (ObjectId id in blockDef)
{
var att = acTrans.GetObject(id, OpenMode.ForWrite) as AttributeDefinition;

if (att != null && !att.Constant)
{
var attRef = new AttributeReference();

attRef.SetAttributeFromBlock(att, blockRef.BlockTransform);

if (att.Tag.ToUpper() == "LOC") att.TextString = num.ToString();
if (att.Tag.ToUpper() == "INST") att.TextString = "ITB";

blockRef.AttributeCollection.AppendAttribute(attRef);

acTrans.AddNewlyCreatedDBObject(attRef, true);
}
}
}

0 Likes
Message 4 of 5

norman.yuan
Mentor
Mentor

Well, if you step through the code in debug with break point in the method InsertBlockReference(), it would be quite easy to find out why the fifth block's attributes are not added, or added but its TextString not set.

 

Norman Yuan

Drive CAD With Code

EESignature

0 Likes
Message 5 of 5

kebby70
Contributor
Contributor

Thanks....I've resolved..

Changed to attRef

 

if (attRef.Tag.ToUpper() == "LOC") attRef.TextString = num.ToString();
if (attRef.Tag.ToUpper() == "INST") attRef.TextString = "ITB";

 

0 Likes