Тема: ВОПРОС К FIXO

Доброе утро!!!
А можно ли тот же самый код сделать не для значений Тагов, а для значений Валуе??? Т.е. у всех блоков одни и те же Таги, а значения Валуе разные.

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

Re: ВОПРОС К FIXO

Этот код ранее Вы размещали на форуме

Re: ВОПРОС К FIXO

> Дашуля
Из твоего вопроса пока ничего не  понятно,
сколько тэгов по которым ведется выборка?
И не пиши пожалуйста заглавными буквами,
по неписанным правилам это означает что
ты кричишь...
~'J'~

Re: ВОПРОС К FIXO

> fixo
Я имела виду следующее вот что.
Сейчас программный код делает следующее:
1) Находит все блоки и создает набор
2) Далее стоит фильтр, который выбирает нужный блок, имя которого объявленно в начале кода
3) Потом он проверяет Таги блока (я не знаю как их правильно называть - имена аттрибутов или Таги)

        Select Case oAtt.TagString
            Case "AT1"
                attVal1 = oAtt.TextString
            Case "AT2"
                attVal2 = oAtt.TextString
            End Select

4) Ну и наконец выдает количество блоков и проверяет следующий блок тем же образом.
Вопрос заключается вот в чем:
Можно ли проверять блоки не по Тагам, а по их значениям (так называемым Валуе)???????
У меня есть большая категория блоков с одинаковым именем, с одинаковыми Тагами (аттрибутами), но с разными Валуе (значениями аттрибутов).
Т.е. тот же самый код, но вместо Тагов проверка должна делаться по Валуе.
P.S.: Если я допускаю ошибку в терминах - не судите меня строго пожалуйста, поправьте если я что-то неправильно говорю.

Re: ВОПРОС К FIXO

> Дашуля
Поправь меня если я что не так понял:
Выбираем все блоки по имени
Группируем данные по значениям атрибутов - value
Я еще спрашивал сколько атрибутов должно
учитываться в такой выборке?
Какое имя блока и какие названия (тэги) атрибутов?
Насчет терминологии не парься, я бы например
обозвал тэг по-русски - "ярлык" или "метка",
но на практике столько различных названий,
что упорядочить это невозможно
~'J'~

Re: ВОПРОС К FIXO

> Дашуля
Информация к размышлению

Option Explicit
Const blkName As String = "_Opora" '<-- имя блока
Const attName1 As String = "NAIMENOVANIE" '<--тэг атрибута
Const attValue1 As String = "Промежуточная опора" '<--значение атрибута
'~~~~~~~~~~~~~~~~~~~~~~~~~~~'
Sub CountBlocksByAttValue()
    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 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
MsgBox oSset.Count
    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, attName1, vbTextCompare) = 0 And _
            StrComp(oAtt.TextString, attValue1, vbTextCompare) = 0 Then
            counter = counter + 1
            Exit For
            End If
        Next i
    Next oEnt
    If Err Then
        Err.Clear
    End If
    MsgBox "Всего блоков " & blkName & " имеющих значение " & vbCr & _
    attValue1 & " для атрибутов " & attName1 & vbCr & _
    " в наборе выбора: " & counter & " штук"
Err_Control:
    If Err.Number <> 0 Then
        MsgBox Err.Description
    End If
End Sub

~'J'~

Re: ВОПРОС К FIXO

> fixo
Спасибо. Очень полезный для меня код.
Я все ломала голову что значит Ваша подпись:
~'J'~
Прочитала на другом форуме Ваши разъяснения по этому поводу :) Смеялась до слез, чуть со стула не рухнула :)

Re: ВОПРОС К FIXO

> fixo
А можно сделать так, чтобы
If blockName & attValue1 =  "П11" & "(2х1х1)" Then
записать все attValue2, принадлежащие именно этим блокам в переменную NomerOpori
????????????

Re: ВОПРОС К FIXO

fixo (2008-08-16 22:55:01)
Скажите пожалуйста можно ли так сделать. Иначе мне предется писать многокиллометровый код и делать миллион проверок без преувеличения.

Re: ВОПРОС К FIXO

> fixo
Помогите пожалуйста. Вторую неделю мучаюсь и никак не могу извлечь значения атрибутов. Для Вас это дело 5 минут. Уделите пожалуйста немного Вашего времени.
У меня должно быть такое условие:

Const blkName As String = "П11" '<-- имя блока
Const attName1 As String = "Ответвления" '<--тэг атрибута
Const attValue1 As String = "(2х1х1)" '<--значение атрибута
Const attName2 As String = "Номер опоры" '<--тэг атрибута

Найти все attValue2 принадлежащие таким блокам. Блоков много. Они одинаковые, а номера у них разные. Мне очень нужны номера.

Re: ВОПРОС К FIXO

> fixo
Объясните пожалуйста если Вам не трудно как задаются условия, как отбрасываются ненужные выражения.
Я добилась только полного извлечения всех значений attValue2  со всех блоков. Какие бы изощренные условия я не ставила, все равно просачиваются ненужные attValue2

Re: ВОПРОС К FIXO

Ну что????????????????????

Re: ВОПРОС К FIXO

> Дарья
Неужели так трудно посмотреть в Help
Например как прописана функция сравнения строк StrComp

Dim k as integer
Dim resAtt() as string
    For Each oEnt In oSset
        Set oBlkRef = oEnt
        attArr = oBlkRef.GetAttributes
        For i = 0 To UBound(attArr)
            Set oAtt = attArr(i)
            If StrComp(oAtt.TagString, attName2, vbTextCompare) = 0 Then
            redim preserve resAtt(k)
            resAtt(k)=oAtt.TextString '<--накапливаешь номера в массив
            k=k+1
            Exit For
            End If
        Next i
    Next oEnt

PS Не надо воплей, тебе не кажется что у меня
могут быть свои собственные не менее срочные дела?
~'J'~

Re: ВОПРОС К FIXO

> fixo
Простите за вопли. Сил больше нет, не клеится код и все!!!!
Вот я получила массив вроде. Как мне его запихать в одну строку???
Я не знаю как обращаться с массивами :(

Option Explicit
Const blkName As String = "П11"
Const attName2 As String = "Количество ответвлений"
Const attValue1 As String = "(2х1х1)"
'~~~~~~~~~~~~~~~~~~~~~~~~~~~'
Sub CountBlocksByAttValue()
    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 attName2 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
Dim k As Integer
Dim resAtt() As String
    For Each oEnt In oSset
        Set oBlkRef = oEnt
        attArr = oBlkRef.GetAttributes
        For i = 0 To UBound(attArr)
            Set oAtt = attArr(i)
            If StrComp(oAtt.TagString, attName2, vbTextCompare) = 0 Then
            ReDim Preserve resAtt(k)
            resAtt(k) = oAtt.TextString
            k = k + 1
            Exit For
            End If
        Next i
    Next oEnt
    If Err Then
        Err.Clear
    End If
PeremennayaKotorayaDoljnaSoderjatVsebeVvideStrokiVseNomeraOpor = resAtt(k)
Err_Control:
    If Err.Number <> 0 Then
        MsgBox Err.Description
    End If
End Sub

Re: ВОПРОС К FIXO

Я никак не могу решить проблемму с номерами. Помогите плиз...

Re: ВОПРОС К FIXO

Вот эту переменную
PeremennayaKotorayaDoljnaSoderjatVsebeVvideStrokiVseNomeraOpor
я должна занести в ячейку моей готовой таблицы.
Мне нужно чтобы эта переменная в виде строки содержала номера заданных блоков.
Не получается сохранить в переменной номера блоков :(
Я уже на грани нервного срыва... Неделя безуспешной работы над кодом :(

Re: ВОПРОС К FIXO

> Дашуля
Тогда замени эту часть

Dim NumStr As String
Numstr=""
    For Each oEnt In oSset
        Set oBlkRef = oEnt
        attArr = oBlkRef.GetAttributes
        For i = 0 To UBound(attArr)
            Set oAtt = attArr(i)
            If StrComp(oAtt.TagString, attName2, vbTextCompare) = 0 Then
            numstr=numstr & "," & oAtt.textstring
            Exit For
            End If
        Next i
    Next oEnt

В переменной numstr будут все номера через запятую
~'J'~

Re: ВОПРОС К FIXO

> fixo
Не работает

Option Explicit
Const blkName As String = "П11"
Const attName1 As String = "Количество ответвлений"
Const attValue1 As String = "(2х1х1)"
Const attName2 As String = "Номер опоры"
'~~~~~~~~~~~~~~~~~~~~~~~~~~~'
Sub CountBlocksByAttValue()
    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 attName2 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
Dim NumStr As String
NumStr = ""
    For Each oEnt In oSset
        Set oBlkRef = oEnt
        attArr = oBlkRef.GetAttributes
        For i = 0 To UBound(attArr)
            Set oAtt = attArr(i)
            If StrComp(oAtt.TagString, attName2, vbTextCompare) = 0 Then
            NumStr = NumStr & "," & oAtt.TextString
            Exit For
            End If
        Next i
    Next oEnt
    If Err Then
        Err.Clear
    End If
MsgBox NumStr
Err_Control:
    If Err.Number <> 0 Then
        MsgBox Err.Description
    End If
End Sub

Re: ВОПРОС К FIXO

> fixo
Я правильно поняла что в коде написано следующее:
Если Таг под номером 2 будет таким, какой задан вначале, то тогда записать все значения этого Тага в переменную NumStr ???

Re: ВОПРОС К FIXO

> fixo
В таком случае, если я правильно поняла, код отфильтрует все блоки с Тагом под номером 2 и запишет все значения этих Тагов в переменную NumStr.

Re: ВОПРОС К FIXO

> fixo
Цель будет не достигнута!!!!
Фильтрация должна идти следующим образом:
1) Отбрасываются все блоки кроме заданных вначале (вначале к примеру задан блок с именем "П11")
2) Из этих блоков отбрасываются все кроме тех, у которых Значение первого Тага заданно вначале (Вначале к примеру заданно Значение первого Тага равное "(2х1х1)" )
3)Получили : "П11" & "(2х1х1)"
Теперь записываем Все Значения второго Тага в переменную NumStr

Re: ВОПРОС К FIXO

Имя блока: "П11"
Таг №1: "Количество ответвлений"
Значение тага №1: "(2х1х1)"
Таг №1: "Номер опоры"
Значение тага №2: --Вот все эти значения не получаются запихнуть в переменную NumStr

Re: ВОПРОС К FIXO

> fixo
В справке я не нашла StrComp.
Я не понимаю как этой справкой пользоваться. Ну есть там примеры кодов. Все очень поверхностно...

Re: ВОПРОС К FIXO

> fixo
Может нельзя сделать такое условие, которое мне нужно, а я мучаюсь????

Re: ВОПРОС К FIXO

> fixo
Не могу понять почему не работает:

Option Explicit
Const blkName As String = "П11"
Const attName1 As String = "Количество ответвлений"
Const attValue1 As String = "(2х1х1)"
Const attName2 As String = "Номер опоры"
'~~~~~~~~~~~~~~~~~~~~~~~~~~~'
Sub CountBlocksByAttValue()
    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 attName2 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
Dim NumStr As String
NumStr = ""
    For Each oEnt In oSset
        Set oBlkRef = oEnt
        attArr = oBlkRef.GetAttributes
        For i = 0 To UBound(attArr)
            Set oAtt = attArr(i)
            If StrComp(oAtt.TagString, attName1, vbTextCompare) = 0 And _
            StrComp(attVal1, attValue1, vbTextCompare) = 0 And _
            StrComp(oAtt.TagString, attName2, vbTextCompare) = 0 Then
            NumStr = NumStr & "," & oAtt.TextString
            Exit For
            End If
        Next i
    Next oEnt
    If Err Then
        Err.Clear
    End If
MsgBox NumStr
Err_Control:
    If Err.Number <> 0 Then
        MsgBox Err.Description
    End If
End Sub