.NET

.NET

Reply
Contributor
vasantpadhiyar71
Posts: 23
Registered: ‎05-25-2012
Message 1 of 12 (983 Views)
Accepted Solution

How to Set File Property to Layout Title Block using C#

983 Views, 11 Replies
05-30-2012 11:10 PM

Hi Experts,

 

I am setting the Custom Properties on a CAD File. The Properties may include "Drawing Number, DrawingName, ProjectName"...

Now using code I want to fetch values of these Properties and set into Layout Title Block.

Is it possible??

 

Thanks,

Vasant PADHIYAR

Thanks all for your valuable Suggestion.....

 

Finally I got the Solution using Block Attributes:

 

Before editing anything Locking the Document can Solve All Issues:

 

The Code is As:

 

public class TITLEBLOCK
    {
        
        [Autodesk.AutoCAD.Runtime.CommandMethod("TITLEBLOCK1")]

        public void TitleBlock1Command(string projectname)
        {

      Document doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
      Database db = doc.Database;
      Editor ed = doc.Editor;
      


       string blockName = "COMPBLK";
       string attbName = "PROJECT-NAME";
       string attbValue = projectname;
       

      UpdateAttributesInDatabase(
        db,
        blockName,
        attbName,
        attbValue
        

      );
    }

    private void UpdateAttributesInDatabase(
      Database db,
      string blockName,
      string attbName,
      string attbValue
     
    )
    {
      Document doc =
        Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
      Editor ed = doc.Editor;

      // Get the IDs of the spaces we want to process
      // and simply call a function to process each

      ObjectId msId, psId;
      Transaction tr = db.TransactionManager.StartTransaction();
      
      using (tr)
      {
        BlockTable bt =
          (BlockTable)tr.GetObject(
            db.BlockTableId,
            OpenMode.ForRead
          );
        msId =
          bt[BlockTableRecord.ModelSpace];
        psId =
          bt[BlockTableRecord.PaperSpace];

        // Not needed, but quicker than aborting
        tr.Commit();
      }
      int msCount =
        UpdateAttributesInBlock(
          msId,
          blockName,
          attbName,
          attbValue         
              
        );
      int psCount =
        UpdateAttributesInBlock(
          psId,
          blockName,
          attbName,
          attbValue
        
        );
      ed.Regen();

      // Display the results

      ed.WriteMessage(
        "\nProcessing file: " + db.Filename
      );
      ed.WriteMessage(
        "\nUpdated {0} attribute{1} of CHTITLEBLOCK in the modelspace.",
        msCount,
        msCount == 1 ? "" : "s",
        attbName
      );
      ed.WriteMessage(
        "\nUpdated {0} attribute{1} of CHTITLEBLOCK in the default paperspace.",
        psCount,
        psCount == 1 ? "" : "s",
        attbName
      );
    }

    private int UpdateAttributesInBlock(
      ObjectId btrId,
      string blockName,
      string attbName,
      string attbValue
     
    )
    {
      // Will return the number of attributes modified

      int changedCount = 0;
      Document doc =
        Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
        DocumentLock doclock = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.LockDocument();
      Database db = doc.Database;
      Editor ed = doc.Editor;

      Transaction tr =
        doc.TransactionManager.StartTransaction();
      using (tr)
      {
        BlockTableRecord btr =
          (BlockTableRecord)tr.GetObject(btrId, OpenMode.ForRead);

        // Test each entity in the container...
        using (DocumentLock acLckDoc = doc.LockDocument())
        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
              );

              // ... to see whether it's a block with
              // the name we're after

              if (bd.Name.ToUpper() == blockName)
              {

                // Check each of the attributes...

                foreach (
                  ObjectId arId in br.AttributeCollection
                )
                {
                  DBObject obj =
                    tr.GetObject(
                      arId,
                      OpenMode.ForRead
                    );
                  AttributeReference ar =
                    obj as AttributeReference;
                  if (ar != null)
                  {
                    // ... to see whether it has
                    // the tag we're after

                    if (ar.Tag.ToUpper() == attbName)
                    {
                      // If so, update the value
                      // and increment the counter

                      ar.UpgradeOpen();
                      ar.TextString = attbValue;
                      ar.DowngradeOpen();
                      changedCount++;
                    }
                                     
                   
                  }
                }
              }

              // Recurse for nested blocks
              changedCount +=
                UpdateAttributesInBlock(
                  br.BlockTableRecord,
                  blockName,
                  attbName,
                  attbValue
                 
                );
            }
          }
        }
        tr.Commit();
        tr.Dispose();
      }
      doclock.Dispose();
      return changedCount;
    }
  }

Distinguished Contributor
Artvegas
Posts: 104
Registered: ‎04-21-2011
Message 2 of 12 (974 Views)

Re: How to Set File Property to Layout Title Block using C#

05-31-2012 01:59 AM in reply to: vasantpadhiyar71
Have you considered using the sheet set manager for this? You can add custom properties to your sheets and have text fields in your title blocks that automatically reflect your custom properties. To do this programatically can get complicated as you need to use the sheet set object COM interop library. If not then perhaps you can write some code to manually retrieve your custom data and then add /update text entities in your block title. Perhaps using block attributes as outlined here: http://through-the-interface.typepad.com/through_the_interface/2007/07/updating-a-spec.html
Valued Mentor
cadMeUp
Posts: 331
Registered: ‎05-11-2006
Message 3 of 12 (959 Views)

Re: How to Set File Property to Layout Title Block using C#

05-31-2012 08:22 AM in reply to: vasantpadhiyar71

You can use fields to link to custom file property values,

using fields would be the best way for this, but you could automate it to fill in the values thru code too...

 

You might look into using the following classes:

 

Autodesk.AutoCAD.DatabaseServices.DatabaseSummaryInfo Autodesk.AutoCAD.DatabaseServices.DatabaseSummaryInfoBuilder Autodesk.AutoCAD.Interop.Common.AcadSummaryInfoClass

 

and the 'SummaryInfo' property of the Autodesk.AutoCAD.DatabaseServices.Database class.

 

 

 

 

Distinguished Contributor
Artvegas
Posts: 104
Registered: ‎04-21-2011
Message 4 of 12 (952 Views)

Re: How to Set File Property to Layout Title Block using C#

05-31-2012 08:53 AM in reply to: cadMeUp

Great suggestion from cadMeUp.

 

If you run DWGPROPS you'll see the standard info you can store in a drawing (Summary tab). You can also add custom properties (Custom tab).

 

Custom drawing properties seem really cool. You can reference custom properties in text fields. For example:

%<\AcVar MyCustomPropertyName>%

 

So if you store your data there you can set up your title block to automatically show standard and custom data.

Valued Contributor
FFlix
Posts: 95
Registered: ‎11-15-2011
Message 5 of 12 (942 Views)

Re: How to Set File Property to Layout Title Block using C#

05-31-2012 09:29 AM in reply to: vasantpadhiyar71

as an extension to art's example, initiate creating a field in acad gives you an idea of what's available in terms of field names and formats while at the same time showing the associated 'field expression'. e.g. this expression as string value makes a field

Distinguished Contributor
vince1327
Posts: 117
Registered: ‎11-02-2011
Message 6 of 12 (929 Views)

Re: How to Set File Property to Layout Title Block using C#

05-31-2012 01:55 PM in reply to: FFlix

Try this:

 

Make sure you define your blockname in the beginning in "string blockname" and make sure your attributes are correct. This is what i use. The argument "projectname" is just a string from a form, configure that however you want. 

 

Hope this helps :smileywink:

 

public class TITLEBLOCK
    {
        
        [Autodesk.AutoCAD.Runtime.CommandMethod("TITLEBLOCK1")]

        public void TitleBlock1Command(string projectname)
        {

      Document doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
      Database db = doc.Database;
      Editor ed = doc.Editor;
      


       string blockName = "COMPBLK";
       string attbName = "PROJECT-NAME";
       string attbValue = projectname;
       

      UpdateAttributesInDatabase(
        db,
        blockName,
        attbName,
        attbValue
        

      );
    }

    private void UpdateAttributesInDatabase(
      Database db,
      string blockName,
      string attbName,
      string attbValue
     
    )
    {
      Document doc =
        Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
      Editor ed = doc.Editor;

      // Get the IDs of the spaces we want to process
      // and simply call a function to process each

      ObjectId msId, psId;
      Transaction tr = db.TransactionManager.StartTransaction();
      
      using (tr)
      {
        BlockTable bt =
          (BlockTable)tr.GetObject(
            db.BlockTableId,
            OpenMode.ForRead
          );
        msId =
          bt[BlockTableRecord.ModelSpace];
        psId =
          bt[BlockTableRecord.PaperSpace];

        // Not needed, but quicker than aborting
        tr.Commit();
      }
      int msCount =
        UpdateAttributesInBlock(
          msId,
          blockName,
          attbName,
          attbValue         
              
        );
      int psCount =
        UpdateAttributesInBlock(
          psId,
          blockName,
          attbName,
          attbValue
        
        );
      ed.Regen();

      // Display the results

      ed.WriteMessage(
        "\nProcessing file: " + db.Filename
      );
      ed.WriteMessage(
        "\nUpdated {0} attribute{1} of CHTITLEBLOCK in the modelspace.",
        msCount,
        msCount == 1 ? "" : "s",
        attbName 
      );
      ed.WriteMessage(
        "\nUpdated {0} attribute{1} of CHTITLEBLOCK in the default paperspace.",
        psCount,
        psCount == 1 ? "" : "s",
        attbName 
      );
    }

    private int UpdateAttributesInBlock(
      ObjectId btrId,
      string blockName,
      string attbName,
      string attbValue
     
    )
    {
      // Will return the number of attributes modified

      int changedCount = 0;
      Document doc =
        Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
      Database db = doc.Database;
      Editor ed = doc.Editor;

      Transaction tr =
        doc.TransactionManager.StartTransaction();
      using (tr)
      {
        BlockTableRecord btr =
          (BlockTableRecord)tr.GetObject(btrId, OpenMode.ForRead);

        // Test each entity in the container...
        using (DocumentLock acLckDoc = doc.LockDocument())
        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
              );

              // ... to see whether it's a block with
              // the name we're after

              if (bd.Name.ToUpper() == blockName)
              {

                // Check each of the attributes...

                foreach (
                  ObjectId arId in br.AttributeCollection
                )
                {
                  DBObject obj =
                    tr.GetObject(
                      arId,
                      OpenMode.ForRead
                    );
                  AttributeReference ar =
                    obj as AttributeReference;
                  if (ar != null)
                  {
                    // ... to see whether it has
                    // the tag we're after

                    if (ar.Tag.ToUpper() == attbName)
                    {
                      // If so, update the value
                      // and increment the counter

                      ar.UpgradeOpen();
                      ar.TextString = attbValue;
                      ar.DowngradeOpen();
                      changedCount++;
                    }
                                     
                   
                  }
                }
              }

              // Recurse for nested blocks
              changedCount +=
                UpdateAttributesInBlock(
                  br.BlockTableRecord,
                  blockName,
                  attbName,
                  attbValue
                 
                );
            }
          }
        }
        tr.Commit();
        tr.Dispose();
      }
      return changedCount;
    }
  }

        

 

Contributor
vasantpadhiyar71
Posts: 23
Registered: ‎05-25-2012
Message 7 of 12 (914 Views)

Re: How to Set File Property to Layout Title Block using C#

05-31-2012 11:25 PM in reply to: vince1327

Thanks all for your Innovative Ideas......

 

Hi Vince,

 

Using CommandMethod in already opened drawing it works fine but.....
I am running this Code while Opening the Drawing in AutoCAD. When this Code runs I am getting a RunTime Error: "eLockViolation".
The Snapof this Error is attached with this Post.
Please suggest Appropriate Solution for this.

 

Thanks & Regards,

Vasant PADHIYAR
Distinguished Contributor
vince1327
Posts: 117
Registered: ‎11-02-2011
Message 8 of 12 (896 Views)

Re: How to Set File Property to Layout Title Block using C#

06-01-2012 05:38 AM in reply to: vasantpadhiyar71

Depending on how you're running it, it seems like you may need to ensure that the document is locked properly. At what point is it crashing, what line?

 

Cheers

Vince

Contributor
vasantpadhiyar71
Posts: 23
Registered: ‎05-25-2012
Message 9 of 12 (881 Views)

Re: How to Set File Property to Layout Title Block using C#

06-01-2012 10:09 PM in reply to: vince1327

Hello Vince,

 

My System Crashed at following Code:

ar.UpgradeOpen();
ar.TextString = drawingAttrs["drawingnumber"].ToString();
ar.DowngradeOpen();

 

When I try to show message using line:

MessageBox.Show("IsWriteEnabled:" + ar.IsWriteEnabled.ToString());

Then I am getting Response as FALSE.

 

How can I solve it.

Any help will be appreciated....

Thanks,

Vasant PADHIYAR
Contributor
vasantpadhiyar71
Posts: 23
Registered: ‎05-25-2012
Message 10 of 12 (878 Views)

Re: How to Set File Property to Layout Title Block using C#

06-01-2012 10:19 PM in reply to: Artvegas

Hello Art,

 

How Can I link my Custom Property into TitleBlock Attribute using:

%<\AcVar MyCustomPropertyName>%

 

Where I have to write this Code? Means in Block Editor whether I have to write this code in Default value?

 

Thanks a lot for Help....

Vasant PADHIYAR
Post to the Community

Have questions about Autodesk products? Ask the community.

New Post
Announcements
Do you have 60 seconds to spare? The Autodesk Community Team is revamping our site ranking system and we want your feedback! Please click here to launch the 5 question survey. As always your input is greatly appreciated.