склеивание различных ObjectIdCollection

Автор Тема: склеивание различных ObjectIdCollection  (Прочитано 6722 раз)

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

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

  • ADN OPEN
  • Сообщений: 32
  • Карма: 1
Здравствуйте, уважаемые форумчане! мне в свое время подсказали как найти все вставки динамического блока

http://adn-cis.org/kak-najti-vse-vstavki-dinamicheskogo-bloka.html

немного откорректировав код я получил
Код - C# [Выбрать]
  1.                                
  2.                                        
  3.                     ObjectIdCollection dynBlockRefs=null;            
  4.  
  5.                     BlockTable bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead);
  6.                     foreach (ObjectId btrId in bt)
  7.                     {
  8.                         BlockTableRecord btr = (BlockTableRecord)tr.GetObject(btrId, OpenMode.ForRead);
  9.                         if ((btr.Name.Contains("Ось")==true))
  10.                         {                            
  11.                             ObjectIdCollection anonymousIds = btr.GetAnonymousBlockIds();
  12.  
  13.                             dynBlockRefs = btr.GetBlockReferenceIds(true, true);
  14.                                                                                    
  15.                             foreach (ObjectId anonymousBtrId in anonymousIds)
  16.                             {
  17.                                 BlockTableRecord anonymousBtr = (BlockTableRecord)tr.GetObject(anonymousBtrId, OpenMode.ForRead);                              
  18.                                 ObjectIdCollection blockRefIds = anonymousBtr.GetBlockReferenceIds(true, true);
  19.                              
  20.                                 foreach (ObjectId id in blockRefIds)
  21.                                 {                                    
  22.                                     dynBlockRefs.Add(id);                                    
  23.                                 }
  24.                                
  25.                             }
  26.                         }
  27.                     }
  28.  
  29.  

очевидно, что если у меня есть таблице блоков несколько бтр с содержанием имени "Ось" то в коллекцию наберется не все ID, т.к. при нахождении нового бтр с содержанием имени "Ось" - коллекция переприсвоится

Код - C# [Выбрать]
  1. dynBlockRefs = btr.GetBlockReferenceIds(true, true);
  2.  

найти метод по склеиванию коллекций - не нашел
попробовал добавлять id по отдельности .add()

Код - C# [Выбрать]
  1.  
  2. ObjectIdCollection dynBlockRefs=null;
  3.                     ObjectIdCollection dynBlockRefsFull = null;
  4.  
  5.                     BlockTable bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead);
  6.                     foreach (ObjectId btrId in bt)
  7.                     {                      
  8.                         BlockTableRecord btr = (BlockTableRecord)tr.GetObject(btrId, OpenMode.ForRead);
  9.                         if ((btr.Name.Contains("Ось")==true))
  10.                         {
  11.                             ObjectIdCollection anonymousIds = btr.GetAnonymousBlockIds();
  12.                            
  13.                             dynBlockRefs = btr.GetBlockReferenceIds(true, true);
  14.  
  15.                             foreach (ObjectId id in dynBlockRefs)
  16.                             {
  17.                                 dynBlockRefsFull.Add(id);
  18.                             }
  19.  
  20.  
  21.                             foreach (ObjectId anonymousBtrId in anonymousIds)
  22.                             {                                
  23.                                 BlockTableRecord anonymousBtr = (BlockTableRecord)tr.GetObject(anonymousBtrId, OpenMode.ForRead);                              
  24.                                 ObjectIdCollection blockRefIds = anonymousBtr.GetBlockReferenceIds(true, true);
  25.                              
  26.                                 foreach (ObjectId id in blockRefIds)
  27.                                 {
  28.                                     dynBlockRefsFull.Add(id);                                    
  29.                                 }
  30.                                
  31.                             }
  32.                         }
  33.                     }
  34.  
  35.  

вот вообще не могу понять в чем ошибка

не понимаю почему не получается склеить несколько коллекций в одной.
Подскажите, как склеить различные коллекции dynBlockRefs  в одну dynBlockRefsFull ?

и почему возникает ошибка?


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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: склеивание различных ObjectIdCollection
« Ответ #1 : 13-11-2017, 13:58:10 »
вот вообще не могу понять в чем ошибка
и почему возникает ошибка?
Какая ошибка возникает???
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Отмечено как Решение bert 13-11-2017, 14:45:54

Оффлайн avc

  • ADN Club
  • *****
  • Сообщений: 805
  • Карма: 166
    • Мои плагины к Автокаду
Re: склеивание различных ObjectIdCollection
« Ответ #2 : 13-11-2017, 14:02:25 »
Коллекции ObjectIdCollection действительно не имеют метода AddRange поэтому вы правильно добавляете по одному. Только я не вижу у вас в коде инициализации dynBlockRefsFull . Вы у null вызываете Add
Код - C# [Выбрать]
  1. ObjectIdCollection dynBlockRefsFull = new ObjectIdCollection();

Оффлайн avc

  • ADN Club
  • *****
  • Сообщений: 805
  • Карма: 166
    • Мои плагины к Автокаду
Re: склеивание различных ObjectIdCollection
« Ответ #3 : 13-11-2017, 14:10:19 »
И сейчас суда набегут апологеты Linq и научат вас как написать все это в одну строку кода на языке лямбда выражений с кукуевой тучей конвенций массивов в списки и обратно :) А я лучше заткну беруши ;)

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

  • ADN Club
  • *****
  • Сообщений: 1658
  • Карма: 366
  • Отец modplus.org
    • ModPlus
Re: склеивание различных ObjectIdCollection
« Ответ #4 : 13-11-2017, 14:28:48 »
Подскажите, как склеить различные коллекции dynBlockRefs  в одну dynBlockRefsFull ?
Ну так вы уже это делаете
Код - C# [Выбрать]
  1. dynBlockRefs = btr.GetBlockReferenceIds(true, true);
  2.  
  3.        foreach (ObjectId id in dynBlockRefs)
  4.        {
  5.             dynBlockRefsFull.Add(id);
  6.        }
Проблема только в том, что коллекции dynBlockRefsFull у вас при этом не существует

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

  • ADN OPEN
  • Сообщений: 32
  • Карма: 1
Re: склеивание различных ObjectIdCollection
« Ответ #5 : 13-11-2017, 14:45:18 »
Какая ошибка возникает???
Александр, Фатальная ошибка: Unhandled Access Violation Reading 0x0000 Exception at 9a04faebh

Проблема и правда была в том, что я не создал новый экземпляр класса

Код - C# [Выбрать]
  1. ObjectIdCollection dynBlockRefsFull = new ObjectIdCollection();
всех благодарю за ответы

Оффлайн Дмитрий Загорулькин

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 735
Re: склеивание различных ObjectIdCollection
« Ответ #6 : 13-11-2017, 22:46:47 »
И сейчас суда набегут апологеты Linq и научат вас как написать все это в одну строку кода на языке лямбда выражений с кукуевой тучей конвенций массивов в списки и обратно
Ятд, что нельзя разочаровывать avc  ;D
Код - C# [Выбрать]
  1. List<ObjectId> dynBlockRefsFull = new List<ObjectId>();
  2.  
  3. BlockTable bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead);
  4. foreach (ObjectId btrId in bt)
  5. {
  6.     BlockTableRecord btr = (BlockTableRecord)tr.GetObject(btrId, OpenMode.ForRead);
  7.     if ((btr.Name.Contains("Ось") == true))
  8.     {
  9.         ObjectIdCollection
  10.             anonymousIds = btr.GetAnonymousBlockIds(),
  11.             dynBlockRefs = btr.GetBlockReferenceIds(true, true);
  12.  
  13.         dynBlockRefsFull.AddRange(anonymousIds.Cast<ObjectId>());
  14.         dynBlockRefsFull.AddRange(dynBlockRefs.Cast<ObjectId>());                  
  15.     }
  16. }
  17.  

Оффлайн avc

  • ADN Club
  • *****
  • Сообщений: 805
  • Карма: 166
    • Мои плагины к Автокаду
Re: склеивание различных ObjectIdCollection
« Ответ #7 : 13-11-2017, 22:56:16 »
нельзя разочаровывать avc
Пока разочарован, мало Linq ;) Даже один милый сердцу foreach выжил

Оффлайн Дмитрий Загорулькин

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 735
Re: склеивание различных ObjectIdCollection
« Ответ #8 : 14-11-2017, 12:38:11 »
Пока разочарован, мало Linq  Даже один милый сердцу foreach выжил
Ну тогда как-то так (не проверял):
Код - C# [Выбрать]
  1. BlockTable bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead);
  2.  
  3. ObjectId[] dynBlockRefsFull = bt
  4.     .Cast<ObjectId>()
  5.     .Select(btrId => tr.GetObject(btrId, OpenMode.ForRead))
  6.     .Cast<BlockTableRecord>()
  7.     .Where(btr => btr.Name.Contains("Ось"))
  8.     .SelectMany(btr =>
  9.         btr.GetAnonymousBlockIds().Cast<ObjectId>().Union
  10.         (btr.GetBlockReferenceIds(true, true).Cast<ObjectId>()))    
  11.     .ToArray();          
  12.  

Оффлайн avc

  • ADN Club
  • *****
  • Сообщений: 805
  • Карма: 166
    • Мои плагины к Автокаду
Re: склеивание различных ObjectIdCollection
« Ответ #9 : 14-11-2017, 12:59:27 »
Ну тогда как-то так
Во! Вот оно зло вселенское! Пошел за святой водой - монитор окропить :))))

Оффлайн Владимир Шу

  • ADN Club
  • *****
  • Сообщений: 611
  • Карма: 155
    • ПГСу Бложик
Re: склеивание различных ObjectIdCollection
« Ответ #10 : 14-11-2017, 13:09:58 »
Ну тогда как-то так (не проверял)
Красота то какая! Больше функциональщины!
Проверил, ошибок нет, результат идентичный перебору (с поправкой на тип массива)

Оффлайн German

  • ADN Club
  • **
  • Сообщений: 84
  • Карма: 13
Re: склеивание различных ObjectIdCollection
« Ответ #11 : 14-11-2017, 13:31:50 »
Я б немного сократил еще ))

Код - C# [Выбрать]
  1.     .Select(btrId => (BlockTableRecord)tr.GetObject(btrId, OpenMode.ForRead))
  2.  

В данном случае не важно, но иногда нужно Concat() вместо Union().

Оффлайн avc

  • ADN Club
  • *****
  • Сообщений: 805
  • Карма: 166
    • Мои плагины к Автокаду
Re: склеивание различных ObjectIdCollection
« Ответ #12 : 14-11-2017, 13:42:33 »
Понеслось!!!  ;)
Между прочим человеку нужен был на выходе ObjectIdCollection, а не ObjectId[]. Он же опять for-ом заталкивать будет ;)

не понимаю почему не получается склеить несколько коллекций в одной.
Вот вам вывод - склеить очень даже получается, но клей сильно галлюциногенный и вызывает привыкание ;)

Оффлайн Дмитрий Загорулькин

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 735
Re: склеивание различных ObjectIdCollection
« Ответ #13 : 14-11-2017, 13:51:18 »
Между прочим человеку нужен был на выходе ObjectIdCollection, а не ObjectId[].
Ну это не факт. Возможно, автор просто не знает, что можно использовать List и Array вместо ObjectIdCollection.
Даже если действительно нужна ObjectIdCollection, можно её легко создать:
Код - C# [Выбрать]
  1. ObjectIdCollection col = new ObjectIdCollection(dynBlockRefsFull);
Я б немного сократил еще ))
Я знаааал, что кто-то обязательно меня ткнёт носом в это :). Но умышленно оставил, просили же - больше Linq! :)
В данном случае не важно, но иногда нужно Concat() вместо Union().
Там и SelectMany можно использовать, как тут описано: https://msdn.microsoft.com/ru-ru/library/bb302894(v=vs.110).aspx

Оффлайн German

  • ADN Club
  • **
  • Сообщений: 84
  • Карма: 13
Re: склеивание различных ObjectIdCollection
« Ответ #14 : 14-11-2017, 14:22:25 »
Там и SelectMany можно использовать, как тут описано: https://msdn.microsoft.com/ru-ru/library/bb302894(v=vs.110).aspx
Точно!