Тема: Как добавить в набор только блоки?

Сделал программу по составлению спецификации в EXCEL. Обрабатываю файлы DWG. Учитываются блоки с атрибутами.
Делаю так:

... ' работаем с открытым в фоновом режиме файлом DWG из Excel'я
Set elem = ACADApp
For Each elem In ACADApp.ActiveDocument.ModelSpace
    With elem
        If .EntityName = "AcDbBlockReference" Then
....
        End If
    End With
Next elem

Работает ужасно долго, т.к. перебирает все элементы чертежа.
В другой своей программе использую код, который нашел на просторах этого форума:

Public elem As Object
...
Sub ОбработкаТекущегоЛистаACAD(i As Integer)
Set elem = ACADApp
Dim objSelSet
Dim objSelCol
Dim intType(0) As Integer
Dim varData(0) As Variant
...
BlockName = "Штамп"
Set objSelCol = ACADApp.ActiveDocument.SelectionSets
For Each objSelSet In objSelCol
    If objSelSet.Name = "BlockSelect" Then
        objSelSet.Delete
        Exit For
    End If
Next
Set objSelSet = objSelCol.add("BlockSelect")
intType(0) = 2
varData(0) = BlockName
objSelSet.Select 5, filtertype:=intType, filterdata:=varData
For Each elem In objSelSet
    If elem.EntityName = "AcDbBlockReference" Then 'проверяем на всякий случай
                                                   '(а вдруг что не так?)
        With elem
        ...
        End With
    End If
Next elem

Код работает только с блоками с именем "Штамп". Естественно, что этот код намного быстрее.
Попытался изменить свой первый код, но без указания конкретного имени блока, т.к. нужны все блоки (ну почти все, но отбраковка идет уже потом).
Пробовал убирать из строки формирования выборки упоминание об имени блока, но не пошло:
Было

objSelSet.Select 5, filtertype:=intType, filterdata:=varData

Делал так:

objSelSet.Select 5, filtertype:=intType

Подскажите - как правильно сделать выборку из блоков?

Re: Как добавить в набор только блоки?

Во втором варианте кода попробуй вместо:

intType(0) = 2
varData(0) = BlockName

использовать

intType(0) = 0
varData(0) = "INSERT"

Re: Как добавить в набор только блоки?

> Александр Ривилис
Если как он говорит что блоки с атрибутами, то
лучше использовать такой фильтр:

Dim intType(0 to 1) As Integer
Dim varData(0 to 1) As Variant
intType(0) = 0
varData(0) = "INSERT"
intType(1) = 66
varData(1) = 1

Если выбор блоков по имени, тогда добавить
в фильтр:

Dim intType(0 to 2) As Integer
Dim varData(0 to 2) As Variant
intType(0) = 0
varData(0) = "INSERT"
intType(1) = 2
varData(1) = "Штамп"
intType(2) = 66
varData(2) = 1

Правда, тут код (66 . 1) можно и опустить, поскольку и так знаешь
что в штампе у тебя атрибуты
Следующий кусок вообще не нужен, фильтр выбирает только
блоки с атрибутами, поэтому излишняя проверка
не нужна:

For Each elem In objSelSet
    If elem.EntityName = "AcDbBlockReference" Then

Лучше сразу так (причем переменная ведь elem уже задана ранее
уже как AcadApplication:

Set elem = ACADApp

причем здесь блоки???)
Задавай так:

Dim ent as AcadEntity

или неявно:

Dim ent as Object

Тогда код должен выглядеть так:

Dim blk as AcadBlockReference
For Each ent In objSelSet
Set blk=ent
dim atts as variant
atts=blk.GetAttributes
Dim i as integer
Dim attobj as AcadAttributeReference
For LBound(atts) to UBound(atts)
Set attobj=atts(i)
...
и тд
Next
Next

~'J'~

Re: Как добавить в набор только блоки?

Если Учитываются блоки с атрибутами.
то имеет смысл поставить дополнительный фильтр:

Sub TestBlockSet()
    Dim objSelSet As AcadSelectionSet
    On Error Resume Next
    ThisDrawing.SelectionSets("MySet").Delete
    Set objSelSet = ThisDrawing.SelectionSets.Add("MySet")
    Dim mode As Integer
    mode = acSelectionSetAll
    Dim intType(0 To 3) As Integer
    Dim varData(0 To 3) As Variant
    intType(0) = -4: varData(0) = "<AND"
    intType(1) = 0: varData(1) = "INSERT"
    intType(2) = 66: varData(2) = 1
    intType(3) = -4: varData(3) = "AND>"
    objSelSet.Select mode, Filtertype:=intType, filterdata:=varData
    'MsgBox Err.Description

Re: Как добавить в набор только блоки?

> Fatty
Н-да... У кого это мысли сходятся?

Re: Как добавить в набор только блоки?

> LeonidSN
У тебя красивше :)
~'J'~

Re: Как добавить в набор только блоки?

Помогите пожалуйста отредактировать программный код.
Мне надо создать блок из круга с диаметром 2,25.
Чтобы его имя складывалось из элементов моей формы.
ИМЯ БЛОКА = Label, TextBox1, TextBox2,TextBox3.
Никак не получается. Как создавать блоки???
Я нашел только этот пример...
'Вставка блока с атрибутом
'Пример вставки в чертеж высотной отметки
Sub InsertBlockAtr()
Dim attributeObj As AcadAttribute
Dim height As Double
Dim mode As Long
Dim tag As String
Dim value As String
Dim prompt As String
Dim insPoint(0 To 2) As Double
'Создание блока
Dim blockObj As AcadBlock
Dim insertionPnt(0 To 2) As Double
insertionPnt(0) = 55#: insertionPnt(1) = -11.5: insertionPnt(2) = 0#
Set blockObj = ThisDrawing.Blocks.Add(insertionPnt, "Otmetka")
'Создание Атрибута в блоке
height = 7.5
mode = acAttributeModeVerify
prompt = "Отметка"
insPoint(0) = -50#: insPoint(1) = 17#: insPoint(2) = 0
tag = "0.000"
value = "0.000"
Set attributeObj = blockObj.AddAttribute(height, mode, prompt, insPoint, tag, value)
'Создание Полилинии в блоке
Dim plineObj As AcadLWPolyline
Dim points(0 To 13) As Double
points(0) = 4: points(1) = -5.5
points(2) = 0.5: points(3) = -5.5
points(4) = 4: points(5) = -11.5
points(6) = 7.5: points(7) = -5.5
points(8) = 4: points(9) = -5.5
points(10) = 4: points(11) = 3.5
points(12) = 40: points(13) = 3.5
Set plineObj = blockObj.AddLightWeightPolyline(points)
'Создание линии в блоке
Dim lineObj As AcadLine
Dim startPoint(0 To 2) As Double
Dim endPoint(0 To 2) As Double
startPoint(0) = 0.5: startPoint(1) = -11.5: startPoint(2) = 0#
endPoint(0) = 55#: endPoint(1) = -11.5: endPoint(2) = 0#
Set lineObj = blockObj.AddLine(startPoint, endPoint)
'Вставка блока в чертеж
Dim blockRefObj As AcadBlockReference
Dim InsertPnt As Variant
InsertPnt = ThisDrawing.Utility.GetPoint _
(, vbCrLf & "Укажите точку вставки:")
Set blockRefObj = ThisDrawing.ModelSpace.InsertBlock _
(InsertPnt, "Otmetka", 1#, 1#, 1#, 0)
attributeObj.Delete
End Sub

Re: Как добавить в набор только блоки?

К сожалению, по варианту

> LeonidSN
ничего не получилось, т.к. использую позднее связывание из Excel. Соответственно, все вот это не работает:

Dim objSelSet As AcadSelectionSet
ThisDrawing.SelectionSets("MySet").Delete
Set objSelSet = ThisDrawing.SelectionSets.Add("MySet")
mode = acSelectionSetAll

Взял на вооружение код > Fatty (2008-01-09 19:49:28)

Re: Как добавить в набор только блоки?

> Loner Wanderer
Позднее связывание здесь не при чем.
Если ты (не возражаешь, что на "ты"?) буквально вставил этот код, то это неправильно с точки зрения клиент-серверной архитектуры. Я выложил код для VBA полагая, что ты его адаптируешь под вызов из сторонней программы (Exel). Вот классический вариант обращения к AutoCAD как к серверу:

Option Explicit
Public app As Object
Sub Main()
    On Error Resume Next
    Set app = GetObject(, "AutoCAD.Application")
    If Err Then
        Set app = CreateObject("AutoCAD.Application")
    End If
    Dim MyDrawing As AcadDocument
    Set MyDrawing = app.ActiveDocument
    Dim ss As AcadSelectionSet
    MyDrawing.SelectionSets("MySet").Delete
    Set ss = MyDrawing.SelectionSets.Add("MySet")
End Sub

Обрати внимание на определение объекта MyDrawing.
Кроме того, имеют место нюансы связанные с версией AutoCAD'а к которому ты обращаешься.
Если это AutoCAD2006, например, то вместо "AutoCAD.Application" следует писать "AutoCAD.Application.16.2"
Ну и последнее. Мы с Fatty предложили (не сговариваясь и одновременно) не разные варианты, а один и тот же - фильтр с использованием DXF-кода 66 = 1.