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

Вернуться   Форум DWG.RU > Программное обеспечение > Программирование > Как программно обновить блок, если добавлен новый атрибут?

Как программно обновить блок, если добавлен новый атрибут?

Ответ
Поиск в этой теме
Непрочитано 21.03.2019, 17:43 #1
Как программно обновить блок, если добавлен новый атрибут?
stuff
 
Регистрация: 28.01.2019
Сообщений: 14

Всем привет.

Добавляю новый атрибут в выделенные блоки:

Код:
[Выделить все]
Sub SelectObjectsOnscreen1()
  
 Dim acEnt As AcadEntity
 Dim varAtts As Variant
 Dim intCnt As Integer
 Dim Msg As String
 Dim IsElectric As Boolean
 
 Dim newBlock As AcadBlock
 Dim newAtr As AcadAttribute
 
 Dim insertionPoint1(0 To 2) As Double
 insertionPoint1(0) = 5
 insertionPoint1(1) = 5
 insertionPoint1(2) = 0

 ' Создание нового набора
 Dim sset As AcadSelectionSet
 Set sset = ThisDrawing.SelectionSets.Add("SS23")
 
 On Error GoTo ErrorHandler
 
 ' Запрос пользователю выбрать объекты и добавление их в набор
 sset.SelectOnScreen
 
 ' Перебор выбранных объектов
 For Each acEnt In sset


   If TypeOf acEnt Is AcadBlockReference Then

      If acEnt.HasAttributes Then
      
         varAtts = acEnt.GetAttributes
      
         For intCnt = LBound(varAtts) To UBound(varAtts)
         
           If Trim(varAtts(intCnt).TagString) = "ЕЛ.ПОТУЖНІСТЬ,КВТ" And Trim(varAtts(intCnt).TextString) <> "" Then
              IsElectric = True
           End If
         
         Next intCnt

         'Если это электрический элемент, создаем в нем атрибут принадлежности к электрическому щиту
         If IsElectric = True Then
            Set newBlock = ThisDrawing.Blocks(acEnt.Name)
            Set newAtr = newBlock.AddAttribute(100, acAttributeModeInvisible, "принадлежности к электрическому щиту", insertionPoint1, "NameElectricalPanel", NameElectricalPanel)
            
            newAtr.Visible = True
            newAtr.Invisible = False
            
            newAtr.Update
            
            acEnt.Visible = True
            acEnt.Update
            
            
         End If
         
      End If
      
   End If
   
 Next acEnt
 
ErrorHandler:
 ' Удаление набора
 sset.Delete
 
 ' Если возникла ошибка, ее описание
 If Err.Number <> 0 Then
    Msg = "Error # " & str(Err.Number) & " was generated by " _
            & Err.Source & Chr(13) & Err.Description
    MsgBox Msg, , "Error", Err.HelpFile, Err.HelpContext
 End If
         
 
End Sub
Обновляю этим фрагментом кода:

Код:
[Выделить все]
newAtr.Visible = True
newAtr.Invisible = False
            
newAtr.Update
            
acEnt.Visible = True
acEnt.Update
После добавления, новый атрибут нельзя увидеть в списке всех атрибутов, через интерфейсное окно AutoCad.

Видимость нового атрибута в блоке можно установить только по средством AutoCad - Редактировать -> Объект -> Атрибуты -> Диспетчер атрибутов блоков... -> Обновить -> Ok



ВОПРОС: Как программно обновить блоки с новым атрибутом?
Просмотров: 4979
 
Непрочитано 21.03.2019, 21:20
#2
Кулик Алексей aka kpblc
Moderator

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


Цитата:
Сообщение от stuff Посмотреть сообщение
Как программно обновить блоки с новым атрибутом?
Самый простой вариант - в тихом режиме выполнить _.attsync.
__________________
Моя библиотека lisp-функций
---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Кулик Алексей aka kpblc вне форума  
 
Непрочитано 21.03.2019, 22:53
1 | 1 #3
Сергей812


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


Цитата:
Сообщение от Кулик Алексей aka kpblc Посмотреть сообщение
в тихом режиме выполнить _.attsync.
только при этом учитывайте:
Цитата:
Прим.: Команда АТРОБНОВИТЬ удаляет любое, внесенное командами АТРЕД или АТРЕДАКТ изменение формата или свойства. Она также удаляет любые дополнительные данные, связанные с блоком, и может повлиять на динамические блоки или блоки, созданные в приложениях сторонних разработчиков.
Сергей812 вне форума  
 
Автор темы   Непрочитано 21.03.2019, 23:08
#4
stuff


 
Регистрация: 28.01.2019
Сообщений: 14


Цитата:
Сообщение от Кулик Алексей aka kpblc Посмотреть сообщение
Самый простой вариант - в тихом режиме выполнить _.attsync.
Спасибо.

Этот код решил проблему при обновлении одного блока:

Код:
[Выделить все]
ThisDrawing.SendCommand "(acet-attsync" & Chr(34) & acEnt.Name & Chr(34) & ") "
Но если прописать этот код в цил перебора блоков, то на втором блоке выдает ошибку:

Цитата:
Error # -2145386296 was generated by AutoCAD
Недoпустимый контекст выпoлнения
Что может быть? Хотелось в цикле перебирать все изменённые блоки.
stuff вне форума  
 
Непрочитано 21.03.2019, 23:31
1 | 1 #5
Кулик Алексей aka kpblc
Moderator

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


Может, надо использовать не .Name, а .EffectiveName
А так - смотри:
_.attsync <Enter> _n <Enter> * <Enter>
Решит твою проблему?

----- добавлено через 38 сек. -----
Сергей812, так я и не говорю, что решение универсальное

----- добавлено через ~2 мин. -----
P.S. Вообще, учитывая, как в ACAD живут атрибуты, без танцев с бубнами их не синхронизировать. Андрей Бушман, если я правильно помню, в свое время пытался сделать аналог _.attsync на .NET, и потерпел фиаско.
__________________
Моя библиотека lisp-функций
---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Кулик Алексей aka kpblc вне форума  
 
Непрочитано 22.03.2019, 00:52
#6
Сергей812


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


Offtop:
Цитата:
Сообщение от stuff Посмотреть сообщение
'Если это электрический элемент, создаем в нем атрибут принадлежности к электрическому щиту
If IsElectric = True Then
Это уже классика)


А как костыль к решению: вставить атрибут изначально и попробовать играться уже с видимостью вставки атрибута. Можно было бы хранить в расширенных данных вставки блока - но VBA вроде не позволяет создать PaletteSet (палитру) или "внедряться" в окно свойств. А без этого вменяемый интерфейс не сделаешь, имхо.

Цитата:
Сообщение от Кулик Алексей aka kpblc Посмотреть сообщение
Андрей Бушман, если я правильно помню, в свое время пытался сделать аналог _.attsync на .NET, и потерпел фиаско.
хм?
Сергей812 вне форума  
 
Автор темы   Непрочитано 22.03.2019, 10:45
#7
stuff


 
Регистрация: 28.01.2019
Сообщений: 14


Цитата:
Сообщение от Кулик Алексей aka kpblc Посмотреть сообщение
Может, надо использовать не .Name, а .EffectiveName
C .EffectiveName на втором блоке при переборе выделенных блоков выдает туже самую ошибку...

Цитата:
Error # -2145386296 was generated by AutoCAD
Недoпустимый контекст выпoлнения
Цитата:
Сообщение от Кулик Алексей aka kpblc Посмотреть сообщение
_.attsync <Enter> _n <Enter> * <Enter>
Как эту команду на VBA написать?

Пробовал так:

Код:
[Выделить все]
ThisDrawing.SendCommand "_.attsync <Enter> " & acEnt.Name & " <Enter> * <Enter>"
Пишет неправильное ключевое слово...
stuff вне форума  
 
Непрочитано 22.03.2019, 10:53
1 | 1 #8
Сергей812


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


Цитата:
Сообщение от stuff Посмотреть сообщение
<Enter>
на это ругается, Алексей так пишет лишь для наглядности.
Сергей812 вне форума  
 
Непрочитано 22.03.2019, 11:01
#9
Кулик Алексей aka kpblc
Moderator

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


Сергей812, где-то было обсуждение, что представленный код то ли некорректно срабатывал, то ли еще что-то. Точно не помню
__________________
Моя библиотека lisp-функций
---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Кулик Алексей aka kpblc вне форума  
 
Автор темы   Непрочитано 22.03.2019, 11:41
#10
stuff


 
Регистрация: 28.01.2019
Сообщений: 14


Вообщем есть три рабочих команды для обновления блока:

Код:
[Выделить все]
ThisDrawing.SendCommand "(acet-attsync" & Chr(34) & acEnt.Name & Chr(34) & ") "
ThisDrawing.SendCommand "ATTSYNC" & vbCr & "ИМЯ" & vbCr & acEnt.Name & vbCr
ThisDrawing.SendCommand "_.attsync" & vbCr & "ИМЯ" & vbCr & acEnt.Name & vbCr
Они прекрасно обновляют один выделенный блок.

Но выдают ошибку, если их вставить в цикл перебора выделенных блоков...

Почему возникает ошибка на втором блоке в цикле перебора?

----- добавлено через ~32 мин. -----
Получается, что команда ATTSYNC не корректно работает, если выбрано несколько блоков...
Если выбран только один блок - то все Ok

Последний раз редактировалось stuff, 22.03.2019 в 12:19.
stuff вне форума  
 
Непрочитано 22.03.2019, 13:52
1 | 1 #11
Кулик Алексей aka kpblc
Moderator

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


Я звездочку зачем поставил, как думаешь?
__________________
Моя библиотека lisp-функций
---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Кулик Алексей aka kpblc вне форума  
 
Автор темы   Непрочитано 22.03.2019, 14:50
#12
stuff


 
Регистрация: 28.01.2019
Сообщений: 14


Проблема решилась, если использовать PostCommand:

Код:
[Выделить все]
ThisDrawing.PostCommand "(acet-attsync" & Chr(34) & acEnt.Name & Chr(34) & ") "
https://forums.autodesk.com/t5/visua...d/td-p/5854952

Цитата:
I have found a work around this problem.

In stead of Using "ThisDrawing.SendCommand" with a parameter list, you can use "ThisDrawing.PostCommand" with the same parameter list.

The command will then be processed asynchronously in stead of synchronously, but with the same parameter list it will behave the same way.

I used this work around in a macro where I print multiple drawing views, using a loop.

Последний раз редактировалось stuff, 22.03.2019 в 21:22.
stuff вне форума  
 
Непрочитано 23.03.2019, 10:28
1 | #13
VVA

Инженер LISP
 
Регистрация: 11.05.2005
Минск
Сообщений: 6,991
<phrase 1= Отправить сообщение для VVA с помощью Skype™


Цитата:
Сообщение от Кулик Алексей aka kpblc Посмотреть сообщение
_.attsync <Enter> _n <Enter> * <Enter>
Цитата:
Сообщение от Кулик Алексей aka kpblc Посмотреть сообщение
Я звездочку зачем поставил, как думаешь?
stuff, Попробуй так
Код:
[Выделить все]
ThisDrawing.SendCommand "_.attsync" & vbCr & "_N" & vbCr & "*" & vbCr
или даже так
Код:
[Выделить все]
ThisDrawing.SendCommand "_.attsync\n_N\n*\n"
__________________
Как использовать код на Лиспе читаем здесь
VVA вне форума  
 
Автор темы   Непрочитано 23.03.2019, 11:05
#14
stuff


 
Регистрация: 28.01.2019
Сообщений: 14


PostCommand решает все проблемы
stuff вне форума  
 
Непрочитано 23.03.2019, 11:24
#15
Сергей812


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


Цитата:
Сообщение от stuff Посмотреть сообщение
PostCommand решает все проблемы
и добавляет новые - так как работает асинхронно в момент простоя акада)
Сергей812 вне форума  
 
Непрочитано 03.02.2024, 13:00
#16
Barmaley Bubusikin


 
Регистрация: 05.06.2014
Сообщений: 77


Цитата:
Сообщение от Сергей812 Посмотреть сообщение
так как работает асинхронно в момент простоя акада)
1. Правильно ли я понял что с 2015 PostCommand выполняется синхронно, а SendCommand - асинхронно?
2. При выполнении кода из топика появляется ошибка: no function definition: ACET-ATTSYNC. Ошибка не появляется, если перед этим вручную выполнить хотя бы один раз АТРОБНОВИТЬ. Это можно как-то обойти?
Barmaley Bubusikin вне форума  
 
Непрочитано 03.02.2024, 14:30
#17
Barmaley Bubusikin


 
Регистрация: 05.06.2014
Сообщений: 77


Цитата:
Сообщение от Barmaley Bubusikin Посмотреть сообщение
При выполнении кода из топика появляется ошибка: no function definition: ACET-ATTSYNC. Ошибка не появляется, если перед этим вручную выполнить хотя бы один раз АТРОБНОВИТЬ.
Сделал так. Для первого вхождения выполняю:
Код:
[Выделить все]
 ThisDrawing.SendCommand "ATTSYNC" & vbCr & "ИМЯ" & vbCr & acEnt.Name & vbCr
для следующих:
Код:
[Выделить все]
 ThisDrawing.PostCommand "(acet-attsync" & Chr(34) & acEnt.Name & Chr(34) & ") "
Barmaley Bubusikin вне форума  
Ответ
Вернуться   Форум DWG.RU > Программное обеспечение > Программирование > Как программно обновить блок, если добавлен новый атрибут?

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

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


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Как обновить внешнюю ссылку DWG если изменилось название файла Zets AutoCAD 10 23.02.2021 14:43
Почему атрибут не сдвигается от ручки выбора?(динамический блок) prajdziswet Динамические блоки 3 26.04.2017 14:49
Как программно прочитать цвет слоя, если он задан в формате RGB? 480725 LISP 7 09.03.2017 12:01
Как программно вставить блок с атрибутами. Kirill_Ja Программирование 6 12.05.2012 00:53
Аннотативный блок в составе обыкновенного Ruppel Динамические блоки 11 20.03.2008 10:53