Author Topic: Block References, Attributes, and Attribute Synchronization  (Read 1549 times)

0 Members and 1 Guest are viewing this topic.

Keith Brown

  • Swamp Rat
  • Posts: 601
I have an application where I am inserting block references into a paperspace into a side database.  If the block reference contains certain attributes then I am populating the attributes with calculated text.  The issue that I am having is that the text is not formatting properly.  The attributes are set to be center justified but the resulting attribute is not.  After running the routine I open up the created drawing and select the attribute.  The text says that it is center justified but it is not displayed that way.  I can do an attribute sync at the command line and the text will snap into its correct location.


So I thought that I would just need to synchronize the attributes in code.  Using giles brute force method here.  Unfortunately it does not correct the incorrect justification.  I can follow the code through and see that it is setting the position of the text correctly.


I have followed the instructions in this post and followed all links about as far as you can go but without much success.  Here is the code that I am using to add my attributes to a block reference.

Code - C#: [Select]
  1. public static void AddAttributeReferences(this BlockReference blockReference, Dictionary<string, string> attributeValues)
  2. {
  3.         if (blockReference == null)
  4.         {
  5.                 throw new ArgumentNullException("blockReference");
  6.         }
  7.  
  8.  
  9.         var transaction = blockReference.Database.TransactionManager.TopTransaction;
  10.         if (transaction == null)
  11.         {
  12.                 throw new AcRx.Exception(ErrorStatus.NoActiveTransactions);
  13.         }
  14.  
  15.  
  16.         var blockTableRecord = blockReference.BlockTableRecord.GetObject<BlockTableRecord>();
  17.         var database = blockReference.Database;
  18.  
  19.  
  20.         foreach (var objectId in blockTableRecord)
  21.         {
  22.                 if (objectId.ObjectClass != GlobalAcad.AttributeDefinitionClass)
  23.                 {
  24.                         continue;
  25.                 }
  26.  
  27.  
  28.                 using (new WorkingDatabaseSwitcher(database))
  29.                 {
  30.                         var attributeDefinition = objectId.GetObject<AttributeDefinition>();
  31.                         var attributeReference = new AttributeReference();
  32.                         attributeReference.SetDatabaseDefaults(database);
  33.                         attributeReference.SetAttributeFromBlock(attributeDefinition, blockReference.BlockTransform);
  34.                         if (attributeValues != null && attributeValues.ContainsKey(attributeDefinition.Tag.ToUpper()))
  35.                         {
  36.                                 if (attributeReference.IsMTextAttribute)
  37.                                 {
  38.                                         attributeReference.MTextAttribute.Contents = attributeValues[attributeDefinition.Tag];
  39.                                 }
  40.                                 else
  41.                                 {
  42.                                         attributeReference.TextString = attributeValues[attributeDefinition.Tag];
  43.                                 }
  44.  
  45.  
  46.                                 if (attributeDefinition.Justify != AttachmentPoint.BaseLeft)
  47.                                 {
  48.                                         attributeReference.AlignmentPoint = attributeDefinition.AlignmentPoint.TransformBy(blockReference.BlockTransform);
  49.                                         attributeReference.AdjustAlignment(database);
  50.                                 }
  51.                         }
  52.  
  53.  
  54.                         blockReference.AttributeCollection.AppendAttribute(attributeReference);
  55.                         transaction.AddNewlyCreatedDBObject(attributeReference, true);
  56.                 }
  57.         }
  58. }


I have tried many different possiblities including trying to set the position, etc.  Everything I have read however states that you just need to set the alignment point and then make a call to AdjustAlignment.  This works in other applications where I am using the active document but for some reason I cannot get it to work in a side database.  Anyone have any additional ideas?
Keith Brown | AutoCAD MEP Blog | RSS Feed
AutoCAD MEP 2014 / Revit MEP 2014 / EastCoast CAD/CAM addon / Visual Studio 2013

Keith Brown

  • Swamp Rat
  • Posts: 601
Re: Block References, Attributes, and Attribute Synchronization
« Reply #1 on: July 27, 2015, 02:41:06 PM »
Well as usual about 5 minutes after posting this issue I have been working on for about 2 days I figured it out.  I had previously wrote a attribute sync method to try and get the attributes to sync up but had the same issue.  After making changes to my attribute insertion code I had forgotten to make the changes to my sync code.  So I was properly inserting the attributes and they would center up nicely but then when the synchronization code ran it would move them back to the wrong spot.  Once i updated the sync code and removed it from this application (it was no longer needed) everything worked as expected.  (Working in side databases can be a pain sometimes)


For anyone interested in the sync code I started with Giles code from here.  I made some modifications for it to work with a side database and justifications other then left center and ended up with the code below.


The original block reference add attribute insert code and the attribute sync code.
Code - C#: [Select]
  1. /// <summary>
  2. ///     Adds attribute references to the block reference.
  3. /// </summary>
  4. /// <param name="blockReference">The block reference to add to.</param>
  5. /// <param name="attributeValues">The attribute values.</param>
  6. /// <exception cref="System.ArgumentNullException">
  7. /// If the BlockTableRecord is null.
  8. /// </exception>
  9. /// <exception cref="Autodesk.AutoCAD.Runtime.Exception">
  10. /// If there are no active transactions.
  11. /// </exception>
  12. public static void AddAttributeReferences(this BlockReference blockReference, Dictionary<string, string> attributeValues)
  13. {
  14.         if (blockReference == null)
  15.         {
  16.                 throw new ArgumentNullException("blockReference");
  17.         }
  18.  
  19.  
  20.         var database = blockReference.Database;
  21.         var transaction = database.TransactionManager.TopTransaction;
  22.         if (transaction == null)
  23.         {
  24.                 throw new AcRx.Exception(ErrorStatus.NoActiveTransactions);
  25.         }
  26.  
  27.  
  28.         var blockTableRecord = blockReference.BlockTableRecord.GetObject<BlockTableRecord>();
  29.  
  30.  
  31.         foreach (var objectId in blockTableRecord)
  32.         {
  33.                 if (objectId.ObjectClass != GlobalAcad.AttributeDefinitionClass)
  34.                 {
  35.                         continue;
  36.                 }
  37.                
  38.                 var attributeDefinition = objectId.GetObject<AttributeDefinition>();
  39.                 var attributeReference = new AttributeReference();
  40.                 attributeReference.SetDatabaseDefaults(database);
  41.                 attributeReference.SetAttributeFromBlock(attributeDefinition, blockReference.BlockTransform);
  42.                 if (attributeValues != null && attributeValues.ContainsKey(attributeDefinition.Tag.ToUpper()))
  43.                 {
  44.                         if (attributeReference.IsMTextAttribute)
  45.                         {
  46.                                 attributeReference.MTextAttribute.Contents = attributeValues[attributeDefinition.Tag];
  47.                         }
  48.                         else
  49.                         {
  50.                                 attributeReference.TextString = attributeValues[attributeDefinition.Tag];
  51.                         }
  52.  
  53.  
  54.                         if (attributeDefinition.Justify != AttachmentPoint.BaseLeft)
  55.                         {
  56.                                 using (new WorkingDatabaseSwitcher(database))
  57.                                 {
  58.                                         attributeReference.AlignmentPoint = attributeDefinition.AlignmentPoint.TransformBy(blockReference.BlockTransform);
  59.                                         attributeReference.AdjustAlignment(database);
  60.                                 }
  61.                         }
  62.                 }
  63.  
  64.  
  65.                 blockReference.AttributeCollection.AppendAttribute(attributeReference);
  66.                 transaction.AddNewlyCreatedDBObject(attributeReference, true);
  67.         }
  68. }
  69.  
  70.  
  71. /// <summary>
  72. ///     Resets the attributes on a block reference.
  73. /// </summary>
  74. /// <param name="blockReference">The block reference.</param>
  75. /// <param name="attributeDefinitions">
  76. /// The attribute definitions to reset.
  77. /// </param>
  78. public static void ResetAttributes(this BlockReference blockReference, List<AttributeDefinition> attributeDefinitions)
  79. {
  80.         if (blockReference == null)
  81.         {
  82.                 throw new ArgumentNullException("blockReference");
  83.         }
  84.         var database = blockReference.Database;
  85.         var transaction = database.TransactionManager.TopTransaction;
  86.         if (transaction == null)
  87.         {
  88.                 throw new AcRx.Exception(ErrorStatus.NoActiveTransactions);
  89.         }
  90.  
  91.  
  92.         var attributeValues = new Dictionary<string, string>();
  93.         foreach (ObjectId objectId in blockReference.AttributeCollection)
  94.         {
  95.                 if (!objectId.IsErased)
  96.                 {
  97.                         var attributeReference = objectId.GetObject<AttributeReference>(OpenMode.ForWrite);
  98.                         attributeValues.Add(attributeReference.Tag, attributeReference.IsMTextAttribute ? attributeReference.MTextAttribute.Contents : attributeReference.TextString);
  99.                         attributeReference.Erase();
  100.                 }
  101.         }
  102.  
  103.  
  104.         foreach (var attributeDefinition in attributeDefinitions)
  105.         {
  106.                 var attributeReference = new AttributeReference();
  107.                 attributeReference.SetAttributeFromBlock(attributeDefinition, blockReference.BlockTransform);
  108.                 if (attributeValues.ContainsKey(attributeDefinition.Tag))
  109.                 {
  110.                         if (attributeReference.IsMTextAttribute)
  111.                         {
  112.                                 attributeReference.MTextAttribute.Contents = attributeValues[attributeDefinition.Tag];
  113.                         }
  114.                         else
  115.                         {
  116.                                 attributeReference.TextString = attributeValues[attributeDefinition.Tag];
  117.                         }
  118.  
  119.  
  120.  
  121.  
  122.                         if (attributeDefinition.Justify != AttachmentPoint.BaseLeft)
  123.                         {
  124.                                 using (new WorkingDatabaseSwitcher(database))
  125.                                 {
  126.                                         attributeReference.AlignmentPoint = attributeDefinition.AlignmentPoint.TransformBy(blockReference.BlockTransform);
  127.                                         attributeReference.AdjustAlignment(database);
  128.                                 }
  129.                         }
  130.                 }
  131.  
  132.  
  133.                 blockReference.AttributeCollection.AppendAttribute(attributeReference);
  134.                 transaction.AddNewlyCreatedDBObject(attributeReference, true);
  135.         }
  136. }
Keith Brown | AutoCAD MEP Blog | RSS Feed
AutoCAD MEP 2014 / Revit MEP 2014 / EastCoast CAD/CAM addon / Visual Studio 2013

Jeff H

  • Needs a day job
  • Posts: 6150
Re: Block References, Attributes, and Attribute Synchronization
« Reply #2 on: July 27, 2015, 04:27:42 PM »
Sounds like you need a rubby ducky to talk to.

Keith Brown

  • Swamp Rat
  • Posts: 601
Re: Block References, Attributes, and Attribute Synchronization
« Reply #3 on: July 27, 2015, 04:34:49 PM »
The sad thing is that i gave one to all of my coworkers last Christmas.  In my defense I did talk it out with myself and a couple workers last week and this morning but could come up with nothing.
Keith Brown | AutoCAD MEP Blog | RSS Feed
AutoCAD MEP 2014 / Revit MEP 2014 / EastCoast CAD/CAM addon / Visual Studio 2013