Разбор программных кодов из "Программирование для AutoCAD 2013-2015" Полещука

Автор Тема: Разбор программных кодов из "Программирование для AutoCAD 2013-2015" Полещука  (Прочитано 19878 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн Максим МаркевичАвтор темы

  • ADN Club
  • ****
  • Сообщений: 254
  • Карма: 29
  • Skype: evthisrel
У меня миссклик произошёл. Сразу же полез править в соответствии со скринкастом у Вас. Но Вы не оставили никаких шансов. Видимо, мы одновременно даже правили. Я бы исправился. Извиняюсь.

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Но Вы не оставили никаких шансов
:) С ошибкой всё понятно?
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Максим МаркевичАвтор темы

  • ADN Club
  • ****
  • Сообщений: 254
  • Карма: 29
  • Skype: evthisrel
С ошибкой всё понятно?
Суть ошибки то я понимаю.
Но вот как с ней бороться, это задача..
Ошибка достаточно четко идентифицирована (eNullObjectId) и в этом контексте это означает, что ts.Template возвращает ObjectId.kNull - видимо таблица без шаблона.
Именно, а все потому, что для 2014х64 автокада не работает присвоение:
Код - C# [Выбрать]
  1. tableStyle2.Template = template.ObjectId;
То есть оно, почему-то, только для чтения:

А, соответсвенно, и вот это:
Код - C# [Выбрать]
  1. Db.TableTemplate template =tr.GetObject(ts.Template,Db.OpenMode.ForRead) as Db.TableTemplate;
Думаю, что нужно какой-то другой способ использовать, но понятия не имею, какой.
Напоминаю, в автокадах 2016 и 2017 все хорошо работает.
Я могу предоставить только такой "топорный" анализ, так как пока еще многое не понимаю.




Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Для AutoCAD 2014 убери в настройках проекта NEWER_THAN_AUTOCAD_2014
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Максим МаркевичАвтор темы

  • ADN Club
  • ****
  • Сообщений: 254
  • Карма: 29
  • Skype: evthisrel
Для AutoCAD 2014 убери в настройках проекта NEWER_THAN_AUTOCAD_2014
Я понимаю, что таким образом выполнение кода будет происходить по 2-й ветке (при помощи COM):
Код - C# [Выбрать]
  1. #if NEWER_THAN_AUTOCAD_2014
  2.                     tableStyle2.Template = template.ObjectId;
  3. #elif NEWER_THAN_AUTOCAD_2009
  4.           Com.IAcadTableStyle customTableStyle2 = (Com.IAcadTableStyle)tableStyle2.AcadObject;
  5. #endif
Но вот здесь, все равно, будет ошибка (ObjectId.kNull):
Код - C# [Выбрать]
  1. Db.TableTemplate template =tr.GetObject(ts.Template,Db.OpenMode.ForRead) as
  2.                       Db.TableTemplate;

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Я понимаю, что таким образом выполнение кода будет происходить по 2-й ветке (при помощи COM):
Там ветка более сложная:
Код - C# [Выбрать]
  1. #if NEWER_THAN_AUTOCAD_2014
  2.           tableStyle2.Template =
  3.             template.ObjectId;
  4. #elif NEWER_THAN_AUTOCAD_2009
  5.           Com.IAcadTableStyle customTableStyle2 = (Com.IAcadTableStyle)tableStyle2 .AcadObject;
  6.  
  7. #if PLATFORM_X86
  8.           customTableStyle2.TemplateId = template.ObjectId.OldIdPtr.ToInt32();
  9. #else
  10.           customTableStyle2.TemplateId = template.ObjectId.OldIdPtr.ToInt64();
  11. #endif // #if PLATFORM_X86
  12.  
  13. #else
  14.           Com.IAcadTableStyle2 customTableStyle2 = (Com.IAcadTableStyle2)tableStyle2.AcadObject;
  15. #if PLATFORM_X86
  16.           customTableStyle2.TemplateId = template.ObjectId.OldIdPtr.ToInt32();
  17. #else
  18.           customTableStyle2.TemplateId = template.ObjectId.OldIdPtr.ToInt64();
  19. #endif // #if PLATFORM_X86
  20.  
  21. #endif // #if NEWER_THAN_AUTOCAD_2009

Но вот здесь, все равно, будет ошибка (ObjectId.kNull):
Ты это уже проверил?
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Кстати, я бы заменил бы этот код на такой:
Код - C# [Выбрать]
  1. #if NEWER_THAN_AUTOCAD_2014
  2.           tableStyle2.Template =  template.ObjectId;
  3. #elif NEWER_THAN_AUTOCAD_2009
  4.           Com.IAcadTableStyle customTableStyle2 =
  5.               (Com.IAcadTableStyle)tableStyle2.AcadObject;
  6.           customTableStyle2.TemplateId =
  7.               ((Com.IAcadObject)template.AcadObject).ObjectID;
  8. #else
  9.           Com.IAcadTableStyle2 customTableStyle2 =
  10.               (Com.IAcadTableStyle2)tableStyle2.AcadObject;
  11.           customTableStyle2.TemplateId =
  12.               ((Com.IAcadObject)template.AcadObject).ObjectID;
  13. #endif // #if NEWER_THAN_AUTOCAD_2009
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Максим МаркевичАвтор темы

  • ADN Club
  • ****
  • Сообщений: 254
  • Карма: 29
  • Skype: evthisrel
Там ветка более сложная:
Просто x86 я не рассматриваю, поэтому адаптировал код под себя.
Но вот здесь, все равно, будет ошибка (ObjectId.kNull):
Ты это уже проверил?
Да, именно по этой причине я и написал.
Причем, если взять программный код в чистоте, из книжки, то он сработает. Таблицы создадутся.
Поэтому сейчас сел за более детальный разбор программного кода, просто я многое взял из Полещука, не осознав до конца, вот и наказан за такое.
Кстати, я бы заменил бы этот код на такой:
Выглядит лаконичней, сейчас поразбираюсь. Спасибо.


Оффлайн Андрей Бушман

  • ADN Club
  • *****
  • Сообщений: 2000
  • Карма: 163
  • Пишу программки...
    • Блог
  • Skype: Compositum78
Кажется я понял в чем у тебя проблема. Добавь еще в Reference Paths путь к ObjectARX SDK подкаталог \inc-x64 (если у тебя AutoCAD x64) или \inc-win32 (если AutoCAD x86):
Чтобы раз и навсегда избавиться от подобных проблем, можно использовать соответствующие NuGet пакеты. В виду того, что пакеты автодеска не доведены до ума, то можно использовать мои.

Оффлайн Андрей Бушман

  • ADN Club
  • *****
  • Сообщений: 2000
  • Карма: 163
  • Пишу программки...
    • Блог
  • Skype: Compositum78
evthisrel, ты уверен, что определил правильный набор отладочных символов в настройках проекта? Например, если у тебя AutoCAD x64, то не следует определять символ PLATFORM_X86.

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Просто x86 я не рассматриваю, поэтому адаптировал код под себя.
Неправильно адаптировал - выкинул существенный код с присвоением customTableStyle2.TemplateId значения. Поэтому он у тебя потом и ObjectId.kNull.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Максим МаркевичАвтор темы

  • ADN Club
  • ****
  • Сообщений: 254
  • Карма: 29
  • Skype: evthisrel
Чтобы раз и навсегда избавиться от подобных проблем, можно использовать соответствующие NuGet пакеты. В виду того, что пакеты автодеска не доведены до ума, то можно использовать мои.
Очень удобно. Спасибо большое!!!
evthisrel, ты уверен, что определил правильный набор отладочных символов в настройках проекта? Например, если у тебя AutoCAD x64, то не следует определять символ PLATFORM_X86.
Да, с этим был порядок. Дело было в том, что уже подметил Александр Ривилис:
Неправильно адаптировал - выкинул существенный код с присвоением customTableStyle2.TemplateId значения. Поэтому он у тебя потом и ObjectId.kNull.
Я лоханулся немного с адаптацией. :(
Сейчас у меня еще одна проблемка. Суть такова..
Я пытаюсь написать плагин, точнее он, вроде как, готов, находится в стадии тестирования, где пользователь выделяет определенные блоки, на уровне программного кода из них считываются свойства и атрибуты, и формируется спецификация. Соответственно, всю теория по созданию спецификации черпал из программного кода Андрея Бушмана, который размещен в книге Полещука. Так вот, там все подробно расписано и для того, чтобы создать табличный стиль на основе шаблона, я создаю табличный стиль "Базовый", причем у себя я это не делаю в разных методах, а загоняю все в один.
То есть, я создаю базовый табличный стиль, потом стиль на основе шаблона и выполняю вставку таблицы (все в одном методе Specification), так вот хочу в конце добавить удаление табличного стиля "Базовый", так как он мне больше не нужен, и не хочется оставлять в документе что-то лишнее.
Код - C# [Выбрать]
  1. //Команды, определённые в данном коде:
  2. //Specification - создание спецификации путем извлечения информации из блоков.
  3. using Autodesk.AutoCAD.Colors;
  4. using AppServCore = Autodesk.AutoCAD.ApplicationServices.Core;
  5. using AppServ = Autodesk.AutoCAD.ApplicationServices;
  6. using Autodesk.AutoCAD.Runtime;
  7. using Autodesk.AutoCAD.DatabaseServices;
  8. using Autodesk.AutoCAD.Geometry;
  9. using Autodesk.AutoCAD.EditorInput;
  10. using Autodesk.AutoCAD.Interop;
  11. using Autodesk.AutoCAD.Interop.Common;
  12. [assembly: CommandClass(typeof(Evth.CAD.Samples.Styles.CreateTable))]
  13. namespace Evth.CAD.Samples.Styles
  14. {
  15.     public class CreateTable
  16.     {
  17.     // Наименование группы команд
  18.     private const string Group = "Samples";
  19.     private const string TextStyleName = "Текст таблиц";
  20.     private const string TableStyleName1 = "Базовый";
  21.     private const string TableStyleName2 = "Спецификация";
  22.         [CommandMethod(Group, "Specification", CommandFlags.Modal)]
  23.         public void Specification()
  24.         {
  25.         var list1 = new List<string>();
  26.         var list2 = new List<string>();
  27.         var list3 = new List<string>();
  28.             var doc = AppServCore.Application.DocumentManager.MdiActiveDocument;
  29.             if (doc == null)
  30.                 return;
  31.             var db = doc.Database;
  32.             var ed = doc.Editor;
  33.             using (doc.LockDocument())
  34.             {
  35.                 var activeDocument = default(AcadDocument);
  36.                 activeDocument = (AcadDocument)
  37.                 AppServ.DocumentExtension.GetAcadDocument(AppServCore.Application.DocumentManager.MdiActiveDocument);
  38.                 using (var tr = db.TransactionManager.StartTransaction())
  39.                 {
  40.  
  41.                     ***************************
  42.                    //Пропускаю момент формирования списков list1..3 (это происходит путем выделения блоков и считывания нужной инфы
  43.                    ***************************
  44.  
  45.                     var tst = tr.GetObject(db.TextStyleTableId, OpenMode.ForWrite) as TextStyleTable;
  46.                     var textStyleId = ObjectId.Null;
  47.                     if (tst.Has(TextStyleName))
  48.                     {
  49.                         textStyleId = tst[TextStyleName];
  50.                     }
  51.                     else
  52.                     {
  53.                         var textStyle = new TextStyleTableRecord();
  54.                         textStyle.Name = TextStyleName;
  55.                         // ttf или, к примеру, shx файл.
  56.                         textStyle.FileName = "Isocpeur.shx";
  57.                         textStyle.XScale = 0.95;
  58.                         tst.Add(textStyle);
  59.                         tr.AddNewlyCreatedDBObject(textStyle, true);
  60.                         textStyleId = textStyle.ObjectId;
  61.                     }
  62.                     var tableStylesDictionary = tr.GetObject(db.TableStyleDictionaryId, OpenMode.ForWrite) as DBDictionary;
  63.                     TableStyle tableStyle;
  64.                     var tableStyleId = ObjectId.Null;
  65.                     if (tableStylesDictionary.Contains(TableStyleName1))
  66.                     {
  67.                         return;
  68.                     }
  69.                     else
  70.                     {
  71.                         tableStyle = new TableStyle();
  72.                         tableStyleId = tableStylesDictionary.SetAt(TableStyleName1, tableStyle);
  73.                         tr.AddNewlyCreatedDBObject(tableStyle, true);
  74.                     }
  75.                     // Некоторые операции будут выполняться через COM, т.к. некоторые настройки
  76.                     // Бушману удалось выполнить только через COM.
  77.                     var customTableStyle = (IAcadTableStyle)tableStyle.AcadObject;
  78.                     customTableStyle.FlowDirection = AcTableDirection.acTableTopToBottom;
  79.                     // Шаг 1: Сначала создаём таблицу, которая должна применяться в качестве шаблона.
  80.                     var table = new Table();
  81.                     table.SetDatabaseDefaults();
  82.                     table.TableStyle = tableStyleId;
  83.                     table.Position = new Point3d(0, 0, 0);
  84.                     const int columnsCount = 6;
  85.                     int rowsCount = list1.Count + 4;
  86.                     table.SetSize(rowsCount, columnsCount);
  87.                     table.Height = 15;
  88.                     table.Width = 20;
  89.                     table.ColorIndex = 5;
  90.                     // Заполняем таблицу...
  91.                     String[,] str = new String[rowsCount, columnsCount];
  92.                     for (int i = 0; i < rowsCount; i++)
  93.                     {
  94.                         for (int j = 0; j < columnsCount; j++)
  95.                         {
  96.                             str[i, j] = String.Empty;
  97.                         }
  98.                     }
  99.                     str[0, 0] = "Спецификация";
  100.                     str[1, 0] = "Поз.";
  101.                     str[1, 1] = "Обозначение";
  102.                     str[1, 2] = "Наименование";
  103.                     str[1, 3] = "Кол.";
  104.                     str[1, 4] = "Масса  ед.,кг";
  105.                     str[1, 5] = "Приме- чание";
  106.                     for (int i = 0; i < rowsCount; i++)
  107.                     {
  108.                         for (int j = 0; j < columnsCount; j++)
  109.                         {
  110.                             table.Cells[i, j].SetValue(str[i, j], ParseOption.ParseOptionNone);
  111.                         }
  112.                         table.Rows[i].Height = 8;
  113.                     }
  114.                     table.Rows[1].Height = 15;
  115.                     table.Columns[0].Width = 15;
  116.                     table.Columns[1].Width = 60;
  117.                     table.Columns[2].Width = 65;
  118.                     table.Columns[3].Width = 10;
  119.                     table.Columns[4].Width = 15;
  120.                     table.Columns[5].Width = 20;
  121.                     for (int i = 0; i < list1.Count; i++)
  122.                     {
  123.                         table.Cells[i + 2, 0].SetValue(list1[i] +
  124.                             Convert.ToString(Math.Round(Convert.ToDouble(list3[i]) / 100, 0, MidpointRounding.AwayFromZero)),
  125.                             ParseOption.ParseOptionNone);
  126.                     }
  127.                     for (int i = 0; i < list1.Count; i++)
  128.                     {
  129.                         table.Cells[i + 2, 2].SetValue(" " + list1[i] + "  СТБ 1704-2012" + " L=" + list3[i],
  130.                             ParseOption.ParseOptionNone);
  131.                     }
  132.                     for (int i = 0; i < list1.Count; i++)
  133.                     {
  134.                         table.Cells[i + 2, 4].SetValue(Convert.ToString(Math.Round(Math.Pow(Convert.ToDouble(list1[i]), 2) *
  135.                             Math.PI / 4 * Convert.ToDouble(list3[i]) * 7850 / Math.Pow(10, 9), 2, MidpointRounding.AwayFromZero)),
  136.                             ParseOption.ParseOptionNone);
  137.                     }
  138.                      for (Int32 i = 0; i < columnsCount; i++)
  139.                     {
  140.                         table.Columns[i].Alignment = CellAlignment.MiddleCenter;
  141.                     }
  142.                      for (Int32 i = 0; i < 2; i++)
  143.                     {
  144.                         table.Rows[i].Alignment = CellAlignment.MiddleCenter;
  145.                         if (i == 0)
  146.                             table.Rows[i].Style = "_TITLE";
  147.                         else
  148.                             table.Rows[i].Style = "_HEADER";
  149.                     }
  150.                     for (int i = 2; i < rowsCount; i++)
  151.                     {
  152.                         table.Cells[i, 2].Alignment = CellAlignment.MiddleLeft;
  153.                     }
  154.                     table.GenerateLayout();
  155.                     // Шаг 2: Назначаем созданную нами выше таблицу, шаблоном для табличного стиля
  156.                     var tableStyle2 = new TableStyle();
  157.                     tableStyle2.CopyFrom(tableStyle);
  158.                     var tableStyle2Id = tableStylesDictionary.SetAt(TableStyleName2, tableStyle2);
  159.                     tr.AddNewlyCreatedDBObject(tableStyle2, true);
  160.                     var template =new TableTemplate(table, TableCopyOptions.TableCopyColumnWidth |
  161.                         TableCopyOptions.TableCopyRowHeight |TableCopyOptions.ConvertFormatToOverrides);
  162.                     db.AddDBObject(template);
  163.                     tr.AddNewlyCreatedDBObject(template, true);
  164. #if NEWER_THAN_AUTOCAD_2014
  165.           tableStyle2.Template =  template.ObjectId;
  166. #elif NEWER_THAN_AUTOCAD_2009
  167.            IAcadTableStyle customTableStyle2 = (IAcadTableStyle)tableStyle2.AcadObject;
  168.            customTableStyle.TemplateId =((IAcadObject)template.AcadObject).ObjectID;
  169. #else
  170.           Com.IAcadTableStyle2 customTableStyle2 = (Com.IAcadTableStyle2)tableStyle2.AcadObject;
  171.           customTableStyle2.TemplateId = ((Com.IAcadObject)template.AcadObject).ObjectID;
  172. #endif
  173.           //Выполняем настройки таблиуцы (вызываем приватный метод)
  174.           InitializeEmbededCellStyles(tableStyle2, textStyleId);
  175.                     var dict = tr.GetObject(db.TableStyleDictionaryId, OpenMode.ForRead) as DBDictionary;
  176.                     var ts = tr.GetObject(dict.GetAt(TableStyleName2),
  177.                       OpenMode.ForRead) as TableStyle;
  178.                     var template2 = tr.GetObject(ts.Template, OpenMode.ForRead) as
  179.                       TableTemplate;
  180.                     var tableInstance = new Table();
  181.                     tableInstance.CopyFrom(template2, TableCopyOptions.FillTarget);
  182.                     tableInstance.GenerateLayout();
  183.                     PromptPointResult pr = ed.GetPoint("\nУкажите точку вставки таблицы: ");
  184.                     if (pr.Status == PromptStatus.OK)
  185.                     {
  186.                         tableInstance.Position = pr.Value;
  187.                     }
  188.                     var bt = tr.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable;
  189.                     var modelSpace = tr.GetObject(bt[BlockTableRecord.ModelSpace],
  190.                     OpenMode.ForWrite) as BlockTableRecord;
  191.                     modelSpace.AppendEntity(tableInstance);
  192.                     tr.AddNewlyCreatedDBObject(tableInstance, true);
  193.  
  194.                    *****************************************************
  195.                    // Вот здесь хочу удалить стиль "Базовый", но никак не выходит              
  196.                    *****************************************************
  197.  
  198.                     tr.Commit();
  199.                 }
  200.             }
  201.         }



Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
так вот хочу в конце добавить удаление табличного стиля "Базовый", так как он мне больше не нужен, и не хочется оставлять в документе что-то лишнее.
Не пробовал tableStyle.Erase(); ? Возможно нужно создать вторую транзакцию.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Максим МаркевичАвтор темы

  • ADN Club
  • ****
  • Сообщений: 254
  • Карма: 29
  • Skype: evthisrel
Не пробовал tableStyle.Erase(); ? Возможно нужно создать вторую транзакцию.
Пробовал, но не берусь говорить, что не работает данный вариант (возможно, плохо пробовал).
Нашел более деликатный способ решения данного вопроса, а именно обошелся без создания базового стиля.
Код - C# [Выбрать]
  1. var tableStyle = new TableStyle() as TableStyle;
  2. tableStyleId = tableStylesDictionary.SetAt("Standard", tableStyle);
То есть воспользовался существующим "Standard". Довел свой адаптированный код до ума, то есть подчистил его и упростил, но уже с полным пониманием дела, а посему доволен как слон. :)