Vba в autocad как автоматически сделать обводку фигуры при ее изменении

Обновлено: 04.07.2024

COM-автоматизация – технология, с помощью которой приложения, написанные на различных языках программирования, могут получать функциональность программных систем (AutoCAD, Word, Excel и др.). Объектная модель приложения определяет иерархию объектов. Доступ к какому-либо свойству (или методу) конкретного объекта осуществляется через указание всех объектов в иерархической последовательности от корневого объекта (Application) и ниже.

Например, возможность обращения к командной строке из программы, написанной на языке VB, реализуется через метод SendCommand объекта ActiveDocument:

Ниже рассматривается простейший пример программы с загрузкой системы AutoCAD и управление через свойства и методы объекта Circle непосредственно из VB приложения.

В Visual Studio создайте VB проект c прототипом Windows Forms Application. На форме разместите 4 командных кнопки. При запуске VB приложения загружается диалоговое окно и запускается AutoCAD. При выборе кнопок в последовательности сверху вниз соответственно выполняются действия:


Постановка задачи. Разработать программный продукт, обеспечивающий создание в системе AutoCAD комплексного чертежа из 3-х проекций и аксонометрии.


Для решения задачи создается VB проект, который обеспечивает запуск AutoCAD, загрузку и запуск 2-х VLisp приложений.

В файле mod3d.lsp описывается создание 3D модели объекта, файле pro3.lsp – создание комплексного чертежа из 3-х проекций и аксонометрии объекта.


Структура приложения позволяет разрабатывать комплексный чертеж для любого пространственного объекта. При этом модифицируется только лишь файл mod3d.lsp.

Задание: Модифицируйте файл mod3d.lsp, обеспечив создание в AutoCAD модели в соответствии с вариантом задания.

Ниже описывается программа, обеспечивающая моделирование процесса нарезания резьбы с использованием методов и свойств объектов AutoCAD.

Откройте в AutoCAD чертеж Винт.dwg.

Создайте VB проект с формой, на которой размещены две командные кнопки. Одна из кнопок запускает процесс нарезания резьбы, вторая выгружает AutoCAD и закрывает форму. Подключите к проекту библиотеку AutoCAD. Для этого выберите кнопки меню Project>References и отметьте флажок AutoCAD 20… Type Library.

Скопируйте листинг программы (см. ниже) в окно кода. Ознакомьтесь с описанием программы, модифицируйте ее, если необходимо. Протестируйте программу.

Запустите AutoCAD и откройте чертеж-прототип Винт.dwg. При запуске программы (загрузке формы) и нажатии кнопки cmdStart устанавливается связь с этим чертежом-прототипом.

Язык программирования VisualBasic for Applications (VBA) является такой же встроенной в AutoCAD средой, как и VisualLISP среда. VBA обеспечивает более удобную среду для создания диалоговых окон по сравнению с совместным использованием для этой цели языков VLISP и DCL. Однако, VLISP более прост для программирования графических операций. К тому же графические действия выполняются на VBA медленнее, поскольку они осуществляются опосредовано через интерфейс COM-автоматизации.

Различия между VBA и VB:

  • VBA запускается в том же самом рабочем пространстве, как и AutoCAD, обеспечивая очень быструю среду программирования.
  • VBA имеет собственный набор объектов, ключевых слов, констант, и т. д., который обеспечивает управление, отладку и выполнение программы.
  • VBA не поддерживает создание выполнимых (executables) программ.
  • VBA обеспечивает связь с активным рисунком в текущем AutoCAD сеансе через объект ThisDrawing. Используя ThisDrawing Вы получаете непосредственный доступ к текущему объекту Document, всем методам, свойствам, и другим объектам в иерархии.

Если VBA не поддерживает создание выполнимых (executables) программ. Тогда возникает вопрос, каким образом запускается VBA приложение? Прежде всего, введем новый термин Макрокоманда (Macros) – это VBA подпрограмма, записанная в модуле ThisDrawing или Module. Каждая подпрограмма, записанная в этих модулях, может запускать VBA приложение. Для запуска приложения необходимо выделить имя макроса в диалоговом окне Macros (вызывается из среды AutoCAD кнопками меню Tools>Macro>Macros) и щелкнуть на кнопке Run.

Макросы можно запустить не только из диалогового окна, но и с командной строки, например:

Предварительно командой VBALOAD должен быть загружен проект, запускаемый макросом.

VLISP также позволяет запустить VBA (функция vl-vbarun), однако данные одной среды (переменные и константы) не могут быть видимы из другой среды. В этом случае существует единственная возможность обмена информацией – запись данных в файл одной программой и считывание данных из другой программы.


Примитивы чертежей AutoCAD

Пример создания класса для работы с примитивами AutoCAD

Сейчас мы попробуем создать класс объекта, который позволит нам задавать параметры и получать значения свойств отрезка. Создайте VBA проект, добавте в него модуль класса. Задайте этому модулю класса имя "imaLine".

Добавим в класс два свойства Начальную точку (StartPoint) и Конечную точку (EndPoint). Для этого опишем две переменные в разделе General Declarations модуля класса и добавим соответствующие функции:

Ну а теперь давйте придумаем, зачем нам это все было нужно и как это можно использовать.
Откройте модуль "ThisDrawing" и добавьте в него следующий код

Теперь, если Вы запустите процедуру NotARealLine и укажете две точки, то будет создан объект objLine как экземпляр класса imaLine, его свойствам будут присвоены указанные Вами точки, Х координаты которых будут напечатаны в окне Immediate.

"Ну и что с того?" - спросите Вы. И правильно спросите. Пока ничего. Надо еще доработать наш класс. Добавим в него свойство Lenght, определяющее длину линии. Это будет свойство "Только для чтения", поэтому процедура Property Let не нужна. Чтобы создать свойство Lenght добавте в модуль класса следующий код:

Подправим наш код в модуле ThisDrawing и опять запустим процедуру NotARealLine

Теперь наш класс не только занимает место на диске в виде программного кода, но и выполняет полезную работу. Вычисляет длину между указанными точками.

А представьте, ведь в этот класс можно добавить, например, метод DrawLine (Отрисовать линию). Давайте попробуем. Добавьте в модуль класса следующий код:

Снова подправим наш код в модуле ThisDrawing и опять запустим процедуру NotARealLine

Теперь мы не только получаем информацию о длине нашей линии, но и отрисовываем ее

А можно пойти и дальше, создать свойства MidPoint (Средняя точка), LineType (Тип линии, задающий собственно Тип линии, ее толщину и цвет). И это далеко не все, что можно придумать.

Можно создать класс Кольцевой сектор, со всевозможными свойствами типа Радиуса, Площадь, Периметр. И, естественно, с методом DrawSector.

Как Вам простор для деятельности?

Выбор объектов

Процедура сохранения всех объектов с заданного слоя в отдельном чертеже.

Работа с SelectionSet (Набор объектов)

  • Добавление объектов в набор путем указания мышью
  • Определение количества объектов в наборе
  • Удаление набора

Проверка, есть ли в заданной точке текстовый объект

Перед запуском процедуры создайте в текущем чертеже текстовый объект в точке X = -1.75, Y = 1.063, Z = 0. Функция вернет содержимое текстового объекта.

Получение набора объектов, пересекающихся с выбранной линией

Определение габаритов группы выбранных объектов

После запуска процедуры выберите несколько объектов и изображение будет масштабировано по их габаритам.

При запуске этой процедуры будут выбраны только текстовые объекты

Обеспечение фильтра выбора объектов

Перед запуском процедуры создайте в чертеже три слоя Prova1, Prova2 и Prova3. Разместите по несколько объектов на каждом из этих слоев. После запуска процедуры будут выбраны только те объекты, которые не находятся на слоях Prova1 и Prova2

Использование меток для создания набора

Отслеживание выбора пользователем примитивов

Если переменная blnOn равна True, то при выборе пользователем в чертеже примитива будет возникать диалоговое окно с информацией об объекте.

Изменение свойств объектов

Изменения цвета объектов с помощью диалогового окна,
вызываемого из файла ACAD.EXE

В этом примере используется вызов функции acedSetColorDialog из файла acad.exe.

Отрезки

Определение длины выбранного отрезка

Определение координат середины отрезка

Процедура отрисовки двойной ломанной линии заданной ширины
через указываемые точки

Размеры

Замена значениия размера его текстовым выражением

Процедура SelfOverRide заменяет значение размера его текстовым эквивалентом. Т.е. если текст размера равен "<>", и в чертеже отображается значение размера, например, 89,31, то процедура SelfOverRide заменит символы "<>" на символы "89,31"
К сожалению данный алгоритм работает только с линейными размерами.

Простановка вертикального или горизонтального линейного размера

Создайте в чертеже отрезок и добавьте в стандартный модуль следующий ниже код. Запустите процедуру TEST_DimLine_Horizontal_Vertical и на запрос "Выберите отрезок:" укажите созданный. Теперь осталось только указать местоположения размерных линий для вертикального и горизонтального размеров.

Группы объектов

Группировка примтивов по слоям

Поместите в стандартный модуль приведенный ниже код. Затем создайте в чертеже два слоя. Разместите на каждом из этих слоев по несколко примитивов POINT (ТОЧКА) и запустите процедуру GroupPntsByLayer. Точки будут сгруппированы по слоям и имена групп будут совпадать с именами слоев.

Пороверка наличия в чертеже групппы с заданным именем

Пример функции, проверяющей, используется ли в текущем чертеже заданная строка как имя группы. Если заданное имя уже есть, то генерируется новое имя, которое в текущем чертеже еще не используется. Эта процедура необходима при программном создании новых групп объектов. После внесения очивидных изменений на базе этой функции можно создать анологичные функции для слоев, блоков стилей и пр.

Option Explicit
Sub LineRotate()
Dim lineObj As AcadLine
Dim Pt1(0 To 2) As Double
Dim Pt2(0 To 2) As Double
Dim BasePt(0 To 2) As Double
Dim RotAngle As Double
'Указываем начальную и конечную точку
Pt1(0) = 1: Pt1(1) = 1: Pt1(2) = 0
Pt2(0) = 5: Pt2(1) = 1: Pt2(2) = 0
'Добавляем линию в пространство модели
Set lineObj = ThisDrawing.ModelSpace.AddLine(Pt1, Pt2)
'Указываем базовую точку
BasePt(0) = 1: BasePt(1) = 1: BasePt(2) = 0
'Указываем угол поворота
RotAngle = 0.7853981
'Здесь угол задан в радианах, что бы перевести в градусы
'Нужно воспользоваться формулой: Градусы = радианы/180*Pi
'Поворачиваем линию
lineObj.Rotate BasePt, RotAngle
'Обновляем объект
lineObj.Update
End Sub

Как видно не чего сложного. Единственное, немного поясню, для тех, кто не знает или забыл:
Option Explicit -оператор, который требует, чтобы все переменные в данном модуле должны быть предварительно объявлены.
Double –число с плавающей точкой двойной точности (от 4,940 656 458 412 47е-324 до 1,797 693 134 862 32е308)

Итак, все это конечно интересно, но сразу возникают вопросы: Как повернуть линию с помощью выбора в чертеже, и не линию, а вообще любой выбранный объект? Как, сделать, чтобы базовая точка была указана в чертеже, а угол в командной строке? Для рассмотрения этих вопросов перейдем к следующему шагу.

Шаг второй

Для, того чтобы выбирать объекты в чертеже, мы будем использовать наборы выбора(AcadSelectionSet) методом указания на экране объекта(SelectOnScreen).
Указывать базовую точку – методом GetPoint (возвращает значение типа Variant, содержащее трехмерный массив). Пользователь может указать точку или задать ее координаты.
Для ввода угла поворота применим метод GetInteger ( Integer – целые числа в диапазоне от -32768 до +32767).Пользователю выдается приглашение ввести число. Смотрим код:

Option Explicit
Sub ObjRotate()
Dim Obj As AcadEntity
Dim BasePt As Variant
Dim SelSet As AcadSelectionSet
Dim GradAngle As Integer
Dim RotAngle As Integer
On Error GoTo Control
'Создаем новый набор выбора, например с именем "Set"
Set SelSet = ThisDrawing.SelectionSets.Add("Set")
'Запрос на выбор примитивов
SelSet.SelectOnScreen
'Если не чего не выбрано, переходим к "Control"
If SelSet.Count = 0 Then GoTo Control
'Указываем базовую точку
BasePt = ThisDrawing.Utility.GetPoint(, "Укажите базовую точку: ")
'Вводим угол поворота(в градусах)
GradAngle = ThisDrawing.Utility.GetInteger("Введите угол поворота:")
'Переводим градусы в радианы
RotAngle = GradAngle / 180 * 3.141592653
For Each Obj In SelSet
'Выполняем поворот объекта
Obj.Rotate BasePt, RotAngle
'Обновляем объект
Obj.Update
Next Obj
Control:
SelSet.Delete 'Удаляем набор выбора
End Sub

Некоторые пояснения:
AcadEntity-объект AutoCAD
Variant - Переменная, которая может содержать данные любого типа. Если, есть возможность, рекомендуется воздерживаться от применения этого типа и объявлять тип явно(например:Integer, Double и т.д.), так как программе требуется больше времени на считывание данных.
On Error GoTo Control- один из операторов, с помощью которого можно контролировать работу программы при возникновении ошибок. Если обнаружена ошибка, то происходит переход к метке“Control:” В нашем случае это удаление набора выбора и выход.
If SelSet.Count = 0 Then GoTo Control- условный оператор. Если выражение истинно, то Оператор выполнится, если ложно, то нет. Здесь SelSet.Count - количество объектов в наборе.
For Each Obj In SelSet - форма цикла предназначенная для выполнения какой-либо операции с каждым объектом, входящим в состав некоторой коллекции объектов:
For Each ИмяОбъекта In ИмяКоллекции
Операции над объектами
Next ИмяОбъекта

Ну вот, с этим мы вроде как разобрались. Давайте немного разнообразим код, а заодно получим некоторые навыки при работе с формами.

Шаг третий

Допустим, нам нужно, чтобы на экране появлялось диалоговое окно, в котором можно было бы ввести угол поворота.
Для начала вставим форму. В окне свойств(Properties Window) формы, значение в поле Name изменим на “Form1”. Значение в поле Caption изменим, например, на “Поворот объекта“
Добавим на форму несколько элементов:

Label(Надпись), который используется для отображения текста. В свойствах изменим значение Caption на “Угол:” Кстати, так же в свойствах можно изменить цвет и размеры элемента, выравнивание, шрифт и т.д.

TextBox(Текстовое поле)- служит для ввода или вывода информации, которая используется в программе. Изменим свойство Name на “Text1”.
(Если нужно запретить изменение содержимого текстового поля, когда форма появляется на экране в свойствах значение Locked надо поставить на True.Если нужно, чтобы в текстовом поле при появлении формы постоянно находилось какое-либо значение, в свойствах в поле Value надо указать это значение. Если нужно ограничить количество введенных символов, то его можно указать в свойстве MaxLength.)

SpinButton(Счетчик)-дает возможность пользователю указывать числовое значение. Он используется вместе с элементом TextBox. В его свойствах задаются:
Max - определяет максимальное значение элемента SpinButton
Min - минимальное значение
Value - текущее значение
Пусть у нас будет задано:Max=360,Min= -360,Value=0

CommandButton(командная кнопка) - используется для выполнения какого-либо действия, например, запуск какой-то опперации. В нашем примере мы будем использовать два этих элемента:
Первый для запуска. В свойствах, в поле Name зададим ему имя cmdApply,в поле Caption – “OK”.
Второй для выхода. Name-“cmdCancel”, Caption – “Cancel”.
Короче, говоря, должно получиться что-то похожее как на рисунке.

Form VBA

Идем дальше. Дважды щелкнем(кликнем) на кнопке”OK”(элемент cmdApply) и добавим в процедуру “Private Sub cmdApply_Click()”знакомый нам, но немного измененный код:

С элементом TextBox думаю все понятно, теперь заставим работать элемент SpinButton. Дважды щелкнем(кликнем) на нем и добавим в процедуру “Private Sub SpinButton1_Change()” следующее:

Private Sub SpinButton1_Change()
Text1.Text = SpinButton1.Value
'Значение TextBox = Значению SpinButton
End Sub

Рассмотрим кнопку Cancel. Снова дважды щелкнем(кликнем), на кнопке“Cancel”(элемент cmdCancel),чтобы добавим в процедуру”Private Sub cmdCancel_Click()” следующий код:

Private Sub cmdCancel_Click()
Unload Me 'Закрываем окно(см.выше)
End Sub

Теперь осталось добавить в проект модуль, для вызова формы. И вставить в него такой код:

Sub Rotate()
Form1.Show
End Sub

Здесь “Form1”-имя нашей формы.
Show-метод, загружающий и показывающий форму на экране.

Я инженер-проектировщик ОВиК, не программист. И не хочу, да и некогда, вникать в серьезное программирование. Чаще всего появляется ситуация, что нужно как-то автоматизировать рутину здесь и сейчас. На помощь приходит простой язык VBA.

Далее я покажу, как можно без особых забот сделать самому то, за что серьезные ребята берут не плохие денежки. А именно перенос данных из Excel в AutoCAD и обратно. Заинтересованных прошу под кат.

Программировать будем на стороне Excel — мне так проще. Для подключения нужно войти в режим разработчика: Alt+F8 Либо можно открыть вкладку «разработчик» из настроек ленты.

В окне разработчика VBA входим в верхнее меню: Tools/References. В этом окне нужно поставить галочку на вашей версии AutoCAD


В моем случае это AutoCAD 2014 Type Library. Далее нужно в левом окне создать в вашей книге модуль, как на скриншоте (Module)


И в модуль вставляем нижеприведенный код:


Аналогичным способом можно создавать блоки с атрибутами, в которые можно вставлять текст из ячеек.
Нужно внести в верхний код изменения вроде:


Код обновления текста по хэндлу — написан ниже: 'получаем хэндл из ячейки, в которую мы записали кодом выше.

entHandle = ActiveCell.Offset(0, 3).Value 'получили наш блок по хэндлу
Set blockObj = acadDoc.HandleToObject(entHandle)

А дальше делаем всё то же самое, что и выше.

Для того, чтобы немного разъяснить как это работает вживую — записал видео:

Как видите, кода минимум, однако на больших объектах мне экономит по несколько часов работы. И снижается риск ошибки. Т.к. обычно это выглядит следующим образом у проектировщиков — открываются два окна на разных экранах, и или вручную, или через буфер обмена начинается заполнение выносок или блоков на чертеже.

Опять же чем хорош VBA — что он всегда под рукой :) Excel-то основной инструмент у инженера.

Читайте также: