.NET
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

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

11 REPLIES 11
SOLVED
Reply
Message 1 of 12
vasantpadhiyar71
3521 Views, 11 Replies

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

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
Tags (1)
11 REPLIES 11
Message 2 of 12
Artvegas
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
Message 3 of 12
cadMeUp
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.

 

 

 

 

Message 4 of 12
Artvegas
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.

Message 5 of 12
adadnet
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

Message 6 of 12
vince1327
in reply to: adadnet

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 😉

 

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;
    }
  }

        

 

Message 7 of 12

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
Message 8 of 12

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

Message 9 of 12

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
Message 10 of 12
vasantpadhiyar71
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
Message 11 of 12
Artvegas
in reply to: vasantpadhiyar71

That's the formula you'll see in the fields dialog, but it's easiest just to use the fields dialog as noted by FFlix above. You can learn more about text fields in the AutoCAD user guide. They are extremely useful and worth knowing.

 

The easiest way I can think to describe this to you, is to run you through how you might set up a field for your custom property (without any code):-

 

1. Create a new drawing.

2. Run DWGPROPS to open the drawing properties dialog.

3. Go the the custom tab and add a custom property, for example:
    Name = ProjectName
    Value = Ground Floor Plan.

4. Exit the dialog.

5. Create a text entity using TEXT or MTEXT, and while the text cursor is still active, right-click and choose Insert Field (shortcut Ctrl +F). This will open the Field dialog.

6. In the Field category dropdown choose Document, and in the Field names list you should see your custom property name (i.e. ProjectName). Select it and then pick a Format if applicable. Click the OK button to exit the dialog.

 

You should now see your custom property value (i.e. Ground Floor Plan) in the field you created. This will be automatically updated if you change the custom property value (note though that you have to REGEN to see field changes take effect).

 

You can add fields to both text and mtext entities. And you can even add them to block attributes by right-clicking and selecting Insert Field in the relevant dialog text boxes. Where you place them all depends on how you prefer to setup your drawings.

 

If you have a title block, I would just add text or mtext with fields directly to the block rather than get into attributes, but it's really up to you.

 

Art

Message 12 of 12
vasantpadhiyar71
in reply to: Artvegas

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;
    }
  }

Vasant PADHIYAR

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk DevCon in Munich May 28-29th


Autodesk Design & Make Report

”Boost