Тема: Как добраться до существующего BlockReference?

Господа
На чертеже существует BlockReference с именем "Corner_Stamp_2"
Мне необходимо добраться до его атрибутов. Найти блок с заданным именем мне удалось. А вот как получить BlockReference этого блока?

Sub ATTRIB()
Dim MyBlock As AcadBlock
Dim MyBlocks As AcadBlocks
Dim MyBlockReference As AcadBlockReference
Dim Atts As Variant
Set MyBlocks = ThisDrawing.Blocks
Set MyBlock = MyBlocks.Item("Corner_Stamp_2")
'???????????????????????????????????
'Set MyBlockReference = ???????
'Atts = objTemp.GetAttributes
'???????????????????????????????????
End Sub

Re: Как добраться до существующего BlockReference?

ой, вернее

 Atts =  MyBlockReference.GetAttributes

Re: Как добраться до существующего BlockReference?

 Private elem As Object
   For Each elem In Layout.Block
      With elem
         If .EntityName = "AcDbBlockReference" Then
            name = .Name
            If name Like ("Corner_Stamp_2") Then
               Attr = elem.GetAttributes
               Exit For
            End If
         End If
      End With
   Next

Не весь код, но думаю, что должно быть понятно.

Re: Как добраться до существующего BlockReference?

В коде выше скобки не нужны!

Re: Как добраться до существующего BlockReference?

не работает :(
неужели нельзя как-нибудь просто обратиться к существующему блоку?

Re: Как добраться до существующего BlockReference?

Хех
всем спасибо решение нашлось

Dim MyBlock As AcadBlock
Dim MyBlocks As AcadBlocks
Dim MyBlockReference As AcadBlockReference
Dim Atts As Variant
Public Function SelectMyBlocks(strName As String) As AcadSelectionSet
  Dim objSelSet As AcadSelectionSet
  Dim objSelCol As AcadSelectionSets
  Set objSelCol = ThisDrawing.SelectionSets
    For Each objSelSet In objSelCol
      If objSelSet.Name = strName Then
        objSelSet.Delete
        Exit For
      End If
    Next
  Set objSelSet = ThisDrawing.SelectionSets.Add(strName)
  Set SelectMyBlocks = objSelSet
End Function
 Public Sub GetMyBlockRefAtts()
  Dim objSelSet As AcadSelectionSet
  Dim objBlkRef As AcadBlockReference
  Dim intType(0) As Integer
  Dim varDat(0) As Variant
  Dim strAttributes As String
  Dim i As Integer
  On Error GoTo Err_Control
    intType(0) = 0
    varDat(0) = "INSERT"
    Set objSelSet = SelectMyBlocks("blocks")
    objSelSet.Select acSelectionSetAll, FilterType:=intType, _
    FilterData:=varDat
    For Each MyBlockReference In objSelSet
      If MyBlockReference.Name = "Corner_Stamp_2" Then
        'MsgBox (MyBlockReference.Name)
        Atts = MyBlockReference.GetAttributes
      End If
    Next MyBlockReference
    'For i = LBound(Atts) To UBound(Atts)
        'strAttributes = strAttributes & "  Tag: " & Atts(i).TagString & "   Value: " & Atts(i).TextString & "    "
        'msg = MsgBox(" Tag: " & Atts(i).TagString & "   Value: " & Atts(i).TextString, , i)
  ' Next
Exit_Here:
  Exit Sub
Err_Control:
  MsgBox Err.Description
  Resume Exit_Here
End Sub

Re: Как добраться до существующего BlockReference?

Вот еще вариант для разнообразия:

Dim BlockSS As AcadSelectionSet
fType(0) = 2: fData(0) = "Corner_Stamp_2"
BlockSS.Select acSelectionSetAll, , , fType, fData

Re: Как добраться до существующего BlockReference?

Господа, вы не подскажете, что мне необходимо изменить в коде, чтобы MyBlockReference выбирался только из Active Layout?

Re: Как добраться до существующего BlockReference?

Наверное

Dim Layout as AcadLayout
Set Layout = ThisDrawing.ActiveLayout

В применении к моему примеру.

Re: Как добраться до существующего BlockReference?

brigval,
Спасибо, разобрался
просто сначала думал, что

If .EntityName = "AcDbBlockReference" Then 

опечатка и должно было быть "AcadBlockReference" :)
Полностью это выглядит так

Public MyBlockReference As AcadBlockReference
Public Atts As Variant
 Public Sub GetMyBlockRefAtts()
  Dim nm As String
    Dim elem As Object
   For Each elem In ThisDrawing.ActiveLayout.Block
      With elem
        If .EntityName Like "AcDbBlockReference" Then
            nm = .Name
            If nm Like ("Corner_Stamp_2") Then
               Atts = elem.GetAttributes
               Exit For
            End If
         End If
      End With
   Next
End Sub

Re: Как добраться до существующего BlockReference?

> Jam
:)
Db означает, кажется, что эти объекты из базы данных AutoCAD. По крайней меере, я для себя так считаю.

Re: Как добраться до существующего BlockReference?

Интересно а можно ли средствами VB .NET и .dll автокада
сделать тоже самое, только не открывая файл .dwg а указывая просто путь к нему?
Естесственно предполагая, что Layout в файле только один

Re: Как добраться до существующего BlockReference?

Не открвывая файл, то есть не загружая его в ОЗУ, ничего с ним сделать нельзя. Наверное, можно открыть файл не видимым для пользователя. Тогда с ним можно делать все что и с отображаемым в окне программы.
А вообще, лучше придерживаться принципа "один вопрос - одна тема".

Re: Как добраться до существующего BlockReference?

> brigval
Для уточнения:
AcDbBlockReference - это имя класса в базе данных чертежа, подкласс класса AcDbEntity, который в свою очередь входит в класс AcDbObject. В силу такой иерархии наверное и срабатывает выражение:
Object.EntityName = "AcDbBlockReference"

Re: Как добраться до существующего BlockReference?

> LeonidSN
Cпасибо за уточнение, LeonidSN.

Re: Как добраться до существующего BlockReference?

> Jam

> brigval
можно. вот рабтающий код. не лишен недостатков, но свое дело делает

Public Function GetAttrFromFileC(fName As String, BlkName As String, Optional AccuCompare = False) As Collection
 Dim MainDoc As AxDbDocument
 Dim AttrSet As Collection
 Dim Objblk As AcadBlockReference
 Dim objEnt As AcadEntity
 Dim PS As AcadPaperSpace
On Error GoTo Err_Control
 Set MainDoc = IsOpened(fName)
 If MainDoc Is Nothing Then
  Set MainDoc = New AxDbDocument
  MainDoc.Open fName
 End If
 Set PS = MainDoc.PaperSpace
 For Each objEnt In PS
  If TypeName(objEnt) = "IAcadBlockReference" Then
   Set Objblk = objEnt
   If AccuCompare Then
    If StrComp(Objblk.Name, BlkName) = 0 Then
     Set AttrSet = GetBlockAttributesC(Objblk)
    End If
   Else
    If InStr(Objblk.Name, BlkName) <> 0 Then
     Set AttrSet = GetBlockAttributesC(Objblk)
    End If
   End If
  End If
 Next
 Set GetAttrFromFileC = AttrSet
 Set MainDoc = Nothing
 Exit Function
Err_Control:
 MsgBox "Error!" & Err.Number
 Err.Clear
End Function

только в Reference надо сослаться на библиотеку AutoCAD/ObjectDBX

Re: Как добраться до существующего BlockReference?

> Дмитрий
Ну да, можно. Код же не будет изменять намагниченность диска винчестера. :) Для работы с файлом, как минимум его надо открыть (=загрузить в ОЗУ). А потом выгрузить с сохранением (фактически, перезаписать). Тогда на винчестере он останется измененным.
Вы же проверяете

MainDoc Is Nothing

Есть ли документ в памяти или нет.
А потом очищаете память

Set MainDoc = Nothing 

Если только Jam не имел ввиду что-то другое.

Re: Как добраться до существующего BlockReference?

он имел ввиду "не загружая чертеж" скорее всего.
кстати, по скорости выцепляния атрибутов из файла этот метод гораздо быстрее обычного (с загрузкой чертежа в акад)

Re: Как добраться до существующего BlockReference?

Дмитрий пишет:

этот метод гораздо быстрее обычного

А в чем его отличие от обычного метода? Использованы другие функции?

Re: Как добраться до существующего BlockReference?

> brigval
нет. чертеж не открывается, не вырисовываются примитивы, нет регенерации модели или лайаута, доступ идет непосредственно к базе данных

Re: Как добраться до существующего BlockReference?

> Дмитрий
Да. Это действительно интересно. Спасибо за информацию.

Re: Как добраться до существующего BlockReference?

кстати, я так понял, что через DBX интерфейс можно не только читать, но и писать.
т.е. можно туда "нарисовать", а потом чертежик загрузить и что-нибудь с ним еще поделать

Re: Как добраться до существующего BlockReference?

Дмитрий пишет:

через DBX интерфейс можно не только читать, но и писать

А это Вы о чем?

Re: Как добраться до существующего BlockReference?

To Дмитрий
Попробовал по вашему совету обратиться напрямую к базе данных чертежа через объект AxDbDocument. Сработало только в ACAD2004, а в ACAD2002 не срабатывает. При попытке установить объект                         

Set MainDoc = New AxDbDocument

отладчик ругается: Automation error. The specified module could not be found.
И это при том, что компонент AutoCAD/ObjectDBX Common 16.0 Type Library подключен к проекту.
Пока писал, кажется, сообразил в чем дело - подключена библиотека 16-ой версии, т.е. для ACAD2004. Поэтому вопрос будет звучать так: А существует ли в природе соответсвующая библиотека для ACAD2002, или обсуждаемая возможность применима только начиная с 2004-го?

Re: Как добраться до существующего BlockReference?

Есть в P-CAD функции DBX для доступа к объектам P-CAD. У меня DBX ассоциировался только с P-CAD. Я поэтому и переспросил. :)