Доработка формы поиска

Автор Тема: Доработка формы поиска  (Прочитано 5950 раз)

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

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

  • ADN OPEN
  • Сообщений: 8
  • Карма: 0
Доработка формы поиска
« : 16-07-2024, 07:59:51 »
Доброго времени суток!
Дорабатываю свою программу по поиску текста на чертеже. МТекст и обычный текст ищет, но в блоках не ищет. Как можно пройтись по ModelSpace и обратиться к тексту в блоках и найти текст в блоках??. С выводом результата поиска в блоках в datagridwiew
Собственно код как у меня написан поиск текста.
Код - C# [Выбрать]
  1.         foreach (AcadLayout item in (IAcadLayouts)layouts)
  2.             {
  3.                 AcadLayout val = item;
  4.  
  5.                 IAcadBlock block = val.Block;
  6.  
  7.                 foreach (AcadEntity item2 in block)
  8.                 {
  9.                
  10.                     AcadEntity val2 = item2;
  11.  
  12.  Grid.Rows.Add(text3, name, handle, Conversions.ToString(checked(Grid.Rows.Count - 0)));
  13.  
  14.  
« Последнее редактирование: 17-07-2024, 03:06:05 от Александр Ривилис »

Оффлайн avc

  • ADN Club
  • *****
  • Сообщений: 816
  • Карма: 166
    • Мои плагины к Автокаду
Re: Доработка формы поиска
« Ответ #1 : 16-07-2024, 08:09:37 »
Я бы порекомендовал не по модели искать, по всем блокам. Открыть таблицу блоков (BlockTable) и перебрать все блоки (BlockTableRecord) и их содержимое. А уж дальше по желанию - выводить в список только блоки вставленные в модель или все подряд. Для каждой BTR можно посмотреть все ее ссылки (BlockReference)
 - метод GetBlockReferenceIds

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

  • ADN OPEN
  • Сообщений: 8
  • Карма: 0
Re: Доработка формы поиска
« Ответ #2 : 16-07-2024, 09:10:48 »
Вот так


Код - C# [Выбрать]
  1. HostMgd.ApplicationServices.Document doc = HostMgd.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
  2. Database dbase = doc.Database;
  3.  
  4. using (Transaction trans = dbase.TransactionManager.StartTransaction())
  5. {
  6.     BlockTable blockTable = trans.GetObject(dbase.BlockTableId, Teigha.DatabaseServices.OpenMode.ForRead) as BlockTable;
  7.  
  8.     foreach (ObjectId blockRecId in blockTable)
  9.     {
  10.         BlockTableRecord blockRec = trans.GetObject(blockRecId, Teigha.DatabaseServices.OpenMode.ForRead) as BlockTableRecord;
  11.  
  12.         foreach (ObjectId entId in blockRec)
  13.         {
  14.  

AcadEntity не принимает значений ObjectId. Как вывести блочный текст найденный в datagridview?

« Последнее редактирование: 17-07-2024, 03:06:52 от Александр Ривилис »

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

  • ADN Club
  • *****
  • Сообщений: 624
  • Карма: 158
    • ПГСу Бложик
Re: Доработка формы поиска
« Ответ #3 : 16-07-2024, 12:31:37 »
Kirill2001, Вас вот за это "Teigha" на этом форуме сильно приветливо не встретят...
А так, для проверки типа объекта, совсем не обязательно его открывать:
if (id.ObjectClass != Rtm.RXObject.GetClass(typeof(Db.MText))) , а выяснив тип объекта,
можно его открывать не как Entity, а как Mtext или какие еще у вас там должны быть объекты

А и еще, нужно понимать разницу между СОМ объектам и .NET и если их смешиваешь, то делай это осознано.

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

  • ADN OPEN
  • Сообщений: 8
  • Карма: 0
Re: Доработка формы поиска
« Ответ #4 : 16-07-2024, 15:14:49 »
Можно пожалуйста по конкретнее, как по средствам Odax можно получить доступ к описанию блоков через AcadEntity, IAcadBlock  ?
Код - C# [Выбрать]
  1.  
  2. AcadLayouts layouts = ModuleZoom.ThisDrawing.Layouts;
  3.  IAcadBlock block = val.Block;
  4.  
  5.   foreach (AcadEntity item2 in block)
  6.   {
  7.  
  8.       AcadEntity val2 = item2;
  9.  
Так у меня не получается добраться до текста в блоках. Как этот код использовать if (id.ObjectClass != Rtm.RXObject.GetClass(typeof(Db.MText))) не очень понимаю
« Последнее редактирование: 17-07-2024, 03:07:37 от Александр Ривилис »

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

  • ADN Club
  • *****
  • Сообщений: 624
  • Карма: 158
    • ПГСу Бложик
Re: Доработка формы поиска
« Ответ #5 : 16-07-2024, 16:12:49 »
Вот это очень, очень упрощенный код... специально написанный, как можно проще и понятнее для Вас.
Правильнее делать по другому, но судя по Вашим вопросам, лучше вот так.

Код - C# [Выбрать]
  1.       App.Document doc = App.Application.DocumentManager.MdiActiveDocument;
  2.       Db.Database db = doc.Database;
  3.       Ed.Editor ed = doc.Editor;
  4.  
  5.       Db.ObjectId modelSpaceId = Db.SymbolUtilityServices.GetBlockModelSpaceId(db);
  6.  
  7.       using (Db.Transaction tr = db.TransactionManager.StartTransaction())
  8.       {
  9.         //Открываем пространство модели
  10.         using (var ms = tr.GetObject(modelSpaceId, Db.OpenMode.ForRead) as Db.BlockTableRecord)
  11.         {
  12.           //Перебираем все объекты в модели
  13.           foreach (Db.ObjectId entId in ms)
  14.           {
  15.             //если не блок, то пропускаем
  16.             if (entId.ObjectClass != Rtm.RXObject.GetClass(typeof(Db.BlockReference))) continue;
  17.  
  18.             Db.ObjectId btrId = Db.ObjectId.Null;
  19.  
  20.             //Открываем блок и получаем ссылку на его описание
  21.             using (var br = tr.GetObject(entId, Db.OpenMode.ForRead) as Db.BlockReference)
  22.             {
  23.               btrId = br.BlockTableRecord;
  24.             }
  25.  
  26.             //Открывает описание блока
  27.             using (var btr = tr.GetObject(btrId, Db.OpenMode.ForRead) as Db.BlockTableRecord)
  28.             {
  29.               //Перебираем содержимое описания блока
  30.               foreach (Db.ObjectId id in btr)
  31.               {
  32.                 //Если это не текст, то пропускаем
  33.                 if (id.ObjectClass != Rtm.RXObject.GetClass(typeof(Db.MText))) continue;
  34.  
  35.                 //Открываем текст и получаем его содержимое
  36.                 using (var mtext = tr.GetObject(id, Db.OpenMode.ForRead) as Db.MText)
  37.                 {
  38.                   //Содержимое текста
  39.                   string text = mtext.Contents.ToString();
  40.                 }
  41.               }
  42.             }
  43.           }
  44.         }
  45.  
  46.         tr.Commit();
  47.       }

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

  • ADN OPEN
  • Сообщений: 8
  • Карма: 0
Re: Доработка формы поиска
« Ответ #6 : 17-07-2024, 11:31:48 »
Спасибо)! Пытаюсь вывести результаты поиска в datagriview криво выводит.
Код - C# [Выбрать]
  1.  Grid.Rows.Add(text5, Conversions.ToString(checked(Grid.Rows.Count - 0)));
Может надо создать отдельный класс для поиска блоков.

Код - C# [Выбрать]
  1.                                AcadEntity val2 = item2;
  2.  
  3. if (LikeOperator.LikeString(Versioned.TypeName(val2), "*IAcad*Text*", CompareMethod.Binary) && LikeOperator.LikeString(Strings.LCase(Cable_Net.Привести_к_Русскому_без_пробелов(Conversions.ToString(NewLateBinding.LateGet(val2, null, "TextString", new object[0], null, null, null)))), pattern, CompareMethod.Binary))
  4.  
  5.                                {
  6.                                    ModuleZoom.Найдено = true;
  7.  
  8. string text3 = ((!LikeOperator.LikeString(Versioned.TypeName(val2), "IAcadMText*", CompareMethod.Binary)) ? Conversions.ToString(NewLateBinding.LateGet(val2, null, "TextString", new object[0], null, null, null)) : searchBox.Text);
  9.  
  10.                                    string name = val.Name;
  11.                                    string handle = val2.Handle;
  12.  
  13.              Grid.Rows.Add(text3, name, handle, Conversions.ToString(checked(Grid.Rows.Count - 0)));
  14.  
  15.                                }
  16.                            }
  17.                        }

Подскажите пожалуйста как результаты поиска в блоках встроить в мой уже существующий поиск. У меня получается пересечение каша. И поиск тормозит 5 сек на одну позицию ?
« Последнее редактирование: 17-07-2024, 17:13:22 от Александр Ривилис »

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

  • ADN Club
  • *****
  • Сообщений: 624
  • Карма: 158
    • ПГСу Бложик
Re: Доработка формы поиска
« Ответ #7 : 17-07-2024, 12:23:02 »
Kirill2001, если Вы хотите получить помощь, то прикладывайте полный код в котором у Вас возникают проблемы, а не какие-то непонятные обрывки.  Уважайте чужое время, это Вам нужно, что бы другие люди смогли запустить Ваш код у себя и подсказали Вам, что нужно поправить.

Оффлайн trir

  • ADN Club
  • ****
  • Сообщений: 475
  • Карма: 63
Re: Доработка формы поиска
« Ответ #8 : 17-07-2024, 13:36:48 »
Что значит искать в блоках? Искать в описании или атрибутах?
Если искать в описании - сначала получаем список описаний блоков, а потом для найденных описаний - находим вставки (если они есть)

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

  • ADN OPEN
  • Сообщений: 8
  • Карма: 0
Re: Доработка формы поиска
« Ответ #9 : 17-07-2024, 14:26:48 »
Нужен Текст и Мтекст получается в описании искать. Атрибуты не нужны (настройки). Получается нужно описание, например - в блоке "50 шп. смотри в нос" и таких блоков и выносок много

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

  • Administrator
  • *****
  • Сообщений: 13877
  • Карма: 1785
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Доработка формы поиска
« Ответ #10 : 17-07-2024, 17:15:16 »
Kirill2001,
Прочитай правило форматирования кода на нашем форуме и неукоснительно соблюдай его. Мне надоело править твой текст.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN OPEN
  • Сообщений: 8
  • Карма: 0
Re: Доработка формы поиска
« Ответ #11 : 18-07-2024, 18:51:08 »
Спасибо! Вопрос решился. Код работает

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

  • ADN OPEN
  • Сообщений: 8
  • Карма: 0
Re: Доработка формы поиска
« Ответ #12 : 25-07-2024, 10:57:40 »
Не пойму, что делал неправильно вот код без транзакций, блоки находи. Но теперь местоположение layouts не показывает при нажатии на найденную позицию в datagridview. Мтекст находит но символы в ячейке datagridview  отображаются пустыми


Код - C# [Выбрать]
  1. foreach (AcadLayout item in (IAcadLayouts)layouts)
  2.                 {
  3.                         AcadLayout val = item;
  4.                         AcadBlock block = ((IAcadLayout)val).Block;
На выходе получаю одинаковые строки если добавить AcadLayout


Код - C# [Выбрать]
  1. AcadLayouts layouts = ModuleZoom.ThisDrawing.Layouts;
  2. foreach (AcadBlock item in ModuleZoom.ThisDrawing.Blocks)
  3. {
  4.     AcadBlock val = item;
  5.  
  6.     foreach (AcadEntity item2 in val)
  7.     {
  8.         AcadEntity val2 = item2;
  9. internal static void ActivViePortLock()
  10. {
  11.     if (LikeOperator.LikeString(ThisDrawing.ActiveLayout.Block.Name, "*Paper*", CompareMethod.Binary) && ThisDrawing.MSpace)
  12.     {
  13.         ThisDrawing.MSpace = false;
  14.     }
  15.            string name = val.Name;
  16.  
  17.            string handle = val2.Handle;
  18.  
  19. Grid.Rows.Add(text3, name, handle, Conversions.ToString(checked(Grid.Rows.Count - 0)));
  20.  

Как сделать так что бы и блоки искало и местоположение показывало при нажатии на найденный текст в ячейке :) ?

Оффлайн Алексей Кулик

  • Administrator
  • *****
  • Сообщений: 1111
  • Карма: 173
Re: Доработка формы поиска
« Ответ #13 : 26-07-2024, 10:46:49 »
Не пойму, что делал неправильно вот код без транзакций, блоки находи. Но теперь местоположение layouts не показывает при нажатии на найденную позицию в datagridview. Мтекст находит но символы в ячейке datagridview  отображаются пустыми


Код - C# [Выбрать]
  1. foreach (AcadLayout item in (IAcadLayouts)layouts)
  2.                 {
  3.                         AcadLayout val = item;
  4.                         AcadBlock block = ((IAcadLayout)val).Block;
На выходе получаю одинаковые строки если добавить AcadLayout


Код - C# [Выбрать]
  1. AcadLayouts layouts = ModuleZoom.ThisDrawing.Layouts;
  2. foreach (AcadBlock item in ModuleZoom.ThisDrawing.Blocks)
  3. {
  4.     AcadBlock val = item;
  5.  
  6.     foreach (AcadEntity item2 in val)
  7.     {
  8.         AcadEntity val2 = item2;
  9. internal static void ActivViePortLock()
  10. {
  11.     if (LikeOperator.LikeString(ThisDrawing.ActiveLayout.Block.Name, "*Paper*", CompareMethod.Binary) && ThisDrawing.MSpace)
  12.     {
  13.         ThisDrawing.MSpace = false;
  14.     }
  15.            string name = val.Name;
  16.  
  17.            string handle = val2.Handle;
  18.  
  19. Grid.Rows.Add(text3, name, handle, Conversions.ToString(checked(Grid.Rows.Count - 0)));
  20.  

Как сделать так что бы и блоки искало и местоположение показывало при нажатии на найденный текст в ячейке :) ?
Очень похоже на работу с CAD через COM вместо того, чтоб работать "напрямую". Напоминает вырезание гланд автогеном.
---
Добавлено: и есть логический вопрос - один и тот же текст входит в описания 2 разных блоков. Первый вставлен 2 раза - один раз в пространстве модели, второй раз - внутри третьего блока. Второй блок вообще не имеет вхождений. Чего делать надо?
Все, что сказано - личное мнение.

Правила форума существуют не просто так!

Приводя в сообщении код, не забывайте про его форматирование!

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

  • ADN OPEN
  • Сообщений: 8
  • Карма: 0
Re: Доработка формы поиска
« Ответ #14 : 26-07-2024, 11:37:51 »
Как привести val2 ?  И дальше прогнать по алгоритму приведенному ниже. И вывести в грид найденное в чертеже в описании блоков(мтекст, текст).
Код - C# [Выбрать]
  1. if (LikeOperator.LikeString(Versioned.TypeName(val2), "*IAcad*Text*", CompareMethod.Binary) && LikeOperator.LikeString(Strings.LCase(Cable_Net.Привести_к_Русскому_без_пробелов(Conversions.ToString(NewLateBinding.LateGet(val2, null, "TextString", new object[0], null, null, null)))), pattern, CompareMethod.Binary))
  2.  
  3.                     {
  4.                  ModuleZoom.Найдено = true;
  5.  
  6.  string text3 = ((!LikeOperator.LikeString(Versioned.TypeName(val2), "IAcadMText*", CompareMethod.Binary)) ? Conversions.ToString(NewLateBinding.LateGet(val2, null, "TextString", new object[0], null, null, null)) : searchBox.Text);
  7.  string name = val.Name;
  8.  
  9.  string handle = val2.Handle;
  10.  
  11.  Grid.Rows.Add(text3, name, handle, Conversions.ToString(checked(Grid.Rows.Count - 0)));
  12.  

У меня находит текст на чертеже и даже местоположение указывает, если итерацию в layout задать . Только найденные значения повторяются по много раз.  Итерация не заканчивается. На чертеже находит больше 70к объектов