Макрос вставки блока в точки вставки имеющихся в чертеже блоков

Автор Тема: Макрос вставки блока в точки вставки имеющихся в чертеже блоков  (Прочитано 11156 раз)

0 Пользователей и 2 Гостей просматривают эту тему.

Оффлайн sae.prcАвтор темы

  • ADN OPEN
  • Сообщений: 7
  • Карма: 0
Добрый день, имеется макрос суть которого в том, что бы в места вставки одних блоков вставить другой блок.
Алгоритм изначально предполагался такой: получить все блоки в чертеже, проверить на соответствие имени блока (содержит или нет определенные символы), получить точку вставки этого блока, по этой точке вставки вставить другой блок и назначить вставляемому блоку слой.
Код работает когда в чертеже только блоки, если же есть например мультилиния то блоки "проема" не вставляются.
В дальнейшем так же бы хотелось блок проема (а он динамический) вставлять определенных размеров, в зависимости от имени блоков ВВК и ВВП (они статические, по этому не придумал ничего лучше как пойти в лоб и присваивать в зависимости от имени - размеры)
Просьба помочь, так как vba только начинаю осваивать (с помощью чата GPT в том числе - очень неплохо помогает в начинаниях)

Код - Visual Basic [Выбрать]
  1. Sub OTV_SAE()
  2.     Dim BR As AcadBlockReference
  3.     Dim blk As AcadBlock
  4.     Dim name As String
  5.     Dim pp As Variant
  6.     Dim targetLayerName As String
  7.    
  8.     On Error Resume Next ' Ignore errors temporarily
  9.    
  10.        ' Удаляем предыдущие блоки "Проём"
  11.    For Each BR In ThisDrawing.ModelSpace
  12.         If TypeName(BR) = "IAcadBlockReference" Then
  13.             If BR.name = "Проём" Then
  14.                 BR.Delete
  15.             End If
  16.         End If
  17.     Next BR
  18.    
  19.     name = BR.name
  20.     'расставляю блок отверстия в местах установки КРУГЛЫХ шахт
  21.    For Each BR In ThisDrawing.ModelSpace
  22.             If InStr(1, name, "ВВК", vbTextCompare) > 0 Then ' Check if name contains "ВВК"
  23.                pp = BR.InsertionPoint
  24.                 name = "Проём"
  25.                 Set blk = ThisDrawing.Blocks.Item(name)
  26.                 If Not blk Is Nothing Then
  27.                     ThisDrawing.ModelSpace.InsertBlock pp, name, 1, 1, 1, 0
  28.                 Else
  29.                     MsgBox "Block 'Проём' not found.", vbExclamation, "Error"
  30.                 End If
  31.            
  32.         End If
  33.     Next BR
  34.    
  35.         'расставляю блок отверстия в местах установки ПРЯМОУГОЛЬНЫХ шахт
  36.    For Each BR In ThisDrawing.ModelSpace
  37.             If InStr(1, name, "ВВП", vbTextCompare) > 0 Then ' Check if name contains "ВВП"
  38.                pp = BR.InsertionPoint
  39.                 name = "Проём"
  40.                 Set blk = ThisDrawing.Blocks.Item(name)
  41.                 If Not blk Is Nothing Then
  42.                     ThisDrawing.ModelSpace.InsertBlock pp, name, 1, 1, 1, 0
  43.                 Else
  44.                     MsgBox "Block 'Проём' not found.", vbExclamation, "Error"
  45.                 End If
  46.            
  47.         End If
  48.     Next BR
  49.    
  50.     'назначаю блоку отверстия слой "заданий"
  51.    
  52.     For Each BR In ThisDrawing.ModelSpace
  53.         If TypeName(BR) = "IAcadBlockReference" Then
  54.             name = BR.name
  55.             targetLayerName = ""
  56.              If name = "Проём" Then
  57.              BR.layer = "задание_ОТВЕРСТИЯ"
  58.              End If
  59.          End If
  60.     Next BR
  61.     MsgBox "Отверстия расставлены"
  62.     On Error GoTo 0 ' Reset error handling
  63. End Sub
« Последнее редактирование: 21-08-2023, 15:13:36 от Александр Ривилис »

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13886
  • Карма: 1788
  • Рыцарь ObjectARX
  • Skype: rivilis
Код работает когда в чертеже только блоки, если же есть например мультилиния то блоки "проема" не вставляются.
Это очевидно. Ты же в циклах
Код - Visual Basic [Выбрать]
  1. For Each BR In ThisDrawing.ModelSpace
предполагаешь что у тебя в чертеже есть только вставки блоков. BR у тебя должно быть AcadEntity, чтобы можно было пройтись по всем примитивам в Пространстве Модели.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн sae.prcАвтор темы

  • ADN OPEN
  • Сообщений: 7
  • Карма: 0
Александр, благодарю за ответ!

Оффлайн sae.prcАвтор темы

  • ADN OPEN
  • Сообщений: 7
  • Карма: 0
Подправил код. После исправления типа переменной BR на AcadEntity все работает так как надо. Появился вопрос в зависимости от имени блоков менять свойства динблока "Проем", подскажите как лучше организовать, ввиду того что список типоразмеров велик (прямоуголки от 100х100 до 2000х2000 (и то не предел) с шагом 50). Код как это организовано сейчас (на примере лишь двух размеров)
Код - Visual Basic [Выбрать]
  1. Sub OTV_SAE()
  2.     Dim BR As AcadEntity
  3.     Dim blk As AcadBlock
  4.     Dim dbrp As AcadDynamicBlockReferenceProperty
  5.     Dim name As String
  6.     Dim pp As Variant
  7.     Dim targetLayerName As String
  8.     Dim blrf As AcadBlockReference
  9.    
  10.    
  11.     On Error Resume Next ' Ignore errors temporarily
  12.    
  13.        ' Удаляем предыдущие блоки "Проём"
  14.    For Each BR In ThisDrawing.ModelSpace
  15.         If TypeName(BR) = "IAcadBlockReference" Then
  16.             If BR.name = "Проём" Then
  17.                 BR.Delete
  18.             End If
  19.         End If
  20.     Next BR
  21.    
  22.     'расставляю блок отверстия в местах установки КРУГЛЫХ шахт
  23.    For Each BR In ThisDrawing.ModelSpace
  24.         If TypeName(BR) = "IAcadBlockReference" Then
  25.             name = BR.name
  26.             If InStr(1, name, "ВВК", vbTextCompare) > 0 Then ' Check if name contains "ВВК"
  27.                pp = BR.InsertionPoint
  28.                 name = "Проём"
  29.                 Set blk = ThisDrawing.Blocks.Item(name)
  30.                 If Not blk Is Nothing Then
  31.                     ThisDrawing.ModelSpace.InsertBlock pp, name, 1, 1, 1, 0
  32.                 Else
  33.                     MsgBox "Block 'Проём' not found.", vbExclamation, "Error"
  34.                 End If
  35.             End If
  36.         End If
  37.     Next BR
  38.    
  39.         'расставляю блок отверстия в местах установки ПРЯМОУГОЛЬНЫХ шахт
  40.    For Each BR In ThisDrawing.ModelSpace
  41.         If TypeName(BR) = "IAcadBlockReference" Then
  42.             name = BR.name
  43.             If name = "ВВП400_200" Then '
  44.                pp = BR.InsertionPoint
  45.                 name = "Проём"
  46.                 Set blrf = ThisDrawing.ModelSpace.InsertBlock(pp, name, 1, 1, 1, 0)
  47.                 blrf.layer = "задание_ОТВЕРСТИЯ"
  48.                     If blrf.IsDynamicBlock = True Then
  49.                     props = blrf.GetDynamicBlockProperties
  50.                         For Index = LBound(props) To UBound(props)
  51.                         Set prop = props(Index)
  52.                             If prop.PropertyName = "Ширина" Then
  53.                             prop.Value = 500#
  54.                             ElseIf prop.PropertyName = "Длина/Диаметр" Then
  55.                             prop.Value = 300#
  56.                             End If
  57.                          Next
  58.                      End If
  59.             ElseIf name = "ВВП500_300" Then
  60.                 pp = BR.InsertionPoint
  61.                 name = "Проём"
  62.                 Set blrf = ThisDrawing.ModelSpace.InsertBlock(pp, name, 1, 1, 1, 0)
  63.                 blrf.layer = "задание_ОТВЕРСТИЯ"
  64.                     If blrf.IsDynamicBlock = True Then
  65.                     props = blrf.GetDynamicBlockProperties
  66.                         For Index = LBound(props) To UBound(props)
  67.                         Set prop = props(Index)
  68.                             If prop.PropertyName = "Ширина" Then
  69.                             prop.Value = 600#
  70.                             ElseIf prop.PropertyName = "Длина/Диаметр" Then
  71.                             prop.Value = 400#
  72.                             End If
  73.                          Next
  74.                      End If
  75.             ElseIf InStr(1, name, "ВВП", vbTextCompare) > 0 Then
  76.                 pp = BR.InsertionPoint
  77.                 name = "Проём"
  78.                 Set blrf = ThisDrawing.ModelSpace.InsertBlock(pp, name, 1, 1, 1, 0)
  79.                 blrf.layer = "задание_ОТВЕРСТИЯ"
  80.             End If
  81.         End If
  82.     Next BR
  83.  
  84.     MsgBox "Отверстия расставлены"
  85.     On Error GoTo 0 ' Reset error handling
  86. End Sub
  87.  

Оффлайн sae.prcАвтор темы

  • ADN OPEN
  • Сообщений: 7
  • Карма: 0
Можно ли как то в цикле записать что в текcте [ВВП]#1_#2, извлечь #1 и #2 и блок проема вставить с размерами  #1+100 и #2+100?

Оффлайн sae.prcАвтор темы

  • ADN OPEN
  • Сообщений: 7
  • Карма: 0
Попробовал вариант с использование словаря, значения по ключу не передаются на динамический блок, в чем может быть проблема

Код - Visual Basic [Выбрать]
  1. Sub OTV_SAEv1_4()
  2.     Dim BR As AcadEntity
  3.     Dim blk As AcadBlock
  4.     Dim name As String
  5.     Dim pp As Variant
  6.     Dim targetLayerName As String
  7.     Dim blrf As AcadBlockReference
  8.    
  9.     Dim sizes_bbk As New Scripting.Dictionary ' создаем словарь круглых типоразмеров
  10.  
  11.    
  12.     ' заполняем словарь круглых типоразмеров
  13.    sizes_bbk.Add "ВВК100", 200
  14.     sizes_bbk.Add "ВВК125", 200
  15.     sizes_bbk.Add "ВВК160", 250
  16.     sizes_bbk.Add "ВВК200", 300
  17.     sizes_bbk.Add "ВВК250", 350
  18.     sizes_bbk.Add "ВВК315", 400
  19.     sizes_bbk.Add "ВВК355", 450
  20.     sizes_bbk.Add "ВВК400", 500
  21.     sizes_bbk.Add "ВВК450", 550
  22.     sizes_bbk.Add "ВВК500", 600
  23.     sizes_bbk.Add "ВВК560", 650
  24.     sizes_bbk.Add "ВВК630", 700
  25.     sizes_bbk.Add "ВВК710", 800
  26.     sizes_bbk.Add "ВВК800", 900
  27.     sizes_bbk.Add "ВВК900", 1000
  28.     sizes_bbk.Add "ВВК1000", 1100
  29.     sizes_bbk.Add "ВВК1120", 1200
  30.     sizes_bbk.Add "ВВК1250", 1350
  31.  
  32.    
  33.     On Error Resume Next ' Ignore errors temporarily
  34.    
  35.        ' Удаляем предыдущие блоки "Проём" - ТРЕБУЕТ ДОРАБОТКИ
  36.    For Each BR In ThisDrawing.ModelSpace
  37.         If TypeName(BR) = "IAcadBlockReference" Then
  38.             If BR.name = "Проём" Then
  39.                 BR.Delete
  40.             End If
  41.         End If
  42.     Next BR
  43.    
  44.     'расставляю блок отверстия в местах установки КРУГЛЫХ шахт
  45.    For Each BR In ThisDrawing.ModelSpace
  46.         If TypeName(BR) = "IAcadBlockReference" Then
  47.             name = BR.name
  48.             If sizes_bbk.Exists(name) = True Then
  49.                 pp = BR.InsertionPoint
  50.                 name = "Проём"
  51.                 Set blrf = ThisDrawing.ModelSpace.InsertBlock(pp, name, 1, 1, 1, 0)
  52.                 blrf.layer = "задание_ОТВЕРСТИЯ"
  53.                 If blrf.IsDynamicBlock = True Then
  54.                     Dim size_bbk_Value As Double
  55.                     size_bbk_Value = sizes_bbk(name)
  56.                     props = blrf.GetDynamicBlockProperties
  57.                     For Index = LBound(props) To UBound(props)
  58.                         Set prop = props(Index)
  59.                         If prop.PropertyName = "Ширина" Then
  60.                         prop.Value = size_bbk_Value
  61.                         ElseIf prop.PropertyName = "Длина/Диаметр" Then
  62.                         prop.Value = size_bbk_Value
  63.                         End If
  64.                     Next
  65.                 End If
  66.             ElseIf InStr(1, name, "ВВК", vbTextCompare) > 0 Then
  67.                 pp = BR.InsertionPoint
  68.                 name = "Проём"
  69.                 Set blrf = ThisDrawing.ModelSpace.InsertBlock(pp, name, 1, 1, 1, 0)
  70.                 blrf.layer = "задание_ОТВЕРСТИЯ"
  71.             End If
  72.         End If
  73.     Next BR

Оффлайн sae.prcАвтор темы

  • ADN OPEN
  • Сообщений: 7
  • Карма: 0
В итоге получилось так, код работает, отверстия ставятся, не знаю на сколько корректный код, но мне как новичку пока важно что он рабочий
Код - Visual Basic [Выбрать]
  1. Sub OTV_SAEv1_4()
  2.     Dim BR As AcadEntity
  3.     Dim blk As AcadBlock
  4.     Dim name As String
  5.     Dim pp As Variant
  6.     Dim targetLayerName As String
  7.     Dim blrf As AcadBlockReference
  8.     Dim ro_angle
  9.    
  10.    
  11.     Dim sizes_bbk As New Scripting.Dictionary ' создаем словарь круглых типоразмеров шахт
  12.    Dim sizes_bbp As New Scripting.Dictionary ' создаем словарь прямоугольных типоразмеров шахт
  13.    
  14.     Dim width As Variant
  15.     Dim height As Variant
  16.     Dim widths As Variant
  17.     Dim heights As Variant
  18.     widths = Array(100, 150, 200, 250, 300, 350, 400, 450, 500, 550, 600, 650, 700, 750, 800, 850, 900, 950, 1000, 1050, 1100, 1150, 1200, 1250, 1300, 1350, 1400, 1450, 1500, 1550, 1600, 1650, 1700, 1750, 1800, 1850, 1900, 1950, 2000)
  19.     heights = Array(100, 150, 200, 250, 300, 350, 400, 450, 500, 550, 600, 650, 700, 750, 800, 850, 900, 950, 1000, 1050, 1100, 1150, 1200, 1250, 1300, 1350, 1400, 1450, 1500, 1550, 1600, 1650, 1700, 1750, 1800, 1850, 1900, 1950, 2000)
  20.  
  21.    
  22.     ' заполняем словарь круглых типоразмеров
  23.    sizes_bbk.Add "ВВК100", 200
  24.     sizes_bbk.Add "ВВК125", 200
  25.     sizes_bbk.Add "ВВК160", 250
  26.     sizes_bbk.Add "ВВК200", 300
  27.     sizes_bbk.Add "ВВК250", 350
  28.     sizes_bbk.Add "ВВК315", 400
  29.     sizes_bbk.Add "ВВК355", 450
  30.     sizes_bbk.Add "ВВК400", 500
  31.     sizes_bbk.Add "ВВК450", 550
  32.     sizes_bbk.Add "ВВК500", 600
  33.     sizes_bbk.Add "ВВК560", 650
  34.     sizes_bbk.Add "ВВК630", 700
  35.     sizes_bbk.Add "ВВК710", 800
  36.     sizes_bbk.Add "ВВК800", 900
  37.     sizes_bbk.Add "ВВК900", 1000
  38.     sizes_bbk.Add "ВВК1000", 1100
  39.     sizes_bbk.Add "ВВК1120", 1200
  40.     sizes_bbk.Add "ВВК1250", 1350
  41.  
  42.     ' заполняем словарь прямоугольных типоразмеров
  43.    For Each width In widths
  44.         For Each height In heights
  45.             sizes_bbp.Add "ВВП" & CStr(width) & "_" & CStr(height), Array(width + 100, height + 100)
  46.         Next height
  47.     Next width
  48.    
  49.     On Error Resume Next ' Ignore errors temporarily
  50.    
  51.        ' Удаляем предыдущие блоки "Проём" - ТРЕБУЕТ ДОРАБОТКИ
  52.    For Each BR In ThisDrawing.ModelSpace
  53.         If TypeName(BR) = "IAcadBlockReference" Then
  54.             If BR.name = "Проём" Then
  55.                 BR.Delete
  56.             End If
  57.         End If
  58.     Next BR
  59.    
  60.     'расставляю блок отверстия в местах установки КРУГЛЫХ шахт
  61.    For Each BR In ThisDrawing.ModelSpace
  62.         If TypeName(BR) = "IAcadBlockReference" Then
  63.             name = BR.name
  64.             If sizes_bbk.Exists(name) Then
  65.                 pp = BR.InsertionPoint
  66.                 name_pr = "Проём"
  67.                 Set blrf = ThisDrawing.ModelSpace.InsertBlock(pp, name_pr, 1, 1, 1, 0)
  68.                 blrf.layer = "задание_ОТВЕРСТИЯ"
  69.                 If blrf.IsDynamicBlock = True Then
  70.                     Dim size_bbk_Value As Double
  71.                     size_bbk_Value = sizes_bbk(name)
  72.                     props = blrf.GetDynamicBlockProperties
  73.                     For Index = LBound(props) To UBound(props)
  74.                         Set prop = props(Index)
  75.                         If prop.PropertyName = "Ширина" Then
  76.                         prop.Value = size_bbk_Value
  77.                         ElseIf prop.PropertyName = "Длина/Диаметр" Then
  78.                         prop.Value = size_bbk_Value
  79.                         End If
  80.                     Next
  81.                 End If
  82.             ElseIf InStr(1, name, "ВВК", vbTextCompare) > 0 Then
  83.                 pp = BR.InsertionPoint
  84.                 name = "Проём"
  85.                 Set blrf = ThisDrawing.ModelSpace.InsertBlock(pp, name, 1, 1, 1, 0)
  86.                 blrf.layer = "задание_ОТВЕРСТИЯ"
  87.             End If
  88.         End If
  89.     Next BR
  90.    
  91.         'расставляю блок отверстия в местах установки ПРЯМОУГОЛЬНЫХ шахт
  92.    For Each BR In ThisDrawing.ModelSpace
  93.         If TypeName(BR) = "IAcadBlockReference" Then
  94.             name = BR.name
  95.             If sizes_bbp.Exists(name) Then
  96.                 pp = BR.InsertionPoint
  97.                 name_pr = "Проём"
  98.                
  99.                 'получение угла поворота блока ВВП
  100.                ro_angle = BR.Rotation
  101.                
  102.                 Set blrf = ThisDrawing.ModelSpace.InsertBlock(pp, name_pr, 1, 1, 1, ro_angle)
  103.                 blrf.layer = "задание_ОТВЕРСТИЯ"
  104.                 If blrf.IsDynamicBlock = True Then
  105.                         Dim size_bbp_values As Variant
  106.                         Dim pprops As Variant
  107.                         Dim pprop As Variant
  108.                         pprops = blrf.GetDynamicBlockProperties
  109.                         size_bbp_values = sizes_bbp(name)
  110.                         For Index = LBound(pprops) To UBound(pprops)
  111.                             Set pprop = pprops(Index)
  112.                                 If pprop.PropertyName = "Ширина" Then
  113.                                 pprop.Value = CDbl(size_bbp_values(0))
  114.                                 ElseIf pprop.PropertyName = "Длина/Диаметр" Then
  115.                                 pprop.Value = CDbl(size_bbp_values(1))
  116.                                 End If
  117.                         Next
  118.                 End If
  119.             ElseIf InStr(1, name, "ВВП", vbTextCompare) > 0 Then
  120.                 pp = BR.InsertionPoint
  121.                 name = "Проём"
  122.                 Set blrf = ThisDrawing.ModelSpace.InsertBlock(pp, name, 1, 1, 1, 0)
  123.                 blrf.layer = "задание_ОТВЕРСТИЯ"
  124.             End If
  125.         End If
  126.     Next BR
  127.    
  128.     If blrf Is Nothing Then ' Проверка наличия блока "Проем" в чертеже
  129.        MsgBox "Block 'Проём' not found.", vbExclamation, "Error"
  130.     Else
  131.         MsgBox "Отверстия расставлены"
  132.     End If
  133.                
  134.     On Error GoTo 0 ' Reset error handling
  135. End Sub
  136.