Тема: Подсчет блоков по атрибуту

Здравствуйте,
вот на работе возникла потребность подсчитать блоки в рисунке автокада по конкретному атрибуту. Т.е есть блок "block" и четыре атрибута "at1","at2","at3","at4". Выделяем все необходимые блоки в автокаде после чего создается файл в excel-e в котором в ячейке  A1 будет количество блоков "block" с одинаковыми значениями атрибута "at1",в ячейке A2 значение атрибута "at1" и далее в ячейках A3,A4,A5 соответственно значения атрибутов ","at2","at3","at4". В результате получаем список блоков "block" с подсчетом их количества для разных значений "at1" и выводом атрибутов ","at2","at3","at4".
Буду очень благодарна если кто нибудь сможет подсказать как написать такой макрос или подкинет похожий код который попробую сама переделать.
Заранее Спасибо.

Re: Подсчет блоков по атрибуту

> Елена
А значения остальных атрибутов одинаковые
для всех блоков?
Я имею ввиду "at2","at3","at4".
~'J'~

Re: Подсчет блоков по атрибуту

Добрый вечер. Значения остальных атрибутов "at2","at3","at4"- одинаковые.

Re: Подсчет блоков по атрибуту

> Елена
Тогда держи

Option Explicit
' request Reference to:
' Microsoft Excel XX.X Object Library
Const blkName As String = "MLR" '<-- change block name
Const attName As String = "PRESET" '<-- change attribute tag
Sub CountBlocksByAttribute()
    Dim oSset As AcadSelectionSet
    Dim oEnt As AcadEntity
    Dim oBlkRef As AcadBlockReference
    Dim oFstRef As AcadBlockReference
    Dim oAtt As AcadAttributeReference
    Dim attArr() As AcadAttributeReference
    Dim fstArr As Variant
    Dim tmpStr As String
    Dim i As Long, j As Long
    Dim counter As Integer, m 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
    Set oEnt = oSset.Item(0)
    Set oFstRef = oEnt
    fstArr = oFstRef.GetAttributes
    i = UBound(fstArr)
    ' headers (unused in this context)
    'ReDim hdr(i) As String
    '
    'For j = 0 To i
    'Set oAtt = fstArr(j)
    'If StrComp(oAtt.TagString, attName, vbTextCompare) = 0 Then
    'hdr(j) = oAtt.TagString
    'Else
    'hdr(0) = oAtt.TagString
    'End If
    'Next
    Dim uniqColl As New Collection
    Dim countColl As New Collection
    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)
            If StrComp(oAtt.TagString, attName, vbTextCompare) = 0 Then
                uniqColl.Add oAtt.TextString, oAtt.TextString
            End If
        Next i
    Next oEnt
    If Err Then
        Err.Clear
    End If
    For i = 1 To uniqColl.Count
        tmpStr = uniqColl.Item(i)
        counter = 0
        For Each oEnt In oSset
            Set oBlkRef = oEnt
            attArr = oBlkRef.GetAttributes
            For j = 0 To UBound(attArr)
                Set oAtt = attArr(j)
                If StrComp(UCase(oAtt.TextString), UCase(tmpStr), 1) = 0 Then
                    counter = counter + 1
                    Exit For
                End If
            Next j
        Next oEnt
        ReDim tmp(UBound(fstArr) + 1) As String
        tmp(0) = CStr(counter): tmp(1) = tmpStr
        For j = 0 To UBound(fstArr)
            Set oAtt = fstArr(j)
            If StrComp(oAtt.TagString, "PRESET", 1) <> 0 Then
                tmp(j + 2) = oAtt.TextString
            End If
        Next
        countColl.Add tmp, tmpStr
    Next i
    DoEvents
    ''~~~~~~~~~ Excel part ~~~~~~~~~''
    Dim xlApp As Excel.Application
    Dim xlBooks As Excel.Workbooks
    Dim xlBook As Excel.Workbook
    Dim xlSheet As Excel.Worksheet
    Set xlApp = GetExcelOpen
    If Not xlApp Is Nothing Then
        xlApp.Visible = True
        Debug.Print "Success"
    Else
        Debug.Print "Failed"
        Exit Sub
    End If
    Set xlBooks = xlApp.Workbooks
    xlBooks.Add
    Set xlBook = xlApp.ActiveWorkbook
    Set xlSheet = xlBook.Sheets(1)
    xlSheet.Name = blkName
    xlSheet.Activate
    With xlSheet
        Dim itm As Variant
        For i = 1 To countColl.Count
            itm = countColl.Item(i)
            For j = 0 To UBound(itm)
                .Cells(i, j + 1) = itm(j)
            Next
        Next
        .Columns.HorizontalAlignment = xlHAlignLeft
        .Columns.AutoFit
    End With
    xlBook.SaveAs ThisDrawing.Path & "\" & blkName & ".xls"
    xlBook.Close
    xlApp.Application.Quit
    Set xlSheet = Nothing
    Set xlBook = Nothing
    Set xlBooks = Nothing
    Set xlApp = Nothing
    DoEvents
    MsgBox "Done"
Err_Control:
If Err.Number <> 0 Then
    MsgBox Err.Description
    End If
End Sub
'' written by Joe Sutphin
Public Function GetExcelOpen() As Excel.Application
    On Error Resume Next
    Set GetExcelOpen = GetObject(, "Excel.Application")
    If Err Then
        Err.Clear
        Set GetExcelOpen = CreateObject("Excel.Application")
        If Err Then
            MsgBox "Could not start Excel Application", vbExclamation
            Exit Function
        End If
    End If
End Function

Файл Эксель автоматом сохраняется в той же папке где чертеж
~'J'~

Re: Подсчет блоков по атрибуту

Здравствуйте, спасибо огромное все отлично работает. Ваш код очень работу ускорил :) скажите а что необходимо в нем изменить для того чтоб поменять местами столбцы в которых находятся значения атрибута "AT1"  и количество блоков "block" с одинаковыми значениями атрибута "at1". Т.е в ячейке A1 значение атрибута "at1" а в ячейке A2 количество блоков "block" с одинаковыми значениями атрибута "at1" и далее как прежде.

Re: Подсчет блоков по атрибуту

Прошу прощение за оффтоп. Елена не подскажете что за блоки у вас. У меня задача автоматизировать составление спецификации , в принципе можно из объектов создать блок с атрибутами - значениями свойств объекта, не создавая новый класс. Я и сам подумаю конечно, но проще спросить.
Что касается кода то, если коряво, то можно считать значение ячеек в интересующем вас диапозоне и через свойство value объекта cell передать данные в любые ячейки. Я слабо програмирую поэтому могу  подсказать только такую идею.

Re: Подсчет блоков по атрибуту

> Елена
Нет времени к сожалению, действуй самомтоятельно
~'J'~

Re: Подсчет блоков по атрибуту

К сожалению Autocad выдает ошибку "invalid argument index in Item". Не подскажете в чем дело. Может я где ступил?

Re: Подсчет блоков по атрибуту

> Ринат
У меня тоже код не пошел.