Author Topic: Update the numbering of Sheets in the Sheet Set.  (Read 6107 times)

0 Members and 1 Guest are viewing this topic.

Andrey Bushman

  • Swamp Rat
  • Posts: 864
Update the numbering of Sheets in the Sheet Set.
« on: November 13, 2013, 07:16:22 AM »
I need update the numbering of Sheets in the Sheet Set. My code:

Code - C#: [Select]
  1. /*
  2.  * © Andrey Bushman, 2013
  3.  * AutoCAD 2014 x64 Enu
  4.  *
  5.  * AutoCAD references:
  6.  *
  7.  * AcCoreMgd.dll
  8.  * AcDbMgd.dll
  9.  * AcMgd.dll
  10.  * Interop.ACSMCOMPONENTS19Lib.dll
  11.  */
  12. using System;
  13. using System.Collections.Generic;
  14. using System.Linq;
  15. using System.Text;
  16.  
  17. using cad = Autodesk.AutoCAD.ApplicationServices.Application;
  18. using App = Autodesk.AutoCAD.ApplicationServices;
  19. using Db = Autodesk.AutoCAD.DatabaseServices;
  20. using Ed = Autodesk.AutoCAD.EditorInput;
  21. using Rtm = Autodesk.AutoCAD.Runtime;
  22. using Comp = ACSMCOMPONENTS19Lib;
  23.  
  24. [assembly: Rtm.CommandClass(typeof(Bushman.AutoCAD.SheetSetEditor.Commands))]
  25.  
  26. namespace Bushman.AutoCAD.SheetSetEditor {
  27.  
  28.     public class Commands {
  29.  
  30.         const String ns = "bush"; // namespace
  31.  
  32.         [Rtm.CommandMethod(ns, "test", Rtm.CommandFlags.Modal)]
  33.         public void Renumber() {
  34.             App.Document doc = cad.DocumentManager.MdiActiveDocument;
  35.             Db.Database db = doc.Database;
  36.             Ed.Editor ed = doc.Editor;
  37.             Comp.AcSmSheetSetMgr mng = new Comp.AcSmSheetSetMgr();
  38.             Comp.IAcSmEnumDatabase enumerator = mng.GetDatabaseEnumerator();
  39.             Comp.AcSmDatabase smDb = null;
  40.             while ((smDb = enumerator.Next()) != null) {
  41.                 String fname = smDb.GetFileName();
  42.                 Comp.AcSmSheetSet sheetset = smDb.GetSheetSet();
  43.                 String name = sheetset.GetName();
  44.                 String descr = sheetset.GetDesc();
  45.                 ed.WriteMessage("\nSheet Set: {0}\n", name);
  46.                 Comp.IAcSmEnumComponent encomp = sheetset.GetSheetEnumerator();
  47.                 Comp.IAcSmComponent component = null;
  48.                 while ((component = encomp.Next()) != null) {
  49.                     ProcessElement(ed, component, 0);
  50.                 }
  51.                 encomp.Reset();
  52.             }
  53.             enumerator.Reset();
  54.         }
  55.  
  56.         // Recursive processing of the elements
  57.         void ProcessElement(Ed.Editor ed, Comp.IAcSmComponent component, Int32 level) {
  58.             ed.WriteMessage("\t{0}{1} (Subset)\n", new String('\t', level), component.GetName());
  59.             Array array = null;
  60.             component.GetDirectlyOwnedObjects(out array);
  61.             if (array != null) {
  62.                 Int32 sheet_number = 0;
  63.                 foreach (var item in array) {
  64.                     if (item is Comp.IAcSmSubset) {
  65.                         ProcessElement(ed, (Comp.IAcSmSubset)item, level + 1);
  66.                     }
  67.                     else if (item is Comp.IAcSmSheet) {
  68.                         Comp.IAcSmSheet sheet = (Comp.IAcSmSheet)item;
  69.                         ed.WriteMessage("\t\t{0}{1} (Sheet)", new String('\t', level), sheet.GetName());
  70.                         sheet.SetNumber(sheet_number.ToString()); // I get an exception here!
  71.                         ++sheet_number;
  72.                     }
  73.                     else if (item is Comp.IAcSmPersist) {
  74.                         Comp.IAcSmPersist persist = (Comp.IAcSmPersist)item;
  75.                         ed.WriteMessage("\t\t{0}Additional info: {1}", new String('\t', level), persist.GetTypeName());
  76.                     }
  77.                     else {
  78.                         ed.WriteMessage("\t\t{0}Unknown object: {1}", new String('\t', level), item.GetType().ToString());
  79.                     }
  80.                     ed.WriteMessage("\n");
  81.                 }
  82.             }
  83.         }
  84.     }
  85. }
  86.  

But I get an exception in the row number 70:



Why it happen? I don't understand this message. What is the "PerUser subscription"?

Thank you.
« Last Edit: November 13, 2013, 07:21:04 AM by Andrey »

Andrey Bushman

  • Swamp Rat
  • Posts: 864
Re: Update the numbering of Sheets in the Sheet Set.
« Reply #1 on: November 13, 2013, 07:32:28 AM »
I find the my mistakes: I must to use AcSmDatabase.LockDb and AcSmDatabase.UnlockDb. It works fine:
Code - C#: [Select]
  1. /*
  2.  * SheetSetTools. © Andrey Bushman, 2013
  3.  * AutoCAD 2014 x64 Enu
  4.  *
  5.  * COMMANDS:
  6.  * SS-RENUMBER-ALL - Update the numeration for all sheets in the all opened sheet sets:
  7.  * numbering of each subgroup shall begin with 1.
  8.  *
  9.  * SS-RENUMBER-ALL-BASES-OF-FIRST - Update the numeration: to continue numbering on the
  10.  * basis of the first element in the each subset (in the all opened sheet sets).
  11.  *
  12.  * AutoCAD references:
  13.  * AcCoreMgd.dll
  14.  * AcDbMgd.dll
  15.  * AcMgd.dll
  16.  * Interop.ACSMCOMPONENTS19Lib.dll
  17.  */
  18.  
  19. using System;
  20. using cad = Autodesk.AutoCAD.ApplicationServices.Application;
  21. using App = Autodesk.AutoCAD.ApplicationServices;
  22. using Db = Autodesk.AutoCAD.DatabaseServices;
  23. using Ed = Autodesk.AutoCAD.EditorInput;
  24. using Rtm = Autodesk.AutoCAD.Runtime;
  25. using Comp = ACSMCOMPONENTS19Lib;
  26.  
  27. [assembly: Rtm.ExtensionApplication(typeof(Bushman.AutoCAD.SheetSetTools.SheetSetCommands))]
  28. [assembly: Rtm.CommandClass(typeof(Bushman.AutoCAD.SheetSetTools.SheetSetCommands))]
  29.  
  30. namespace Bushman.AutoCAD.SheetSetTools {
  31.  
  32.     public class SheetSetCommands : Rtm.IExtensionApplication {
  33.  
  34.         const String ns = "bush"; // namespace
  35.  
  36.         /// <summary>
  37.         /// Update the numeration for all sheets in the all opened sheet sets: numbering of
  38.         /// each subgroup shall begin with 1.
  39.         /// </summary>
  40.         [Rtm.CommandMethod(ns, "ss-renumber-all", Rtm.CommandFlags.Modal)]
  41.         public void Renumber_All() {
  42.             Renumber();
  43.         }
  44.  
  45.         /// <summary>
  46.         /// Update the numeration: to continue numbering on the basis of the first element
  47.         /// in the each subset (in the all opened sheet sets).
  48.         /// </summary>
  49.         [Rtm.CommandMethod(ns, "ss-renumber-all-bases-of-first", Rtm.CommandFlags.Modal)]
  50.         public void Renumber_all_bases_of_first() {
  51.             Renumber(true);
  52.         }
  53.  
  54.         /// <summary>
  55.         /// To update numbering of all sheets in the all opened sheet sets.
  56.         /// </summary>
  57.         /// <param name="continue_numbering">True - to continue numbering on the basis
  58.         /// of the first element in the each subset (in the all opened sheet sets);
  59.         /// False - Numbering of each subgroup shall begin with 1 (in the all opened
  60.         /// sheet sets).</param>
  61.         void Renumber(Boolean continue_numbering = false) {
  62.             App.Document doc = cad.DocumentManager.MdiActiveDocument;
  63.             Db.Database db = doc.Database;
  64.             Ed.Editor ed = doc.Editor;
  65.             Comp.AcSmSheetSetMgr mng = new Comp.AcSmSheetSetMgr();
  66.             Comp.IAcSmEnumDatabase enumerator = mng.GetDatabaseEnumerator();
  67.             enumerator.Reset();
  68.             Comp.AcSmDatabase smDb = null;
  69.             while ((smDb = enumerator.Next()) != null) {
  70.                 smDb.LockDb(db);
  71.                 String fname = smDb.GetFileName();
  72.                 Comp.AcSmSheetSet sheetset = smDb.GetSheetSet();
  73.                 String name = sheetset.GetName();
  74.                 String descr = sheetset.GetDesc();
  75.                 ed.WriteMessage("\nSheet Set name: {0}\n", name);
  76.                 Int32 ren_count = 0; // count of renamed sheets.
  77.                 Comp.IAcSmEnumComponent encomp = sheetset.GetSheetEnumerator();
  78.                 encomp.Reset();
  79.                 Comp.IAcSmComponent component = null;
  80.                 while ((component = encomp.Next()) != null) {
  81.                     ProcessElement(ed, component, ref ren_count, continue_numbering);
  82.                 }
  83.                 encomp.Reset();
  84.                 smDb.UnlockDb(db, true);
  85.                 ed.WriteMessage("Renumbered sheets count: {0}\n", ren_count);
  86.             }
  87.             enumerator.Reset();
  88.         }
  89.  
  90.         /// <summary>
  91.         ///  Recursive processing of the elements: change the sheet's number.
  92.         /// </summary>
  93.         /// <param name="ed">An Editor for the output.</param>
  94.         /// <param name="component">Component of Sheet Set.</param>
  95.         /// <param name="ren_count">The count of renumbered sheets in the sheet set.</param>
  96.         /// <param name="continue_numbering">True - to continue numbering on the basis
  97.         /// of the first element in the each subset (in the all opened sheet sets);
  98.         /// False - Numbering of each subgroup shall begin with 1 (in the all opened
  99.         /// sheet sets).</param>
  100.         void ProcessElement(Ed.Editor ed, Comp.IAcSmComponent component,
  101.             ref Int32 ren_count, Boolean continue_numbering) {
  102.             Array array = null;
  103.             component.GetDirectlyOwnedObjects(out array);
  104.             if (array != null) {
  105.                 Int32 sheet_number = 1;
  106.                 Boolean basis_of_first = continue_numbering;
  107.                 foreach (var item in array) {
  108.                     if (item is Comp.IAcSmSubset) {
  109.                         ProcessElement(ed, (Comp.IAcSmSubset)item, ref ren_count, continue_numbering);
  110.                     }
  111.                     else if (item is Comp.IAcSmSheet) {
  112.                         Comp.IAcSmSheet sheet = (Comp.IAcSmSheet)item;
  113.  
  114.                         String cur_str_value = sheet.GetNumber();
  115.                         Int32 int_value = 0;
  116.                         Boolean is_int32 = Int32.TryParse(cur_str_value, out int_value);
  117.  
  118.                         if (!is_int32 || (!basis_of_first && int_value != sheet_number)) {
  119.                             sheet.SetNumber(sheet_number.ToString());
  120.                             ++ren_count;
  121.                         }
  122.                         else if (basis_of_first) {
  123.                             sheet_number = int_value;
  124.                         }
  125.                         ++sheet_number;
  126.                         basis_of_first = false;
  127.                     }
  128.                     else if (item is Comp.IAcSmPersist) {
  129.                         Comp.IAcSmPersist persist = (Comp.IAcSmPersist)item;
  130.                     }
  131.                     else {
  132.                         ed.WriteMessage("Unknown object: {0}", item.GetType().ToString());
  133.                     }
  134.                 }
  135.             }
  136.         }
  137.  
  138.         #region IExtensionApplication Members
  139.  
  140.         public void Initialize() {
  141.             App.Document doc = cad.DocumentManager.MdiActiveDocument;
  142.             Ed.Editor ed = doc.Editor;
  143.             ed.WriteMessage("\nSheetSetTools. © Andrey Bushman, 2013\n\n");
  144.         }
  145.  
  146.         public void Terminate() {
  147.             // Empty body.
  148.         }
  149.         #endregion
  150.     }
  151. }
  152.  
« Last Edit: November 14, 2013, 03:31:31 AM by Andrey »

Andrey Bushman

  • Swamp Rat
  • Posts: 864
Re: Update the numbering of Sheets in the Sheet Set.
« Reply #2 on: November 14, 2013, 12:31:16 AM »
I updated the code in my previous message. Maybe it will useful for anybody.

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: Update the numbering of Sheets in the Sheet Set.
« Reply #3 on: November 14, 2013, 01:12:47 AM »
Thanks Andrey.
kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

Andrey Bushman

  • Swamp Rat
  • Posts: 864
Re: Update the numbering of Sheets in the Sheet Set.
« Reply #4 on: November 14, 2013, 03:43:07 AM »
I've fixed a bug in my previous code: earlier, if the first sheet in the subset had not integer sheet number, then only the first sheet was renumbered. Now it works like I expect.

Keith Brown

  • Swamp Rat
  • Posts: 601
Re: Update the numbering of Sheets in the Sheet Set.
« Reply #5 on: November 14, 2013, 09:04:34 AM »
Thanks for sharing the solution Andrey
Keith Brown | AutoCAD MEP Blog | RSS Feed
AutoCAD MEP 2014 / Revit MEP 2014 / EastCoast CAD/CAM addon / Visual Studio 2013

Andrey Bushman

  • Swamp Rat
  • Posts: 864
Re: Update the numbering of Sheets in the Sheet Set.
« Reply #6 on: November 14, 2013, 09:09:11 AM »
Welcome. I will be glad if it is useful for someone at this forum. :)