Change Attribute Tags together

Change Attribute Tags together

yoitsarun
Advocate Advocate
1,123 Views
5 Replies
Message 1 of 6

Change Attribute Tags together

yoitsarun
Advocate
Advocate

I have code to change attribute tag text value. It is working fine. 

But i want to change another tag in the same block attribute.

that is , if i change 1st tag then 2nd tag also should be updated automatically.

Is there any way to do that??

using (tr)
                {
                    BlockTableRecord btr =(BlockTableRecord)tr.GetObject(btrId,OpenMode.ForRead);                    
                    foreach (ObjectId entId in btr)
                    {
                        Entity ent =tr.GetObject(entId, OpenMode.ForRead)as Entity;
                        if (ent != null)
                        {
                            BlockReference br = ent as BlockReference;
                            if (br != null)
                            {
                                BlockTableRecord bd =(BlockTableRecord)tr.GetObject(br.BlockTableRecord,OpenMode.ForRead);                                
                                if (bd.Name.ToUpper() == blockName)
                                {                                    
                                    foreach (ObjectId arId in br.AttributeCollection)
                                    {
                                        DBObject obj =tr.GetObject(arId,OpenMode.ForRead);
                                        AttributeReference ar =obj as AttributeReference;
                                        if (ar != null)
                                        {
                                        if (ar.Tag.ToUpper() == attbName)
                                        {                                            
                                                //if (ar.TextString == "A") then i need to change another Tag
                                                
                                            ar.UpgradeOpen();
                                            ar.TextString = "B";
                                            ar.DowngradeOpen();                                            
                                        }

 

//if (ar.TextString == "A") then i need to change another Tag

 

How i could do this while on another tag? Any suggestions

0 Likes
Accepted solutions (2)
1,124 Views
5 Replies
Replies (5)
Message 2 of 6

norman.yuan
Mentor
Mentor
Accepted solution

You can simply loop through the AttributeCollection twice: the first time, find the first attribute, if found update its value and break the loop. Then you do the loop again to find the second attribute and update it accordingly. Something like:

 

bool found=false;

foreach (ObjectId id in br.AttributeCollection)

{

  var att=(AttributeReference)tr.GetObject(id, OpenMode.ForRead);

  if (att.Tag.ToUpper()=="A")

  {

    att.UpgradeOpen();

    att.TextString="xxxxxxx";

    found=true;

    break;

  }

}

 

if (found)

{

  foreach (ObjectId id in br.AttributeCollection)

  {

    var att=(AttributeReference)tr.GetObject(id, OpenMode.ForRead);

    if (att.Tag.ToUpper()=="B")

    {

       '' Update it here

       break;

    }

  }

}

 

Or, you can loop through it once to find both attributes and update one or both later:

 

AttributeReference attA=null;

AttributeReference attB=null;

foreach (ObjectId id in br.AttributeCollection)

{

  var att=(AttributeReference)tr.GetObject(id, OpenMode.ForRead);

  if (att.Tag.ToUpper()=="A") attA=att;

  if (att.Tag.ToUpper()=="B") attB=att;

}

 

if (attA!=null)

{

  attA.UpgradeOpen();

  attA.TextString="xxxxxxx";

  if (attB!=null)

  {

    attB.UpgradeOpen();

    attB.TextString="yyyyyy";

  }

}

 

HTH

Norman Yuan

Drive CAD With Code

EESignature

Message 3 of 6

yoitsarun
Advocate
Advocate

Thanks Norman,

I will try this.

0 Likes
Message 4 of 6

micle.space
Enthusiast
Enthusiast
Accepted solution

Hi Aruntr

I developed a method for writing the attributes in all blocks of a dwg file.

The new values of attribute's tag are  collected in a dictionary <TAG, Value>

 

This method searches in all paper spaces (if your dwg file has more then one drawing), for all blocks (but you can specify the name of blocks and enter in the last foreach just for the blocks you need).

Hope this can help you.

 

 

public static void WriteAttributes(string fileName, Dictionary<string, string> drawingsData)
{
	if (!File.Exists(fileName)) return;
	try
	{
		using (var db = OpenSideDatabase(fileName))
		{
			using (Transaction tr = db.TransactionManager.StartOpenCloseTransaction())
			{ 

				//all papers
				var dic = (DBDictionary)tr.GetObject(db.LayoutDictionaryId, OpenMode.ForRead);

				foreach (DBDictionaryEntry entry in dic)
				{
					//get the layout
					Layout layout = tr.GetObject(entry.Value, OpenMode.ForRead) as Layout;
					
					//jump if is modelSpace
					if (layout.ModelType) continue;
					
					BlockTableRecord btr = tr.GetObject(layout.BlockTableRecordId, OpenMode.ForRead) as BlockTableRecord;
					foreach (ObjectId id in btr)
					{
						Entity ent = tr.GetObject(id, OpenMode.ForRead) as Entity;
						if (ent == null) continue;

						BlockReference br = ent as BlockReference;
						if (br == null) continue;

						BlockTableRecord bd = (BlockTableRecord)tr.GetObject(br.BlockTableRecord, OpenMode.ForRead);
					   
						foreach (ObjectId arId in br.AttributeCollection)
						{
							AttributeReference ar = tr.GetObject(arId, OpenMode.ForRead) as AttributeReference;
							if (ar == null) continue;

							ar.UpgradeOpen();
							
							//instead of switch could be:
							// ar.TextString = drawingsData[ar.Tag];
							// better drawingsData.TryGetValue(...)
							
							switch (ar.Tag)
							{
								case "TAG1":
									ar.TextString = drawingsData["TAG1"];
									break;
								//other cases
								case....
								default:
									break;
							}
							ar.DowngradeOpen();
						}
					}

				}
			 
			}
			db.SaveAs(fileName, true, DwgVersion.Current, null);
		}
	}
	catch (System.Exception ex)
	{
		//messages...
	}
}

 

0 Likes
Message 5 of 6

yoitsarun
Advocate
Advocate

Thanks Micle,

i will try this, but my case is different.

I want to change the value of 2nd attribute if the 1st attribute value meets the criteria.

For example if Rev tag is A then i want to change it to B and also need to change the Date tag to the new Date.

I think Norman code is what i was looking for.

0 Likes
Message 6 of 6

micle.space
Enthusiast
Enthusiast

Norman could hardly be wrong...

0 Likes