Тема: Опять блоки и атрибуты :-(

Никак не пойму принцип (поиск юзал). Подскажите, пожалуйста, если не трудно.
В чертеже имеются блоки (несколько блоков с одним именем "ДЕТАЛЬ"). У этого блока есть пара атрибутов (АТ1 и АТ2). Значения атрибутов могут быть разными. Необходимо сосчитать количество блоков в чертеже у которых значения атрибутов равны, к примеру АТ1="Х" и AT2="Y". Блоки, у которых значения атрибутов равны чему-то другому - игнорировать.
Заране спасибо.

Re: Опять блоки и атрибуты :-(

Хэлп!!!

Re: Опять блоки и атрибуты :-(

> wl2000
Посмотри здесь и переделай условие
для 2-х атрибутов вместо одного:
https://www.caduser.ru/forum/topic43411.html
Нет времени, а то бы помог
~'J'~

Re: Опять блоки и атрибуты :-(

Эх. Если б мог бы, то переделал бы конечно.

Re: Опять блоки и атрибуты :-(

> wl2000
Типа того

Option Explicit
Const blkName As String = "ДЕТАЛЬ"    ' <-- change block name
Const attName1 As String = "AT1"    ' <-- change attribute tag
Const attName2 As String = "AT2"    ' <-- change attribute tag
Const attValue1 As String = "0.001"    ' <-- change 1st attribute value
Const attValue2 As String = "ABC"    ' <-- change 2nd attribute value
'~~~~~~~~~~~~~~~~~~~~~~~~~~~'
Sub CountBlocksByAttributes()
    Dim oSset As AcadSelectionSet
    Dim oEnt As AcadEntity
    Dim oBlkRef As AcadBlockReference
    Dim oAtt As AcadAttributeReference
    Dim attArr() As AcadAttributeReference
    Dim attVal1 As String
    Dim attVal2 As String
    Dim i As Long
    Dim counter As Integer
    Dim ftype(1) As Integer
    Dim fdata(1) As Variant
    Dim dxfCode, dxfValue
    On Error GoTo Err_Control
    ftype(0) = 0: ftype(1) = 2
    fdata(0) = "INSERT": fdata(1) = blkName
    dxfCode = ftype: dxfValue = fdata
    With ThisDrawing.SelectionSets
        While .Count > 0
            .Item(0).Delete
        Wend
        Set oSset = .Add("$Blocks$")
    End With
    oSset.Select acSelectionSetAll, , , dxfCode, dxfValue
    For Each oEnt In oSset
        Set oBlkRef = oEnt
        attArr = oBlkRef.GetAttributes
        On Error Resume Next
        For i = 0 To UBound(attArr)
            Set oAtt = attArr(i)
            Select Case oAtt.TagString
            Case "AT1"
                attVal1 = oAtt.TextString
            Case "AT2"
                attVal2 = oAtt.TextString
            End Select
        Next i
        If StrComp(attVal1, attValue1, vbTextCompare) = 0 And _
           StrComp(attVal2, attValue2, vbTextCompare) = 0 Then
            counter = counter + 1
        End If
    Next oEnt
    If Err Then
        Err.Clear
    End If
    MsgBox "Всего блоков с такими атрибутами: " & counter
Err_Control:
    If Err.Number <> 0 Then
        MsgBox Err.Description
    End If
End Sub

~'J'~

Re: Опять блоки и атрибуты :-(

> fixo
Этот код как я поняла находит определенный блок с определенными атрибутами. А если блоков не один, а много???
:)

Re: Опять блоки и атрибуты :-(

> Дарья
Во-первых находит не один блок а все блоки
с заданной парой атрибутов, а если нужно
тоже самое для нескольких блоков просто
переделай эту
процедуру в функцию и вызывай в своей процедуре
как обычно, типа:

Dim count1 as INteger
count1 =  CountBlocksByAttributes (blkname, attName1, attName2, attValue1, attValue2)

и тоже самое для других блоков которые тебя интересуют
count2 =...
countN = ...
где функция естественно типа

Private Function CountBlocksByAttributes (blkname as string, attName1 as string, _
attName2 as string, attValue1 as string, attValue2 as string)
as integer
...............
<< здесь просто копируй код из процедуры выше >>
End Function

~'J'~

Re: Опять блоки и атрибуты :-(

ПРАВИЛЬНО Я СДЕЛАЛА???
:)
ПРОТЕСТИРОВАТЬ ПОКА НЕ УСПЕЛА
Option Explicit
Const blkName As String = "ДЕТАЛЬ"    ' <-- change block name
Const attName1 As String = "AT1"    ' <-- change attribute tag
Const attName2 As String = "AT2"    ' <-- change attribute tag
Const attValue1 As String = "0.001"    ' <-- change 1st attribute value
Const attValue2 As String = "ABC"    ' <-- change 2nd attribute value
'~~~~~~~~~~~~~~~~~~~~~~~~~~~'
Private Function CountBlocksByAttributes (blkname as string, attName1 as string, _
attName2 as string, attValue1 as string, attValue2 as string)
as integer
Dim (count1 to count150) as INteger
count1 =  CountBlocksByAttributes (blkname, attName1, attName2, attValue1, attValue2)
count2 =  CountBlocksByAttributes (blkname, attName1, attName2, attValue1, attValue2)
и т.д. перечислить все варианты count
    Dim oSset As AcadSelectionSet
    Dim oEnt As AcadEntity
    Dim oBlkRef As AcadBlockReference
    Dim oAtt As AcadAttributeReference
    Dim attArr() As AcadAttributeReference
    Dim attVal1 As String
    Dim attVal2 As String
    Dim i As Long
    Dim counter As Integer
    Dim ftype(1) As Integer
    Dim fdata(1) As Variant
    Dim dxfCode, dxfValue
    On Error GoTo Err_Control
    ftype(0) = 0: ftype(1) = 2
    fdata(0) = "INSERT": fdata(1) = blkName
    dxfCode = ftype: dxfValue = fdata
    With ThisDrawing.SelectionSets
        While .Count > 0
            .Item(0).Delete
        Wend
        Set oSset = .Add("$Blocks$")
    End With
    oSset.Select acSelectionSetAll, , , dxfCode, dxfValue
    For Each oEnt In oSset
        Set oBlkRef = oEnt
        attArr = oBlkRef.GetAttributes
        On Error Resume Next
        For i = 0 To UBound(attArr)
            Set oAtt = attArr(i)
            Select Case oAtt.TagString
            Case "AT1"
                attVal1 = oAtt.TextString
            Case "AT2"
                attVal2 = oAtt.TextString
            End Select
        Next i
        If StrComp(attVal1, attValue1, vbTextCompare) = 0 And _
           StrComp(attVal2, attValue2, vbTextCompare) = 0 Then
            counter = counter + 1
        End If
    Next oEnt
    If Err Then
        Err.Clear
    End If
    MsgBox "Всего блоков с такими атрибутами: " & counter
Err_Control:
    If Err.Number <> 0 Then
        MsgBox Err.Description
    End If
End Function

Re: Опять блоки и атрибуты :-(

Большое спасибо, fixo. Вы мне помогаете уже второй раз!