Autocad vba вставить блок

Обновлено: 06.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), однако данные одной среды (переменные и константы) не могут быть видимы из другой среды. В этом случае существует единственная возможность обмена информацией – запись данных в файл одной программой и считывание данных из другой программы.

Для создания нового блока из набора выбранных объектов нам понадобиться две функции. Первая будет проверять заданное нами имя нового блока на возможность его использования, и, если задаваемое имя уже используется в текущем как имя блока, то эта функция сгенерирует новое имя. Вторая функция будет создавать блок из заданного набора объектов:

В этом примере функция BlockNameIncrement немного не доработана. Не плохо бы добавить проверку на наличие в задаваемом имене недопустимых символов. Да и в функции BlockSelSet такая проверка не помешает. Но я думаю что обеспечение этой проверки не вызовит у Вас затруднений.

Диалоговое окно для вставки блока

Добавьте в проект новую форму, задайте ей имя frmBlkInsert и разместите на ней следующие элементы управления:

Два переключателя (Option Buttons)
Один флажек (Check box)
Одну метку (Label)
Один раскрывающийся список (Combo Box)
Одну кнопку (Command Button)

В итоге форма должна выглядеть примерно так:

Теперь добавьте в проект стандартный модуль и добавьте в него процедуру, запускающую наше диалоговое окно:

Теперь создайте в чертеже два блока с теми именами, которые Вы использовали в качестве свойст Caption к элементам OptionButton1 и OptionButton2 в процедуре UserForm_Initialize модуля формы и запустите макрос TEST_frmBlkInsert. Пример, конечно, очень прост. С помощью этого диалогового окна можно вставльять только два строго определенных заранее блока. В принципе есть возможность вместо двух OptionButton разместить на форме ComboBox и попробовать заполнить его именами всех определенных в чертеже блоков.

Удалите из формы элементы OptionButton и вставьте вместо них еще один ComboBox. У Вас должно получиться что-то похожее на следующую картинку:

Теперь надо слегка изменить процедуры UserForm_Initialize и CommandButton1_Click

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

Вставка блока в масштабе, равном масштабу текущего размерного стиля

Не буду приводить здесь весю процедуру вставки блока, ее можно посмотреть в предидущих примерах. Рассмотрим отрывок кода, определяющий масштаб, заданный в текущем стиле размеров:

Вставка блоков в точки, совпадающие с вершинами выбранной полилинии

Перед использованием примера задайте в процедуре TEST_InsertBlocksEX имя блока, определенного в текущем чертеже.

Расчленение блока и перенос всех элементов блока на заданный слой

Ну, думаю, тут и так все ясно. Упомяну только, что кроме всего прочего, если в разбиваемом блоке есть аттрибуты, то функция удаляет их.

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

Функция из следующего примера позволяе "выдернуть" примитив заданного типа, находящийся на заданном слое из блока с заданным именем, определенным в текущем чертеже. Создайте блок, один из элементов которого полилиния (AcadLWPolyline), находящаяся на слое Layer2. Блок можете даже не вставлять. Просто запустите TEST_GetEntityFromBlock. Полилиния будет вставлена в чертеж так, как она была бы вставлена вместе с блоком, вставленным в точку 0,0,0. У функции есть недостаток (а может это преимущество?): если в блоке несколько полилиний, то возвращена будет та, которая определена в блоке первой. В принципе, функцию можно переделать так, чтобы она выдергивала из блока все объекты заданного типа и вставляла их в точки, указываемые пользователем, но, это уже Ваши проблемы…

Нахождение в чертеже всех вставленных блоков с заданным именем

Процедура GetBlkRefs добавляет в созданный ранее набор objSelSet все вставленные в чертеж блоки с именем strBlkName

Создание в таблице Excel списка всех вставленных в чертеж блоков и их количества

Вставьте в чертеж несколько блоков, запустите MS Excel, в котором создайте новую книгу. Теперь вернитесь к AutoCAD, добавьте в стандартный модуль следующий ниже код. Не забудьте добавить в проект ссылку на Excel Object type Library. Запустите процедуру SortBlocksWithCount. После ее работы в текущей таблице MS Excel будет создан список всех вставленных в чертеж блоко и будет указано их количество. Чем не основа для создания программы, автоматически создающей спецификацию к сборочному чертежу?

Изменение всех длинных имен блоков на короткие

AutoCAD 2000 (15) позволяет создавать блоки с именами, которые состоят более чем из 31 символа, а AutoCAD 14 и более ранние версии не воспринимают таких имен. В случаях, когда в чертеже есть блоки с длинными именами и чертеж нужно сохранить в формате AutoCAD 14 может помоч процедура, подобная следующей:

Определение масштабных коэффициентов блока по осям

Следующая процедура возвращает массив, в котором содержатся масштабные коэффициенты по осям X, Y и Z, с которыми блок objBlk вставлен в чертеж

Изменение слоя всех вставленных блоков

Представленная ниже процедура changeBlockSeqEndLayer изменяет слой всех вставленных блоков на слой с заданным именем.

Замена существующего блока на блок из заданного файла

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

Вставка блока с аттрибутами и запрос их значений

Создайте в чертеже блок с аттрибутами или найдите на диске файл, который можно использовать в качестве такого блока. Вставьте в стандартный модуль VBA приведенный ниже код. Теперь подкорректируйте процедуру TEST_VBD_InsertBlock, заменив имя блока, присваеваемое переменной strBlkName на то, которое определено в чертеже или на имя найденного Вами файла. Обращаю Ваше внимание, что имя файла должно быть полным, даже если файл находится в каталоге поддержки AutoCAD. После этого можно запустить процедуру TEST_VBD_InsertBlock

Задание значений атрибутов на основании данных из базы данных.

Суть функции в следующем. Она открывает базу данных, заданную именем файла базы данных sDBPath (имеется в виду база данных mdb), затем открывает таблицу sTableName. После этого просматриваются имена полей таблици и, если имя поля совпадает с именем какого-нибудь аттрибута из вставленного блока TitleBlock, то аттрибуту присваивается значение из соответствующего поля таблицы. Если блок имеет аттрибуты, то функция возвращает True, а если нет, то False. Используя процедуру, подобную этой, можно создать универсальную программу для вставки блоков со стандартными деталями, значения размеров которой подставляются из выбранной пользователем записи базы данных.

Экспорт значений аттрибутов блока в текстовые объекты

Приведенная ниже процедура запросит у Вас начальную точку вставки и блок с аттрибутами, после указания которого значения всех аттрибутов (видимых и невидимых) будут вставлены в чертеж как текстовые объекты.

Вставка блока с изменением масштаба отображения аттрибутов

Вставка блоков с аттрибутами это мощьный инструмент значительно облегчающий выполнение многих операций, но и у этого инструмента есть недостатки. Один из них - это невозможность задания разных масштабов собственно для блока и для аттрибутов блока. Действительно, очень часто бывают случаи, когда надо вставить блок с аттрибутами таким образом, чтобы все элементы блока смасштабировались, а высота текста аттрибутов осталась такой, какая она задана для масштаба 1:1. Эта проблема решена в следующем примере. Для его опробывания создадим блок с незапрашиваемым аттрибутом. Создадим мы его из квадрата 50 на 50 и аттрибута с высотой текста 10мм. Содержимое текста текстовое значение аттрибута не важно, лишь бы не пустое. Назовите этот блок "TEST" и запустите процедуру TEST_ExtendedInsert несколько раз, задавая при этом разные масштабы. Видите, размеры прямоугольника зависят от задаваемого масштаба, а высота текста аттрибута во всех случаях 10 мм. Мною замечено, что этот метод не работает для аттрибутов, значение которых не запрашивается при вставке блока, т. е. для констант.

Выравнивание аттрибутов в повернутом блоке

Вставьте в чертеж какой-нибудь блок с аттрибутами под таким углом, чтобы ориентация текста аттрибутов отличалась от горизонтального (вставьте блок, в котором аттрибуты ориентированы горизонтально, а затем поверните его на какой-нибудь угол). После этого добавьте в стандартный модуль VBA приведенный ниже код и запустите процедуру LevelAttributes. На запрос Select a block выберите повернутый блок. Все аттрибуты будут повернуты таким образом, что их ориентация совпадет с той, которая была бы у них при вставке блока с углом поворота 0 градусов.

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

Изменение цвета аттрибутов

Создайте в чертеже блок с аттрибутами, при этом сделайте так, чтобы цвет аттрибутов отличался от желтого. Вставьте в стандартный модуль приведенный ниже код и отредактируйте процедуру TEST_ColorAttributes, заменив имя блока TestBlkName на имя созданного Вами блока. Теперь, если запустить процедуру TEST_ColorAttributes, то цвет аттрибутов в блоке будет изменен на желтый, и если вставить блок после запуска процедуры TEST_ColorAttributes, блок будет "обновленным", с аттрибутами желтого цвета.

Теперь попробуем изменить цвет аттрибутов уже у вставленных блоков. Добавьте в стандартный модуль следующий код и отредактируйте процедуру ColorMeBlue, заменив имя блока TestBlkName на имя созданного Вами блока. Теперь, если запустить процедуру ColorMeBlue, то у всех вставленных блоков с заданным именем цвет аттрибутов будет заменен на синий. К стати, в этом коде есть не плохой пример очень полезной функции, возвращающей набор объектов, состоящий только из аттрибутов, входящих в состав всех вставленных блоков с заданным именем.

Проверка значения аттрибута перед закрытием файла

Если Вы поместите в модуле ThisDrawing текущего чертежа следующий код и создадите в чертеже блок с именем TitleBlock, в котором определите аттрибут с именем Draftsman, затем вставите этот блок в чертеж, то при закрытии этого чертежа произойдет следующее: Функция IsValidName проверит значение аттрибута Draftsman, и, если оно не равно "Code", то будет отображено окно с запросом кодового слова. Этот запрос будет отображаться и файл не будет закрыт до тех пор ,пока пользователь не введет слово "Code". Если же в момент закрытия чертежа значение аттрибута сразу равно "Code", то никаких запросов кодового слова не производится и файл сразу закрывается.

Функции для операций над аттрибутами и текстом

ApplyDate - присваивает значению выбранного текстового объекта (Text, MText или аттрибут блока) текущую дату
MoveAttribute - процедура, перемещающая выбранный аттрибут блока, оставляя блок на месте
ChangeCase - функция для изменения регистра символов любого текстового объекта (Text, MText или аттрибут блока) . Для демонстрации работы функции запустите процедуру TEST_ChangeCase
TransferTextValue - процедура запрашивает 2 любых текстовых объекта (Text, MText или аттрибут блока) , а затем присваивает значение первого выбранного объекта второму. Эта функция не корректно работает с объектами Mtext, содержащими символы Кирилицы
VBDEdit - процедура для редактирования значения любого текстового объекта (Text, MText или аттрибут блока) . Эта функция не корректно работает с объектами Mtext, содержащими символы Кирилицы
ClearAllKeyPress - вспомогательная функция, очищающая буфер клавиатуры

Есть типы блоков: простой блок, блок XRef и лист.

Простой блок - совокупность объектов, которые Вы можете связать вместе, чтобы формировать единственный объект. Вы можете вставить, масштабировать и вращать простой блок в рисунке. Вы можете взорвать простой блок на его составляющие объекты, изменить их, и переопределить определение блока. Простые блоки могут быть определены от геометрии в текущем рисунке или используя другой рисунок AutoCAD. Когда Вы используете другой рисунок, чтобы создать блок, новый простой блок сохраняется в текущем рисунке; он не модифицируется уже есть в рисунке. Вставка простого блока в текущий рисунок создает объект BlockReference.

Блок XRef - внешняя связь из другого рисунка с текущим рисунком. Поскольку блок XRef представляет связь с геометрией, а не геометрию непосредственно, он модифицируется всякий раз, когда оригинал изменится. Вставка блока XRef в текущий рисунок создает объект ExternalReference.

Блоки листа представляют геометрию в пространстве листа и пространстве модели. C этими блоками связан объект Layout, который содержит графические параметры настройки и другую информацию определения листа. Название блока активного пространства листа - всегда *PAPER_SPACE. Другие листы пространства листа будут иметь блоки, названные *PAPER_SPACEn, где n - целое число. Названия блока начинаются с *PAPER_SPACE0 и увеличивается на 1 каждый раз, когда вставлен новый лист.

По умолчанию, блоки листа в новом рисунке имеют следующие названия:

Определение *MODEL_SPACE Лист пространства модели. Есть только один лист пространства модели в рисуноке.

Этот блок соответствует коллекции ModelSpace. *PAPER_SPACE Первый созданный лист пространства листа. Если текущий лист пространства модели активен, этот блок содержит последний активный лист пространства листа.

Этот блок соответствует коллекции PaperSpace. *PAPER_SPACE0 Второй созданный лист пространства листа. Если этот лист активизирован, его блок переименован *PAPER_SPACE и становится доступным из коллекции PaperSpace; блок первого листа переименован *PAPER_SPACE0.

Когда Вы активизируете новый лист, это меняет имя блока листа, который был прежде активен. Этим способом, блок активного листа всегда называют *PAPER_SPACE. Например, предположите, что Layout1 активен и Layout2 связан с блоком, названным *PAPER_SPACE0. Если Вы тогда активизируете Layout2, этот блок будет переименован в *PAPER_SPACE, а блок Layout1 переименован в *PAPER_SPACE0.

Чтобы идентифицировать тип блока, используйте свойства IsXRef и IsLayout. Если оба из этих свойств - FALSE, то блок - простой блок. Если свойство IsXRef - TRUE, то блок - внешняя ссылка. Если свойство IsLayout - TRUE, то блок содержит всю геометрию, связанную с листом.

Нет никакого предела числу объектов, которые блок может содержать.

Чтобы вставлять простой блок или блок XRef в рисунок, используйте метод InsertBlock. Чтобы создавать новый блок листа, используйте метод Add, добавлить новый лист к коллекции Layouts. Когда новый лист создан, будет также создан связанный блок листа.

Чтобы редактировать или сделать запрос любого из блоков, используйте следующие методы и свойства:

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

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