Тема: Циклировать код

НИЖЕ ПРИВЕДЕННЫЙ КОД РАБОТАЕТ ХОРОШО, НО ОЧЕНЬ МЕДЛЕННО...В НЕМ ПОВТОРЯЕТСЯ ОДИН И ТОТ ЖЕ КОД 100 РАЗ, Т.К. В ЧЕРТЕЖЕ БОЛЕЕ 100 НАИМЕНОВАНИЙ ДЕТАЛЕЙ.
МОЖЕТ ВЫ ЗНАЕТЕ как сделать этот код менее длинным, т.е. циклировать??? Ну что-то вроде счетчика что ли...
А то этот код такой огромный получился и тормозит комп очень сильно!!!
'ПОИСК В ПРОСТРАНСТВЕ ЛИСТА ДЕТАЛЕЙ А
     Dim ss As AcadSelectionSet
     With ThisDrawing.SelectionSets
             While .Count > 0
          .Item(0).Delete
          Wend
          Set ss = .Add("$Blocks$")
     End With
Dim ftype(2) As Integer
Dim fdata(2) As Variant
ftype(0) = 0: ftype(1) = 2: ftype(2) = 67
fdata(0) = "INSERT": fdata(1) = "DETALI_А": fdata(2) = 0
'<--"DETALI_А" это имя блока
     ss.Select acSelectionSetAll, , , ftype, fdata
     POISK_DETALEI.А.Caption = CStr(ss.Count)
     ss.Delete
'ПОИСК В ПРОСТРАНСТВЕ ЛИСТА ДЕТАЛЕЙ Б
     With ThisDrawing.SelectionSets
          While .Count > 0
               .Item(0).Delete
          Wend
          Set ss = .Add("$Blocks$")
     End With
ftype(0) = 0: ftype(1) = 2: ftype(2) = 67
fdata(0) = "INSERT": fdata(1) = "DETALI_Б": fdata(2) = 0
     ss.Select acSelectionSetAll, , , ftype, fdata
     POISK_DETALEI.Б.Caption = CStr(ss.Count)
     ss.Delete
И Т.Д. И Т.П. ЕЩЕ 98 ДЕТАЛЕЙ

Re: Циклировать код

> Дарья
Я делаю так:

Option Explicit
Sub CountingBlocks()
' not working with dynamic blocks
  Dim oBlocks As AcadBlocks
  Dim oBlock As AcadBlock
  Dim oBlkRef As AcadBlockReference
  Dim oEnt As AcadEntity
  Dim fType(1) As Integer, fData(1)
  Dim oSset As AcadSelectionSet
  Dim blkName As String
  Dim iCount As Integer
  Dim dxfCode, dxfData
  Dim tmp(1)
  Dim blkColl As New Collection
  fType(0) = 0: fData(0) = "INSERT"
  fType(1) = 2
On Error GoTo Err_Trapp
          With ThisDrawing.SelectionSets
               While .Count > 0
                    .Item(0).Delete
               Wend
          End With
Set oSset = ThisDrawing.SelectionSets.Add("$BlkInstances$")
oSset.Clear
Set oBlocks = ThisDrawing.Blocks
  'loop through all block definitions
  For Each oBlock In oBlocks
  If oBlock.IsLayout = False And oBlock.IsXRef = False Then
  blkName = oBlock.Name
  fData(1) = blkName
  dxfCode = fType
  dxfData = fData
  oSset.Select acSelectionSetAll, , , dxfCode, dxfData
  iCount = 0
  For Each oBlkRef In oSset
  iCount = iCount + 1
    Next oBlkRef
    tmp(0) = blkName: tmp(1) = iCount
' comment IF - END IF statement to your suit
    If iCount > 0 Then
    blkColl.Add tmp
    End If
    Erase tmp
    oSset.Clear
    End If
  Next oBlock
  Debug.Print "Used Block Definitions: " & blkColl.Count
  oSset.Delete
  Set oSset = Nothing
  ' convert collection to two-dimensional array
  Dim i As Long, j As Long
  ReDim blkVar(blkColl.Count - 1, 1)
  For i = 1 To blkColl.Count
  blkVar(i - 1, 0) = blkColl.Item(i)(0)
  blkVar(i - 1, 1) = blkColl.Item(i)(1)
  Next
Err_Trapp:
If Err Then
 MsgBox "Error occured:" & vbNewLine & Err.Description
 End If
End Sub

~'J'~

Re: Циклировать код

> Fatty
Кажись ты сделал код для ВСЕХ блоков(примитивов) в чертеже, а не только для тех, которые нужна Дарье. И тут возникает вопрос - откуда программа (или программист) берет эти самые 100 имен блоков и куда выдает результаты своей работы? Напрашивается решение в виде текстового файла.

Re: Циклировать код

> LeonidSN
Да, логично предположить, имена блоков где-то
хранятся (текстовый или Excel)
Главное идея надеюсь ясна, цикл будет явно пошустрей
~'J'~

Re: Циклировать код

В моем коде поочередно ищется сначала Деталь "А"
и результат вставляется строго в форму под названием "POISK_DETALEI" в Label под названием "А":
POISK_DETALEI.А.Caption = CStr(ss.Count)
Затем  он находит Деталь "Б" и вставляет результат строго в форму под названием "POISK_DETALEI" и строго в Label под названием "Б":
POISK_DETALEI.Б.Caption = CStr(ss.Count)
Это нужно, чтобы потом с результатами произвести математические вычисления. Например
Деталь "А"
состоит из двух болтов, значит мой код находит количество этих деталей, записывает результат в Label под названием "А" и далее другой мой код умножает это количество на 2!!!
Мне не совсем понятно куда выводятся результаты выше приведенного кода...???
И можно ли искать по определенному слою, а не в пространстве всего листа??????
smile                      smile

Re: Циклировать код

Все это можно - надо просто фильтр "нарастить".

Re: Циклировать код

> Дарья
В результате выполнения кода ты получаешь
двухмерный массив blkVar в котором хранится
вся информация в виде: Имя блока - Количество
Дальше твое дело как ее использовать
А вообще-то нерационально использовать Label
для отображения информации, для этого вполне
подойдет ListBox или ListView на два столбца
~'J'~

Re: Циклировать код

А как "нарастить" фильтр???

Re: Циклировать код

Вот получаем двухмерный массив blkVar и что дальше???
Тут должна быть строгая закономерность:
Сначала он должен найти именно Деталь "А" и помножить количество на 2
Затем Деталь "Б"..... и т.д. и т.п.
Может я не совсем понимаю как работает этот код и как он создает массив???

Re: Циклировать код

> Дарья
Попытаюсь объяснить без редактора
У тебя есть готовый массив
Проходишь его циклом:

dim det as string
dim i as integer
det="Detail A"
For i= lbound(blkvar,1) to ubound(blkvar,1)
If blkvar(i, 0)= det then '<--ищем позицию в массиве (можно использовать StrComp)
qty = blkvar(i,1)*2
exit for '<--раз нашли, выходим из цикла
end if
next i
msgbox "amount of detail " & chr(34) & det & (chr(34) & "is: " & qty

~'J'~

Re: Циклировать код

Спасибо большое всем, кто откликнулся!!!
smile

Re: Циклировать код

> Дарья
Залил для примера небольшую программу
для подсчета количества блоков в чертеже
с возможностью подсчета на отдельных листах
Не бог весть что, но может прояснить методы
которые можно использовать:
http://www.cadforyou.spb.ru/index.php?c … grams_page
Название программы CountBlocks (загружена 13/02/08)
~'J'~