Автокад C#. Ошибка выполнения команды.

Автор Тема: Автокад C#. Ошибка выполнения команды.  (Прочитано 10364 раз)

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

Тема содержит сообщение с Решением. Нажмите здесь чтобы посмотреть его.

Оффлайн melkalex90Автор темы

  • ADN OPEN
  • **
  • Сообщений: 59
  • Карма: 0
Добрый день!
Подскажите, где конкретно я допустил ошибку, если при выполнении команды у меня в автокаде выскакивает ошибка:Операция является недопустимой из-за текущего состояния объекта.
Ниже приведу код, согласно которому у меня идет запрос на выделение контуров(полилиний), считывание всех текстов на чертеже(без MText), определение базовой точки текста, определение принадлежит ли базовая точка текста к контуру и вывод периметра с площадью в командную строку.

Код - C# [Выбрать]
  1. namespace PlinesArea
  2. {
  3.     public class PlineArea
  4.     {
  5.         public Dictionary<string, List<ObjectId>> GetObjects()
  6.         {
  7.             Document acDoc = AcAp.Application.DocumentManager.MdiActiveDocument;
  8.             Database acCurDb = acDoc.Database;
  9.  
  10.             using (Transaction acTrans = acCurDb.TransactionManager.StartTransaction())
  11.             {
  12.                 BlockTable acBlTbl = (BlockTable)acTrans.GetObject(acCurDb.BlockTableId, OpenMode.ForRead);
  13.                 BlockTableRecord acBlTblRec = (BlockTableRecord)acTrans.GetObject(acBlTbl[BlockTableRecord.ModelSpace], OpenMode.ForRead);
  14.                 Dictionary<string, List<ObjectId>> dict = new Dictionary<string, List<ObjectId>>();
  15.  
  16.                 foreach (ObjectId item in acBlTblRec)
  17.                 {
  18.                     if (item.IsValid && !item.IsErased)
  19.                         if (!dict.Keys.Contains(item.ObjectClass.Name))
  20.                             dict.Add(item.ObjectClass.Name, new List<ObjectId>() { item });
  21.                         else
  22.                             dict[item.ObjectClass.Name].Add(item);
  23.                 }
  24.                 return dict;
  25.             }
  26.         }
  27.         [CommandMethod("PlinesAreaToEd")]
  28.         public void Main()
  29.         {
  30.             var doc = AcApp.DocumentManager.MdiActiveDocument;
  31.             var ed = doc.Editor;
  32.             Database db = doc.Database;
  33.  
  34.             try
  35.  
  36.             {
  37.  
  38.  
  39.                 Dictionary<string, List<ObjectId>> dict = GetObjects();
  40.                 var pso = new PromptSelectionOptions();
  41.                 pso.MessageForAdding = "\nSelect polylines: ";
  42.                 var filList = new TypedValue[1] { new TypedValue((int)DxfCode.Start, "*POLYLINE") };
  43.                 SelectionFilter sf = new SelectionFilter(filList);
  44.                 PromptSelectionResult psr = ed.GetSelection(pso, sf);
  45.                 if (psr.Status == PromptStatus.OK)
  46.                 {
  47.                     using (Transaction tr = doc.TransactionManager.StartTransaction())
  48.                     {
  49.                         var selSet = psr.Value;
  50.                         var ids = selSet.GetObjectIds();
  51.  
  52.                         int i = 1;
  53.                         foreach (ObjectId objId in ids)
  54.                         {
  55.                             var pl = tr.GetObject(objId, OpenMode.ForRead) as Polyline;
  56.                             if (pl.Closed)
  57.                                 using (AcDb.MPolygon mp = new AcDb.MPolygon())
  58.                             {
  59.                                  try
  60.                                     {
  61.                                         foreach (ObjectId item in dict["AcDbText"])
  62.                                         {
  63.                                             using (Transaction t = db.TransactionManager.StartTransaction())
  64.                                             {
  65.                                                 DBText text = (DBText)t.GetObject(item, OpenMode.ForWrite);
  66.                                                 DBPoint acPoint = new DBPoint(new Point3d(Math.Round(text.Position.X), Math.Round(text.Position.Y), Math.Round(text.Position.Z)));
  67.                                                 mp.AppendLoopFromBoundary(pl, true, AcGe.Tolerance.Global.EqualPoint);
  68.                                                 /*if (mp.IsPointOnLoopBoundary(acPoint.Position, 0, AcGe.Tolerance.Global.EqualPoint))
  69.                                                 {
  70.                                                    ed.WriteMessage("\n: " + text.TextString + ". Площадь: " + (pl.Area / 1000000).ToString() + " Периметр:" + (pl.Length / 1000).ToString());
  71.                                                 }*/
  72.                                                if (mp.IsPointInsideMPolygon(acPoint.Position, AcGe.Tolerance.Global.EqualPoint).Count > 0)
  73.                                                 {
  74.                                                    ed.WriteMessage("\n" + text.TextString  + ". Площадь: " + (pl.Area / 1000000).ToString() + " Периметр:" + (pl.Length / 1000).ToString());
  75.                                                 }
  76.                                                 else
  77.                                                 {
  78.                                                 }
  79.                                             }
  80.                                                                                      
  81.                                         }
  82.                                        
  83.                                        
  84.                                     }
  85.                                     catch { }
  86.                             }
  87.                             tr.Commit();
  88.                         }
  89.                     }
  90.                 }
  91.             }
  92.             catch (System.Exception ex)
  93.             {
  94.                 ed.WriteMessage("\n" + ex.Message);
  95.             }
  96.         }
  97.     }
  98. }
Заранее благодарю за помощь.
« Последнее редактирование: 31-10-2015, 17:22:04 от Александр Ривилис »

Оффлайн Александр Пекшев aka Modis

  • ADN Club
  • *****
  • Сообщений: 1658
  • Карма: 366
  • Отец modplus.org
    • ModPlus
Когда у вас выскакивает ошибка, то в ее описание написан номер строки, в котором случилась ошибка. Вполне вероятно, что ошибка происходит не в той части кода, которую вы приложили к вопросу. Я вот, например, не знаю что такое MPolygon и как он работает

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

  • Administrator
  • *****
  • Сообщений: 13832
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
melkalex90
1) Прочитайте у меня в подписи как нужно форматировать код.
2) В методе GetObjects не нашёл строки acTrans.Commit();
3) Для использования MPolygon необходимо загрузить AcMPolygonObjNN.dbx  (NN зависит от версии AutoCAD) и подключить AcMPolygonMGD.dll
Кстати, а в какой версии ты проверяешь свой код?
Ну и Александр Пекшев aka Modis абсолютно прав по поводу строки с ошибкой.
По поводу MPolygon: http://adn-cis.org/kak-sredstvami-opredelit-raspolozhenie-tochki-otnositelno-kontura.html
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн melkalex90Автор темы

  • ADN OPEN
  • **
  • Сообщений: 59
  • Карма: 0
Версия автокада 2016. В автокаде не увидел никакого номера строки с ошибкой. В автокаде у меня выводит текст входящий в 1ый контур и выводит 1 строку с площадью и периметром.. На счет остального сейчас не могу сказать не у компьютера

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

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

Оффлайн Александр Пекшев aka Modis

  • ADN Club
  • *****
  • Сообщений: 1658
  • Карма: 366
  • Отец modplus.org
    • ModPlus
Нужно пролистать окно с ошибкой
У него нет окна с ошибкой, т.к. он ее отлавливает и обрабатывает, поэтому он и не видит полный текст

melkalex90
А все из-за того, что мало знаний =) Обычно меня в этом винят  ;D
Вы сами ловите ошибку и выводите только ее сообщение:
Код - C# [Выбрать]
  1. ed.WriteMessage("\n" + ex.Message);
Поменяйте на что-то типа того:
Код - C# [Выбрать]
  1. ed.WriteMessage("\n" + ex.Message + "\n" + ex.StackTrace);
Ну или, как сказал Александр Ривилис, вы можете еще пользоваться отладкой

Оффлайн melkalex90Автор темы

  • ADN OPEN
  • **
  • Сообщений: 59
  • Карма: 0
Добрался я до компьютера.
3) Для использования MPolygon необходимо загрузить AcMPolygonObjNN.dbx  (NN зависит от версии AutoCAD) и подключить AcMPolygonMGD.dll
подключил и загрузил
Ошибку выдает на строке:
Код - C# [Выбрать]
  1. var pl = tr.GetObject(objId, OpenMode.ForWrite) as Polyline;

Вот само сообщение об ошибке:
Операция является недопустимой из-за текущего состояния объекта.
   в Autodesk.AutoCAD.DatabaseServices.Transaction.CheckTopTransaction()
   в Autodesk.AutoCAD.DatabaseServices.Transaction.GetObject(ObjectId id, OpenMode mode)
   в PlinesArea.PlineArea.Main() в D:\Projects\ClassLibrary2\ClassLibrary2\Class1.cs:строка 337

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

  • Administrator
  • *****
  • Сообщений: 13832
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Выложи полностью проект в архиве. В выложенном примере < 100 строк.
P.S.: И еще. Ты показывал код, в котором:
Код - C# [Выбрать]
  1. var pl = tr.GetObject(objId, OpenMode.ForRead) as Polyline;
А теперь оказывается, что:
Код - C# [Выбрать]
  1. var pl = tr.GetObject(objId, OpenMode.ForWrite) as Polyline;
Как же можно искать ошибки в твоём коде???

Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн melkalex90Автор темы

  • ADN OPEN
  • **
  • Сообщений: 59
  • Карма: 0
Это изменил я только что. Сейчас выложу проект полностью.

Отмечено как Решение melkalex90 31-10-2015, 23:55:26

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

  • Administrator
  • *****
  • Сообщений: 13832
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Каша у тебя в коде... Это я так очень скромно... Лишний и не в том месте tr.Commit, ну и так далее. Полностью я править не стал, так работает:
Код - C# [Выбрать]
  1. namespace PlinesArea
  2. {
  3.   public class PlineArea
  4.   {
  5.     static PlineArea()
  6.     {
  7.       AcRx.SystemObjects.DynamicLinker.LoadModule("AcMPolygonObj" + AcAp.Application.Version.Major + ".dbx", false, false);
  8.     }
  9.     public Dictionary<string, List<ObjectId>> GetObjects()
  10.     {
  11.       Document acDoc = AcAp.Application.DocumentManager.MdiActiveDocument;
  12.       Database acCurDb = acDoc.Database;
  13.  
  14.       using (Transaction acTrans = acCurDb.TransactionManager.StartTransaction())
  15.       {
  16.         BlockTable acBlTbl = (BlockTable)acTrans.GetObject(acCurDb.BlockTableId, OpenMode.ForRead);
  17.         BlockTableRecord acBlTblRec = (BlockTableRecord)acTrans.GetObject(acBlTbl[BlockTableRecord.ModelSpace], OpenMode.ForRead);
  18.         Dictionary<string, List<ObjectId>> dict = new Dictionary<string, List<ObjectId>>();
  19.  
  20.         foreach (ObjectId item in acBlTblRec)
  21.         {
  22.           if (item.IsValid && !item.IsErased)
  23.             if (!dict.Keys.Contains(item.ObjectClass.Name))
  24.               dict.Add(item.ObjectClass.Name, new List<ObjectId>() { item });
  25.             else
  26.               dict[item.ObjectClass.Name].Add(item);
  27.         }
  28.         acTrans.Commit();
  29.         return dict;
  30.       }
  31.     }
  32.     [CommandMethod("PlinesAreaToEd")]
  33.     public void Main()
  34.     {
  35.       var doc = AcApp.DocumentManager.MdiActiveDocument;
  36.       var ed = doc.Editor;
  37.       Database db = doc.Database;
  38.  
  39.       try
  40.  
  41.       {
  42.         Dictionary<string, List<ObjectId>> dict = GetObjects();
  43.         var pso = new PromptSelectionOptions();
  44.         pso.MessageForAdding = "\nSelect polylines: ";
  45.         var filList = new TypedValue[1] { new TypedValue((int)DxfCode.Start, "*POLYLINE") };
  46.         SelectionFilter sf = new SelectionFilter(filList);
  47.         PromptSelectionResult psr = ed.GetSelection(pso, sf);
  48.         if (psr.Status == PromptStatus.OK)
  49.         {
  50.           using (Transaction tr = doc.TransactionManager.StartTransaction())
  51.           {
  52.             var selSet = psr.Value;
  53.             var ids = selSet.GetObjectIds();
  54.  
  55.             int i = 1;
  56.             foreach (ObjectId objId in ids)
  57.             {
  58.               var pl = tr.GetObject(objId, OpenMode.ForRead) as Polyline;
  59.               if (pl.Closed)
  60.                 using (AcDb.MPolygon mp = new AcDb.MPolygon())
  61.                 {
  62.                   try
  63.                   {
  64.                     foreach (ObjectId item in dict["AcDbText"])
  65.                     {
  66.                       DBText text = (DBText)tr.GetObject(item, OpenMode.ForRead);
  67.                       mp.AppendLoopFromBoundary(pl, true, AcGe.Tolerance.Global.EqualPoint);
  68.                       if (mp.IsPointInsideMPolygon(new Point3d(text.Position.X, text.Position.Y,0),
  69.                         AcGe.Tolerance.Global.EqualPoint).Count > 0)
  70.                       {
  71.                         ed.WriteMessage("\n" + text.TextString + ". Площадь: " +
  72.                           (pl.Area / 1000000).ToString() +
  73.                           " Периметр: " + (pl.Length / 1000).ToString());
  74.                       }
  75.                     }
  76.                   }
  77.                   catch { }
  78.                 }
  79.             }
  80.             tr.Commit();
  81.           }
  82.         }
  83.       }
  84.       catch (System.Exception ex)
  85.       {
  86.         ed.WriteMessage("\n" + ex.Message + "\n" + ex.StackTrace);
  87.       }
  88.     }
  89.   }
  90. }



Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Александр Пекшев aka Modis

  • ADN Club
  • *****
  • Сообщений: 1658
  • Карма: 366
  • Отец modplus.org
    • ModPlus
Сейчас выложу проект полностью
ох ох ох...
Одно только наличие этих двух строк рядом
Код - C# [Выбрать]
  1. using acad = Autodesk.AutoCAD.ApplicationServices.Application;
  2. using AcApp = Autodesk.AutoCAD.ApplicationServices.Core.Application;
говорит о том, что вы совершенно не понимаете что делаете и что происходит.
Проект - это просто сборка подходящих вам примеров из интернета. Нужно учитывать, что разные люди пишут по разному. Практически у каждого более-менее опытного кодера есть своя некая стилистика. Копипаст кодов с разной стилистикой в одно место - гиблое дело.
Каша у тебя в коде... Это я так очень скромно...
Совсем чуть-чуть напишу:
1. Для проекта стоит платформа х64. Зачем? Почему? Почему не AnyCPU?
2. К проекту подключено минимум 7 библиотек, которые совершенно там не нужны
3. Для AcMPolygonMGD значение Копировать локально нужно ставить False!
Я бы вам посоветовал поставить ReSharper, но боюсь он вам только навредит...

Оффлайн melkalex90Автор темы

  • ADN OPEN
  • **
  • Сообщений: 59
  • Карма: 0
Каша у тебя в коде... Это я так очень скромно... Лишний и не в том месте tr.Commit, ну и так далее. Полностью я править не стал, так работает:
Александр, а где ошибка то была? Из за чего такое выдавало?

Оффлайн melkalex90Автор темы

  • ADN OPEN
  • **
  • Сообщений: 59
  • Карма: 0
Сейчас выложу проект полностью
ох ох ох...
Одно только наличие этих двух строк рядом
Код - C# [Выбрать]
  1. using acad = Autodesk.AutoCAD.ApplicationServices.Application;
  2. using AcApp = Autodesk.AutoCAD.ApplicationServices.Core.Application;
говорит о том, что вы совершенно не понимаете что делаете и что происходит.
Проект - это просто сборка подходящих вам примеров из интернета. Нужно учитывать, что разные люди пишут по разному. Практически у каждого более-менее опытного кодера есть своя некая стилистика. Копипаст кодов с разной стилистикой в одно место - гиблое дело.
Каша у тебя в коде... Это я так очень скромно...
Совсем чуть-чуть напишу:
1. Для проекта стоит платформа х64. Зачем? Почему? Почему не AnyCPU?
2. К проекту подключено минимум 7 библиотек, которые совершенно там не нужны
3. Для AcMPolygonMGD значение Копировать локально нужно ставить False!
Я бы вам посоветовал поставить ReSharper, но боюсь он вам только навредит...
Я примерно представляю свои проблемы с программированием. Не хватка знаний главная проблема(

Оффлайн Александр Пекшев aka Modis

  • ADN Club
  • *****
  • Сообщений: 1658
  • Карма: 366
  • Отец modplus.org
    • ModPlus
Александр, а где ошибка то была? Из за чего такое выдавало?
Александр Вам вроде ответил:
Лишний и не в том месте tr.Commit, ну и так далее

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

  • Administrator
  • *****
  • Сообщений: 13832
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Александр, а где ошибка то была? Из за чего такое выдавало?
Александр Вам вроде ответил:
Цитата: Александр Ривилис от 31-10-2015, 22:21:45

    Лишний и не в том месте tr.Commit, ну и так далее
Именно. Транзакции уже нет, а ты пытаешься с помощью неё открыть примитив. Путаница была с фигурными скобками. Честно говоря даже не хочется анализировать этот код...
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • Administrator
  • *****
  • Сообщений: 13832
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
3. Для AcMPolygonMGD значение Копировать локально нужно ставить False!
Кстати, это я тоже сразу исправил и еще поубивал кучу ссылок, которые у меня не нашлись, но не мешали компиляции.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение