| Правила | Регистрация | Пользователи | Поиск | Сообщения за день | Все разделы прочитаны |  Справка по форуму | Файлообменник |

Вернуться   Форум DWG.RU > Программное обеспечение > Программирование > VBA Не добавляются новые блоки в цикл по всем вхождениям блоков в пространстве Модели

VBA Не добавляются новые блоки в цикл по всем вхождениям блоков в пространстве Модели

Ответ
Поиск в этой теме
Непрочитано 10.11.2016, 21:01 #1
VBA Не добавляются новые блоки в цикл по всем вхождениям блоков в пространстве Модели
99xt1
 
нефтепереработка
 
Мозырь, Республика Беларусь
Регистрация: 17.11.2009
Сообщений: 77

Простой цикл перебора существующих вхождений блоков в пространстве модели

Код:
[Выделить все]
Dim blk As AcadBlockReference
Dim acadDoc As AcadDocument
Dim rownr As Integer
rownr = 1

For Each blk In acadDoc.ModelSpace
rownr = rownr + 1
Next blk
MsgBox ("Обновлено " & rownr - 1 & " блоков")
Так вот, при создании нового блока и его вставке в чертеж, после сохранения чертежа (проверял даже Сохранить-Закрыть-ОткрытьЗаново) это вхождение блока не обрабатывается этим циклом. Может кто сталкивался с похожей проблемой?
Просмотров: 3588
 
Непрочитано 10.11.2016, 22:01
#2
Сергей812


 
Регистрация: 10.08.2013
Сообщений: 11,000


где и чем инициализируется переменная acadDoc? Переменные глобальные? Если закрыть акад и снова открыть, загрузить чертеж и VBA проект - код обработает блок?
Сергей812 вне форума  
 
Непрочитано 10.11.2016, 23:25
#3
Кулик Алексей aka kpblc
Moderator

LISP, C# (ACAD 200[9,12,13,14])
 
Регистрация: 25.08.2003
С.-Петербург
Сообщений: 39,787


99xt1, показывай весь код. Потому что сейчас он выглядит как минимум странно. А заодно уточни - VBA работает из-под AutoCAD или нет.

----- добавлено через ~1 мин. -----
... и почему было не воспользоваться SelectionSet - непонятно...
__________________
Моя библиотека lisp-функций
---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Кулик Алексей aka kpblc вне форума  
 
Автор темы   Непрочитано 10.11.2016, 23:57
#4
99xt1

нефтепереработка
 
Регистрация: 17.11.2009
Мозырь, Республика Беларусь
Сообщений: 77


Запускаю код из Excel

Код:
[Выделить все]
Sub CreateBlockListInExcel()
Dim blk As AcadBlockReference
Dim wrks As Excel.Worksheet
Dim acadApp As AcadApplication
Dim acadDoc As AcadDocument
Dim MyPath As String
Dim lLastRow As Integer
    
Application.DisplayAlerts = False

    On Error Resume Next
    Set acadApp = GetObject(, "AutoCAD.Application")
        
    If acadApp Is Nothing Then
        Set acadApp = CreateObject("AutoCAD.Application")
        acadApp.Visible = True
    End If
    
    Set acadDoc = acadApp.ActiveDocument
    MyPath = "Z:\КУГ\Закупка и поставка оборудования\0. Монтаж - склад - закупка КУГ.dwg"
    If acadDoc.FullName <> MyPath Then
    acadApp.Documents.Open (MyPath)
    Set acadDoc = acadApp.ActiveDocument
    End If
    
    acadDoc.ActiveSpace = acModelSpace

    Set wrks = ActiveSheet
    lLastRow = Cells(Rows.Count, 1).End(xlUp).Row
    Range("A1:F" & lLastRow).Clear
    
    wrks.Range("A1") = "BLOCKNAME"
    wrks.Range("B1") = "LAYERNAME"
    wrks.Range("C1") = "EFFECTIVENAME"
    wrks.Range("D1") = "X"
    wrks.Range("E1") = "Y"
    wrks.Range("F1") = "Z"
    
    Dim rownr As Integer
    rownr = 1
      
    For Each blk In acadDoc.ModelSpace
        rownr = rownr + 1
        wrks.Range("A" & rownr) = blk.Name
        wrks.Range("B" & rownr) = blk.Layer
        wrks.Range("C" & rownr) = blk.EffectiveName
        wrks.Range("D" & rownr) = blk.InsertionPoint(0)
        wrks.Range("E" & rownr) = blk.InsertionPoint(1)
        wrks.Range("F" & rownr) = blk.InsertionPoint(2)
    Next blk
    MsgBox ("Обновлено " & rownr - 1 & " блоков")
  
End Sub
При удалении блоков, кол-во выводимых в Excel уменьшается (цикл меньше работает).

Победил сейчас добавив
Код:
[Выделить все]
Dim AcEnt As AcadEntity
    For Each AcEnt In acadDoc.ModelSpace
    If TypeOf AcEnt Is AcadBlockReference Then
        Set blk = AcEnt
Ну, а потом уже вывод данных в Excel. Т.к. в пространстве модели 300 блоков и 2 растра, то перебор всех элементов пространства модели не так сильно увеличивает время работы (перебираются всего 2 лишних растра)
99xt1 вне форума  
 
Непрочитано 11.11.2016, 00:15
#5
Сергей812


 
Регистрация: 10.08.2013
Сообщений: 11,000


сразу замечание по поводу экселя: если код должен выполняться в определенной книге, то обязательно указывайте ThisWorkBook. Иначе при открытии несколько книг экселя получите выполнение кода в активной книге, а в не в той - где предполагали) Затем: Application.DisplayAlerts = False - а включать кто будет? Не удалось подключиться к уже запущенному экземпляру акада или создать новый - почему код пошел дальше выполняться?
Сергей812 вне форума  
 
Непрочитано 11.11.2016, 00:30
#6
Кулик Алексей aka kpblc
Moderator

LISP, C# (ACAD 200[9,12,13,14])
 
Регистрация: 25.08.2003
С.-Петербург
Сообщений: 39,787


For Each blk In acadDoc.ModelSpace
Стоит мне нарисовать отрезок - и все, код вылетит.
P.S. Я бы, наверное, подобное все же делал напрямую из ACAD'a, выводя информацию в тот же *.CSV.

----- добавлено через 54 сек. -----
P.P.S. Похоже, что используется раннее связывание. Тоже не самое лучшее решение ИМХО.
__________________
Моя библиотека lisp-функций
---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Кулик Алексей aka kpblc вне форума  
 
Непрочитано 11.11.2016, 00:36
#7
Сергей812


 
Регистрация: 10.08.2013
Сообщений: 11,000


в VBA размерность массива в цикле for each временно блокируется...
Сергей812 вне форума  
 
Непрочитано 11.11.2016, 09:18
#8
Кулик Алексей aka kpblc
Moderator

LISP, C# (ACAD 200[9,12,13,14])
 
Регистрация: 25.08.2003
С.-Петербург
Сообщений: 39,787


Сергей812, если я правильно понимаю, то блокировка идет только на время выполнения цикла.
__________________
Моя библиотека lisp-функций
---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Кулик Алексей aka kpblc вне форума  
 
Непрочитано 11.11.2016, 09:34
#9
Сергей812


 
Регистрация: 10.08.2013
Сообщений: 11,000


Цитата:
Сообщение от Кулик Алексей aka kpblc Посмотреть сообщение
если я правильно понимаю, то блокировка идет только на время выполнения цикла.
Да, внутри цикла можно поменять содержимое ячеек массива, но при попытке изменить размерность (в случае дин.массива) вылетает ошибка runtime. А проверку на тип примитива ТС вставил же в код - почему при добавлении отрезка код должен вылететь?

p.s. И как уже неоднократно писал - не заполняйте массивы ячеек экселя путем отдельного обращения к каждой ячейке. Заполнили двухмерный массив Variant и одной строкой блок данных перенесли на лист - скорость заполнения листа увеличивается на порядок и более.
Сергей812 вне форума  
 
Автор темы   Непрочитано 11.11.2016, 10:20
#10
99xt1

нефтепереработка
 
Регистрация: 17.11.2009
Мозырь, Республика Беларусь
Сообщений: 77


С подключением к Автокаду почему то появляются периодические проблемы. Поэтому я просто заранее запускаю нужный файл dwg, и потом уже из Excel выполняю код.
Вот это
Цитата:
p.s. И как уже неоднократно писал - не заполняйте массивы ячеек экселя путем отдельного обращения к каждой ячейке. Заполнили двухмерный массив Variant и одной строкой блок данных перенесли на лист - скорость заполнения листа увеличивается на порядок и более.
насколько я понял относится к
Код:
[Выделить все]
wrks.Range("A" & rownr) = blk.Name
        wrks.Range("B" & rownr) = blk.Layer
        wrks.Range("C" & rownr) = blk.EffectiveName
        wrks.Range("D" & rownr) = blk.InsertionPoint(0)
        wrks.Range("E" & rownr) = blk.InsertionPoint(1)
        wrks.Range("F" & rownr) = blk.InsertionPoint(2)
?
Хорошо, это потом пооптимизирую.

Главный вопрос в другом:
Почему после:
1. добавления нового блока в чертеж.
2. Сохранении чертежа и закрятия Автокада.
3. Перезагрузки компьютера.
4. открытия файла dwg
5. Открытия файла xlsm и выполнения кода

строка For Each blk In acadDoc.ModelSpace не перебирает этот новый блок?
99xt1 вне форума  
 
Непрочитано 11.11.2016, 10:33
#11
Boxa

КЖ; C#
 
Регистрация: 03.11.2005
Санкт-Петербург
Сообщений: 2,588


Важно понимать, что означает фраза
Цитата:
Сообщение от 99xt1 Посмотреть сообщение
1. добавления нового блока в чертеж.
Строка For Each blk In acadDoc.ModelSpace перебирает не блоки, а все объекты в пространстве модели. Нет в модели, не перебирает.
Boxa вне форума  
 
Автор темы   Непрочитано 11.11.2016, 11:56
#12
99xt1

нефтепереработка
 
Регистрация: 17.11.2009
Мозырь, Республика Беларусь
Сообщений: 77


Блок создан в чертеже и его вставлен в него. Т.е. не только в библиотеке блоков он есть, но и в самом пространстве модели есть его вхождение.


В принципе решение задачи нашёл (см. выше).
Но вот просто разобраться хочу, почему не работает For Each
99xt1 вне форума  
 
Непрочитано 11.11.2016, 12:34
#13
Сергей812


 
Регистрация: 10.08.2013
Сообщений: 11,000


в принципе, логично: ModelSpace - это коллекция всех примитивов, размещенных в пространстве модели. А не только вставок блоков. А вот почему себя так ведет: сделайте копию чертежа, удалите лишнее, смоделируйте ситуацию со вставкой блока - если будет вести себя аналогично, то сделайте пошаговую трассировку, отслеживая состояние переменных. Если не найдется причина, попробуйте сделать через цикл for и ModelSpace.Count, например.
Сергей812 вне форума  
Ответ
Вернуться   Форум DWG.RU > Программное обеспечение > Программирование > VBA Не добавляются новые блоки в цикл по всем вхождениям блоков в пространстве Модели

Размещение рекламы
Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Штриховка в пространстве модели philija AutoCAD 9 21.02.2020 13:35
Масштаб в пространстве модели? Помогите определиться с настройками ВладимирВ AutoCAD 6 16.03.2016 05:00
Viewport закрывает объекты, созданные в пространстве модели. Voltegirev AutoCAD 3 09.10.2013 14:31
Перебор блоков в модели и создание надписи с именем слоя Sanmart Программирование 2 16.04.2010 09:27
Как генерировать блоки с атрибутами в пространстве модели(листа) при помощи LISP!!! SpillOver LISP 27 08.01.2010 21:36