среда, 13 ноября 2013 г.

Перенумерация листов в подшивках AutoCAD

Написал пару команд AutoCAD, позволяющих обновить нумерацию всех листов сразу во всех открытых в данный момент подшивках.


Нумерация листов будет соответствовать тому порядку, в котором эти листы расположены в палитре Sheet Set Manager на вкладке Sheet List. В нумерации используются целочисленные значения. Вы можете мышкой перетаскивать листы выше\ниже, а так же переносить их в др. группу листов, меняя тем самым номер перетаскиваемого листа при очередном запуске команды обновления нумерации.

Итак, ниже в программном коде определены следующие команды:

SS-RENUMBER-ALL - обновить нумерацию всех листов во всех открытых подшивках. Нумерацию в каждой подгруппе следует начинать с 1 (единицы).

SS-RENUMBER-ALL-BASES-OF-FIRST - обновить нумерацию всех листов во всех открытых подшивках. Нумерация в каждой подгруппе будет формироваться, взяв за исходное значение номер первого (по порядку следования) листа в подгруппе. Т. е. если первый лист в подгруппе имеет номер 4, то второму будет назначено значение 5, третьему - 6 и т. д. Если в первом листе в качестве номера не будет указано целое число, то это значение будет изменено на 1 и команда отработает как SS-RENUMBER-ALL.

Внимание!
Если у вас возникнут проблемы с загрузкой плагина в AutoCAD - читайте это (возможно вам потребуется разблокировать выложенные мною выше .NET-библиотеки, заблокированные софтом, с помощью которого вы их скачали).


Откомпилированные версии плагина:
Далее, собственно, сам код (следует обратить внимание на это):

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

11 комментариев:

Igor комментирует...

Добрый день. Не могли бы вы выложить компиляцию под AutoCAD 2015. Ну может и 2016 заодно. Спасибо.

Igor комментирует...

Добрый день. Не могли бы вы скомпилировать под AutoCAD 2015.Ну и под 2016 заодно. Спасибо.

Andrey Bushman комментирует...

К сожалению, я пока не располагаю свободным временем, достаточным для выполнения вашей просьбы.

Unknown комментирует...

Здравствуйте!
Судя по статье
http://bushman-andrey.blogspot.co.uk/2014/04/net-autocad-net-framework-ms-visual.html
Плагин для Autocad 2014 подходит для Autocad 2013?
Или я бестолочь....

Unknown комментирует...

Здравствуйте!
Судя по статье
http://bushman-andrey.blogspot.co.uk/2014/04/net-autocad-net-framework-ms-visual.html
Плагин Autocad 2014 подходит для Autocad 2013?
Или я бестолочь...

Andrey Bushman комментирует...

Добрый день.
>Плагин для Autocad 2014 подходит для Autocad 2013?
В данном случае - да. На всякий случай обращаю ваше внимание на то, что обозначенный код выполняет перенумерацию листов в группах листов (SheetSet), а не непосредственно в подшивке.

Unknown комментирует...

О божечки у меня получилось. Реализовал через acaddoc.lsp
Спасибо вам за статьи!!!

Andrey Bushman комментирует...

>Реализовал через acaddoc.lsp
Достаточно было воспользоваться командой netload (dll файл должен находиться на локальном диске).

Анонимный комментирует...

Подгружаю через netload, открываю sheetset в автокаде. запускаю команду. а потом пишет она Sheet Set name: 216-16-КЖ.И4-Наружные стеновые панели
Renumbered sheets count: 0
Что я делаю не так?

Алексей комментирует...

Андрей, подскажите пожалуйста, сколько бы могло стоить вами потраченное время, чтоб откомпелировать этот автонумератор для 2020 автокада.

KEHT комментирует...

Добрый день при компиляции для 2020 автокада не могу найти файл AXDBLib.dll есть только AXDB.dll. Вроде как загружается команда становится активна. Но при добавления в автокад выдает ошибку.
Не удалось загрузить сборку. Сведения об ошибке: Autodesk.AutoCAD.Runtime.Exception: eDuplicateKey
в Autodesk.AutoCAD.Runtime.CommandClass.AddCommand(ICommandLineCallable ca, MethodInfo mi)
в Autodesk.AutoCAD.ApplicationServices.AutoCADApplicationHolder.Initialize(Assembly assembly)
в Autodesk.AutoCAD.ApplicationServices.ExtensionLoader.ProcessAssembly(Assembly assembly)

А при запуске команды SS-RENUMBER-ALL


Приложение не поддерживает оперативную (JIT)
отладку. Подробная информацию приводится в конце данного сообщения.

************** Текст исключения **************
System.Runtime.InteropServices.COMException (0x80040111): Не удалось получить фабрику класса COM для компонента с CLSID {7889CD73-6054-42B8-A3A3-12FEA1BE42A4} из-за следующей ошибки: 80040111 Требуемый класс отсутствует в ClassFactory (Исключение из HRESULT: 0x80040111 (CLASS_E_CLASSNOTAVAILABLE)).
в System.RuntimeTypeHandle.CreateInstance(RuntimeType type, Boolean publicOnly, Boolean noCheck, Boolean& canBeCached, RuntimeMethodHandleInternal& ctor, Boolean& bNeedSecurityCheck)
в System.RuntimeType.CreateInstanceSlow(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache, StackCrawlMark& stackMark)
в System.Activator.CreateInstance(Type type, Boolean nonPublic)
в System.Activator.CreateInstance(Type type)
в Bushman.AutoCAD.SheetSetTools.SheetSetCommands.Renumber(Boolean continue_numbering)
в Autodesk.AutoCAD.Runtime.CommandClass.InvokeWorker(MethodInfo mi, Object commandObject, Boolean bLispFunction)
в Autodesk.AutoCAD.Runtime.CommandClass.InvokeWorkerWithExceptionFilter(MethodInfo mi, Object commandObject, Boolean bLispFunction)
в Autodesk.AutoCAD.Runtime.PerDocumentCommandClass.Invoke(MethodInfo mi, Boolean bLispFunction)
в Autodesk.AutoCAD.Runtime.CommandClass.CommandThunk.Invoke()