Тема: Не получается SelectSet'ом отловить External Reference

Не могу понять, почему не работает следущий фильтр по сортировке External Reference

FilterType(0) = 0
FilterData(0) = "Block"
FilterType(1) = 70
FilterData(1) = 4

Хотя в хелпе (DXF.chm) явно указано:

Block group codes
Group code          |      Description
---------------------------------------
0                      Entity type (BLOCK)
5                      Handle
330                    Soft-pointer ID/handle to ownerobject
100                    Subclass marker (AcDbEntity)
8                      Layer name
100                    Subclass marker (AcDbBlockBegin)
2                      Block name
70                     Block-type flags (bit-coded values, may be combined):
                    0 = Indicates none of the following flags apply
                    1 = This is an anonymous block generated by hatching, associative dimensioning, other internal operations, or an application
                    2 = This block has non-constant attribute definitions (this bit is not set if the block has any attribute definitions that are constant, or has no attribute definitions at all)
                    4 = This block is an external reference (xref)
                    8 = This block is an xref overlay
                    16 = This block is externally dependent
                    32 = This is a resolved external reference, or dependent of an external reference (ignored on input)
                    64 = This definition is a referenced external reference (ignored on input)
10                    Base point DXF: X value; APP: 3D point
20, 30                 DXF: Y and Z values of base point
3                      Block name
1                      Xref path name
4                      Block description (optional)

Re: Не получается SelectSet'ом отловить External Reference

FilterType(0) = 0
FilterData(0) = "INSERT"

Re: Не получается SelectSet'ом отловить External Reference

> Александр Ривилис
Вряд ли этот фокус пройдет, нужно наверно перебирать все
примитивы по этому фильтру на предмет присутствия свойства "Path"
Сугубо, IMHO
~'J'~

Re: Не получается SelectSet'ом отловить External Reference

> Mamont
Извини, но:

FilterData(0) = "Block"

о таком не слышал, Александр Ривилис правильно
указал
~'J'~

Re: Не получается SelectSet'ом отловить External Reference

> Олег(jr.)
Безусловно. Сначала придется отобрать все вставки блоков (INSERT), а потом найти среди них XREF'ы.
BLOCK - это не примитив, а запись в символьной таблице блоков. Ее нельзя отфильтровать таким образом.
Примитивом является вставка блока или внешняя ссылка (INSERT). Вот ее как раз и можно фильтровать.

Re: Не получается SelectSet'ом отловить External Reference

> Александр Ривилис
Вот я как раз сгоряча и нарвался, тоже думал
что бит 4 все отлавливает
Ан, не все так просто:
http://discussion.autodesk.com/thread.j … dID=470919
~'J'~

Re: Не получается SelectSet'ом отловить External Reference

> Олег(jr.)
Для INSERT группа 70 означает количество колонок в мультивставке блока. Так что используя фильтр (70 . 4) таким образом можно отловить только те вставки блоков, у которых количество колонок = 4, что явно никакого отношения к внешним ссылкам не имеет. :)

Re: Не получается SelectSet'ом отловить External Reference

> Александр Ривилис
Да я это и понял, только не сразу врубился,
увидел в хэлпе бит 4 и возрадовался
(тоже сгоряча, как Mamont, сунулся смотреть DXF коды для
блока, а надоть для INSERT - совершенно справедливо)
Мое уважение
~'J'~

Re: Не получается SelectSet'ом отловить External Reference

Похоже, выход только один, но кривой:

Set objselectionset = ThisDrawing.SelectionSets.Add("Temp")
FilterType(0) = 0
FilterData(0) = "INSERT"
objselectionset.Select acSelectionSetAll, FilterType:=FilterType, FilterData:=FilterData
For Each ent In objselectionset
On Error Resume Next
    Set refm = ent
'(Dim refm As AcadExternalReference)
  If Err <> 0 Then
    Err = 0
  Else
    MsgBox (refm.Path) 'Типа, нашли
  End If
Next ent
objselectionset.delete

Re: Не получается SelectSet'ом отловить External Reference

Есть другой, более правильный способ:

Sub all_xref()
Dim mblocks As AcadBlocks
Dim mblock As AcadBlock
Dim i As Long
Set mblocks = ThisDrawing.Blocks
For Each mblock In mblocks
   If mblock.IsXRef Then
     '-------------------
     ' А здесь обыкновенный SelectionSet
     ' по имени блока  mblock.name
     ' Фильтр такой:
     '       FilterType(0) = 0
     '       FilterData(0) = "INSERT"
     '       FilterType(0) = 2
     '       FilterData(0) = mblock.Name
     '
     ' Наши действия над External Reference
     '-------------------
   End If
Next mblock
End Sub

Re: Не получается SelectSet'ом отловить External Reference

Ну а если поднапрячь мозговые извилины на все 100%, то можно изрыгнуть такой код:

dim mobj as object
dim mxref as AcadExternalReference
Set sset2 = ThisDrawing.SelectionSets.Add("M0")
FilterType2(0) = 0
FilterData2(0) = "INSERT"
sset2.Select acSelectionSetAll, FilterType:=FilterType2, FilterData:=FilterData2
For Each mobj in sset2
  if TypeOf mobj is AcadExternalReference then
    set mxref = mobj
   '---------------
   ' Наши действия над External Reference
   '---------------
  end if
next mobj

Re: Не получается SelectSet'ом отловить External Reference

> pavel
Спасибо тебе, добрый человек, уважил старика :)

Re: Не получается SelectSet'ом отловить External Reference

> pavel
Ты изрыгай почаще, хороший код...
~'J'~

Re: Не получается SelectSet'ом отловить External Reference

> Mamont
Не хочется быть "придирастом", но вопрос звучал так: Не могу понять, почему не работает следущий фильтр..., а не - Как сделать чтобы он работал?
И на Ваш вопрос исчерпывающим образом ответил Александр Ривилис (BLOCK — это не примитив, а запись в символьной таблице блоков. Ее нельзя отфильтровать таким образом.)
Хорошо, что pavel догадался о том, что имел в виду, но почему-то не сказал автор темы...
Короче, я за точную формулировку вопроса.

Re: Не получается SelectSet'ом отловить External Reference

Ну а если напрячь извилины где-то на 120%, и если они не распрямятся, то можно получить такой вариант:

Dim vEntity As AcadEntity
Dim mxref As AcadExternalReference
On Error Resume Next
For Each vEntity In ThisDrawing.ModelSpace ' или PaperSpace
    If TypeOf vEntity Is AcadExternalReference Then
    Set mxref = vEntity
    MsgBox mxref.Name
   '---------------
   '---------------
   End If
Next vEntity

Re: Не получается SelectSet'ом отловить External Reference

Я делаю вот так:

Sub select_xref()
' надо массив постоянно обнулять!!!!
ReDim xref_spisok(0)
Dim sset As AcadSelectionSet
Dim grData(0) As Integer
Dim dataValue(0) As Variant
Dim rnd_num As Double
Dim i As Integer
Dim j As Integer
Dim number As Variant
j = 1
Randomize
rnd_num = Int(100000 * Rnd)
Set sset = ThisDrawing.SelectionSets.Add("det" & (rnd_num + 1))
grData(0) = 0
dataValue(0) = "INSERT"
sset.SelectOnScreen grData, dataValue
For i = 0 To sset.Count - 1
 If TypeName(sset(i)) = "IAcadExternalReference" Then
  number = nayti_xref(sset(i).Path)
  If number Then
   xref_spisok(number).n = xref_spisok(number).n + 1
  Else
   ReDim Preserve xref_spisok(j)
   xref_spisok(j).Path = sset(i).Path
   xref_spisok(j).n = 1
   j = j + 1
  End If
 End If
Next i
Load Specificacia
Specificacia.Show
End Sub

Re: Не получается SelectSet'ом отловить External Reference

там кое что криво :)
но это сознательно ...

Re: Не получается SelectSet'ом отловить External Reference

вернее не осознанно

Re: Не получается SelectSet'ом отловить External Reference

LeonidSN пишет:

Хорошо, что pavel догадался о том, что имел в виду, но почему-то не сказал автор темы...

Я считал, что всем должно быть понятно, что, если что-то не получается, то помимо объяснения причины невозможности совершения того или иного действия, желательно предложить возможные пути решения... Ведь если бы у меня было альтернативное решение, то в форуме я такой вопрос бы не поднимал.
Разве не логично?

Re: Не получается SelectSet'ом отловить External Reference

> Mamont
В данном случае, конечно, можно понять, что желательно предложить ... ну и так далее.Но вариант обсуждения, вопрос - ответ, получился очень наглядным, и мне захотелось обратить внимание участников форума на то (повторюсь), что точность - вежливость королей.
А проблема непродуманных, неточных формулировок на этом форуме, увы, не высосана из пальца...

Re: Не получается SelectSet'ом отловить External Reference

ok
конструкцию

If TypeName(sset(i)) = "IAcadExternalReference" Then

не помню где видел, но использую ее, следую примеру на этом форуме ...
конструкцию 

if TypeOf mobj is AcadExternalReference then

к своему стыду вижу впервые ...
в чем разница? и наскока она существенна?

Re: Не получается SelectSet'ом отловить External Reference

> Сергей
TypeName(Var) - это функция, которая возвращает тип данных переменной (Integer,Byte,Long ...) а также тип объекта, как в твоем коде.
If TypeOf Is ObjectType - это оператор, который определяет тип объекта. То есть, как специализированный инструмент для работы с объектом, он в данном случае предпочтительней.
И еще один маленький совет - не стоит переопределять динамический массив в цикле. Достаточно сделать это всего два раза, перед циклом и после цикла на основании счетчика цикла.

Re: Не получается SelectSet'ом отловить External Reference

> LeonidSN
Хотел бы отметить один момент, касающийся вашего кода.
По объему, ваш код оптимальнее моего(> pavel (2006-05-10 16:05:38)), но вот по быстродействию значительно уступает (особенно, когда много объектов) :
Перебор всех объектов пространства модели занимает значительно большее время, нежели перебор объектов после фильтра "INSERT"
Это вариация на тему, что лучше оптимизировать...

Re: Не получается SelectSet'ом отловить External Reference

> pavel
Сразу же согласен на все сто.
Поэтому и назвал свой код - вариантом. Один из вариантов решения, применимый для случая, когда быстродействие не является критическим фактором.
Что касается выражения "По объему, ваш код оптимальнее моего", то в данном случае интересно не количество строк кода, а то что выполняется меньше действий с объектами чертежа и, следовательно, меньше шансов запутаться или напороться на какой-нибудь глюк.
И последнее, у вы проводили замеры быстродействия, или это оценка на глазок?

Re: Не получается SelectSet'ом отловить External Reference

> LeonidSN
Чтобы не быть балаболом и не основаться на априорные измышления привожу результаты тестов.
progr1 - автор LeonidSN (2006-05-12 13:39:36)
progr2 - автор pavel (2006-05-10 16:05:38)
Тестировались программы на P4 2,27GHz, ОЗУ 512 Мб, WinXP SP2, Autocad 2006
Для получения более точных результатов, программы были заключены в цикл(с обращением в 50 и 100 итераций). Были взяты 3 файла *.DWG с разной графической нагрузкой. В каждый из них были интегрированы 38 External Reference.
Итак:
1) Файл малой объектной загрузки:
All(23956)
Line(6714)
Block Reference(11280)
PolyLine(505)
Mtext(3428)
Circle(804)
и прочее (объкты менее 500 шт. не указываю)

Программа     50 итер    100 итер
-----------------------------------------------
progr1  [b]     0.44c        0.44c  [/b]
progr2       0.58c        0.59c
 

2)Файл средней объектной загрузки:
All(71190)
Line(43561)
Block Reference(11527)
PolyLine(5471)
Mtext(3696)
Attrib(2089)
Circle(1439)
Arc(747)
и прочее (объкты менее 500 шт. не указываю)

Программа     50 итер    100 итер
-----------------------------------------------
progr1        1c        0.99c
progr2     [b]   0.7c      0.71c  [/b]
 

3)Файл большой объектной загрузки:
All(161164)
Line(101689)
Block Reference(14208)
PolyLine(18827)
Mtext(4880)
Hatch(2831)
Attrib(4151)
Rotate Dimension(587)
Text(6989)
Circle(3566)
Arc(2223)
и прочее (объкты менее 500 шт. не указываю)

Программа     50 итер    100 итер
-----------------------------------------------
progr1       2.12c      2.1c
progr2      [b] 1.02c      1.03c [/b]
 

Интересные результаты. В файлах с малым количеством объектов программа LeonidSN(Леонида) показывает лучшие результаты, поскольку фильтр SelectionSet берет на себя "изрядную нагрузку", но как только файл начинает загружатся большим количеством объектов и соотношение(все блоки/все объекты) становится все меньше моя прога начинает явно выбиваться в лидеры.
Итого, однозначного выбора между программами сделать я не могу по двум причинам:
1) встречаются проекты с самой разной объектовой загрузкой, причем боюсь 45/45 это средние и малые, и только 10 большие
2) разница в 0,3-1 сек. считаю вообще не существенной
для тех у кого(больше 2,2 Ггц :)))
Так что, Леонид, я мужественно жму вам руку и предлагаю ничью!!! :)))