Selection set на блоки по значению атрибута (VBA)
Реклама i
| Правила | Регистрация | Пользователи | Сообщения за день |  Справка по форуму | Файлообменник |

Вернуться   Форум DWG.RU > Программное обеспечение > Программирование > Selection set на блоки по значению атрибута (VBA)

Selection set на блоки по значению атрибута (VBA)

Ответ
Поиск в этой теме
Непрочитано 10.09.2010, 14:47 #1
Selection set на блоки по значению атрибута (VBA)
Pitonio
 
Регистрация: 10.09.2010
Сообщений: 3

Здравствуйте!

Суть в следующем: Есть чертеж, в котором несколько блоков с несколькими атрибутами каждый. Требуется выбрать блок (AcadBlockReference), у которого атрибут "A" имеет значение "B". До этого программа выбирала все блоки с атрибутами (в Selection set), а потом перебирала каждый блок и смотрела в нем атрибуты (For Each ... GetAttributes ... For Each ...). Все работало достаточно быстро, когда был всего один атрибут у каждого блока. Но теперь и количество блоков и количество атрибутов выросло, все работает жутко медленно.

Что я пытался:
Диагонально скурив спецификацию формата DXF, нашел, что если EntityType у нас 'INSERT' (далее цитата) значение, которое следует за группой 66, равно 1, то ожидается, что атрибуты (ATTRIB) следуют за элементом INSERT. (Конец цитаты). Пытался и так:

Код:
[Выделить все]
    FilterType[0] := 0;
    FilterData[0] := 'INSERT';
    FilterType[1] := 66;
    FilterData[1] := 1;
    FilterType[2] := 0;
    FilterData[2] := 'ATTRIB';
    FilterType[3] := 1; //Значение атрибута
    FilterData[3] := 'B';
    FilterType[4] := 2; //Tag атрибута 
    FilterData[4] := 'A';
    FilterType[5] := 0;//без этого тоже не работает
    FilterData[5] := 'SEQEND';//без этого тоже не работает
и сяк:
Код:
[Выделить все]
    FilterType[0] := 0;
    FilterData[0] := 'INSERT';
    FilterType[1] := 66;
    FilterData[1] := 1;
    FilterType[2] := -4;
    FilterData[2] := '<and';
    FilterType[3] := 0;
    FilterData[3] := 'ATTRIB';
    FilterType[4] := 1;
    FilterData[4] := 'B';
    FilterType[5] := 2;
    FilterData[5] := 'A';
    FilterType[6] := -4;
    FilterData[6] := 'and>';
    FilterType[7] := 0;
    FilterData[7] := 'SEQEND';
и остальные извращения в этом роде, но все-равно SelectionSet.Count = 0.

Если кто что-то насчет этого знает, или имеет идеи как это сделать по другому, прошу, направьте на путь.
Заранее Спасибо!
P.S.: Код на Делфи, но смысл, я думаю понятен.
Просмотров: 7977
 
Непрочитано 12.09.2010, 13:06
#2
Дима_

Продуман
 
Регистрация: 22.02.2007
Питер
Сообщений: 2,839


А зачем ты из делфи лезишь в DXF - он более для автолиспа подходит - с наружи я бы точно использовал объектную модель. Скорость по твоему алгоритму упадет в число раз равное колличеству аттрибутов. Переделвывай чтоб проверяла за один "проход" все аттрибуты.
p.s. ну и заодно проверь не вылезаешь-ли ты с проверками за seqend.
__________________
Когда в руках молоток все вокруг кажется гвоздями.
Дима_ вне форума  
 
Непрочитано 12.09.2010, 13:57
#3
Александр Ривилис

программист, рыцарь ObjectARX
 
Регистрация: 09.05.2005
Киев
Сообщений: 2,413
Отправить сообщение для Александр Ривилис с помощью Skype™


Цитата:
Сообщение от Pitonio Посмотреть сообщение
Если кто что-то насчет этого знает, или имеет идеи как это сделать по другому, прошу, направьте на путь.
Фильтр по имени атрибута в принципе не работает (т.к. атрибут - ATTRIB не самостоятельный примитив, а связан со вставкой блока). Поэтому ты должен сначала отфильтровать все вставки блоков с группой 66 не равной 0, а затем уже самостоятельно отобрать вставки блоков с нужными атрибутами. Иначе никак.
Александр Ривилис вне форума  
 
Автор темы   Непрочитано 18.09.2010, 20:01
#4
Pitonio


 
Регистрация: 10.09.2010
Сообщений: 3


Спасибо за ответы.

Цитата:
Сообщение от Дима_ Посмотреть сообщение
А зачем ты из делфи лезишь в DXF - он более для автолиспа подходит - с наружи я бы точно использовал объектную модель
Я объектную модель и использую, просто в методе Select у объекта Selection Set есть атрибуты FilterType и FilterData, которые задаются "при помощи" формата DXF.

Цитата:
Сообщение от Дима_ Посмотреть сообщение
Переделвывай чтоб проверяла за один "проход" все аттрибуты.
А вот это уже интересней. Как получить список всех атрибутов у всех блоков и потом, найдя нужную пару (атрибут - значение), выбрать блок, в котором этот атрибут? У меня возникали идеи создать небольшую базу данных, которая будет заполняться при первом открытии чертежа и будет содержать внутренний идентификатор блока, атрибуты и их значения. Но это долго и проблематично.


Цитата:
Сообщение от Александр Ривилис Посмотреть сообщение
Поэтому ты должен сначала отфильтровать все вставки блоков с группой 66 не равной 0, а затем уже самостоятельно отобрать вставки блоков с нужными атрибутами. Иначе никак.
Ну я так и делаю. Получается два цикла: первый - перебор всех блоков, второй перебор атрибутов в каждом блоке. Когда атрибутов всего один, программа работает быстро, а когда больше... один блок может искать две минуты...
Pitonio вне форума  
 
Непрочитано 18.09.2010, 21:25
#5
Олег (jr.)

специалист по околачиванию грушевых деревьев
 
Регистрация: 14.09.2004
Pietari, Venäjä
Сообщений: 811


Цитата:
Сообщение от Pitonio Посмотреть сообщение
Ну я так и делаю.
Вот ты и делаешь совершенно не так
Слушай что тебе говорят
Другого метода (как советует А.Ривилис) нет и точка
Олег (jr.) вне форума  
 
Непрочитано 18.09.2010, 21:42
#6
Кулик Алексей aka kpblc
Moderator

LISP, C# (ACAD 200[9,12,13,14])
 
Регистрация: 25.08.2003
С.-Петербург
Сообщений: 40,432


Pitonio, попробуй такой алгоритм:
1. Получить набор блоков, имеющих атрибуты (FilterType(0) = 66: FilterData(0) = 1)
2. Добавить новый набор (естественно, именованный) или массив блоков - в зависимости от того, что собираешься с ним дальше делать.
3. В цикле по первому набору для каждого блока получаешь Variant его атрибутов (и обычных, и постоянных).
4. Проверяешь, есть ли в полученном (п.3) массиве нужный атрибут с нужным значением. Если есть, помещаешь указатель на вхождение блока в набор / массив из п.2
5. По окончании получаешь набор или массив блоков, удовлетворяющих твоим условиям.
---
Лисповой код специально не пишу - только запутаю.
__________________
Моя библиотека lisp-функций
---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Кулик Алексей aka kpblc вне форума  
 
Автор темы   Непрочитано 24.09.2010, 00:28
#7
Pitonio


 
Регистрация: 10.09.2010
Сообщений: 3


Спасибо, Алексей.
Лисповый код действительно мне бы не помог. А вот блок-схема - в самый раз.

Прочитал предложенный тобой алгоритм 26 раз. Пришел к выводу, что он схож с моим (либо я что-то недопонял). Опять же два цикла (один в п.3 - перебор вхождений блоков, второй - в п.4 - перебор значений атрибутов (он вложен в цикл из п.3)). Механизм получения набора блоков интересен, но блок с искомым значением атрибута должен быть всего один на чертеже (условия построения чертежа).
Вот если бы сразу можно было выцепить все атрибуты (объекты типа IACADAttribute), найти нужный и из него получить вхождение блока, в котором он обозначен.
Может быть прояснит дело описание того, что должна делать моя программа. Так вот:
Есть значение (текстовое), которое является значением атрибута с именем Name (имя атрибута постоянно) вхождения блока. Программа должна подсветить (Hilight) и приблизить (Zoom) блок, с искомым значением атрибута Name. Блоков на чертеже больше 40, атрибутов у каждого блока больше 10 (помимо атрибута Name).

1. Я делаю фильтр (Selection Set) на все блоки с атрибутами.
2. <перебираю блоки из Selection Set>
3. __У блока вызываю метод GetAttributes, получаю массив атрибутов;
4. __<перебираю атрибуты>
5. ____Проверяю имя и значение атрибута на соответствие искомым параметрам;
6. ____Если соответствуют, выходим из всех циклов
7. __</перебираю атрибуты>
8. </перебираю блоки из Selection Set>

Где < >, </> - границы цикла.

Спасибо всем за помощь.
Pitonio вне форума  
Ответ
Вернуться   Форум DWG.RU > Программное обеспечение > Программирование > Selection set на блоки по значению атрибута (VBA)



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Express Tools Perezz!! AutoCAD 483 13.02.2015 10:57
Выдавливание вдоль линии (VBA) Markiza-2010 Программирование 4 29.03.2010 02:36
Разбиение черечежа откоса на геологические блоки в VBA Skyper Программирование 1 18.03.2010 08:54
как с помощью vba начертить линию vasyavip Программирование 77 09.10.2008 23:17
Femap и VBA Makson Программирование 11 05.08.2008 14:54