Автоматизация рутинных операций между Excel и AutoCAD при помощи VBA

от автора

Уже не первый год я встречаю на профильных форумах мнение, что VBA для AutoCAD отмирает, и AutoDesk не будет его включать в следующих релизах в дистрибутив, и вообще, истинные падаваны пользуются lisp, C# и прочим, но только не VBA.

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

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

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

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

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

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

Sub DrawMLeader() 'рисуем выноску      Dim acadApp As AcadApplication     Dim acadDoc As AcadDocument      Application.DisplayAlerts = False 'чтобы отключить ненужные сообщения            'Проверяем открыт Автокад или нет      On Error Resume Next     Set acadApp = GetObject(, "AutoCAD.Application")     On Error GoTo 0          'Если Автокад не открыт, создаем новый экземпляр и делаем его видимым     If acadApp Is Nothing Then         Set acadApp = New AcadApplication         acadApp.Visible = True     End If          'Проверяем активный документ     On Error Resume Next     Set acadDoc = acadApp.ActiveDocument     On Error GoTo 0          'Если активных нет - создаем новый документ     If acadDoc Is Nothing Then         Set acadDoc = acadApp.Documents.Add         acadApp.Visible = True     End If     Dim AML As AcadMLeader Dim xx As Long Dim ss As String  ActiveCell.Cells.Activate 'активируем ячейку в экселе ss = ActiveCell.Cells.Value 'заносим данные из ячейки в переменную  Dim points(0 To 5) As Double 'массив точек для вставки выноски   Dim startPnt As Variant, endPnt As Variant   Dim prompt1 As String, prompt2 As String   prompt1 = vbCrLf & "Начало выноски: "   prompt2 = vbCrLf & "Конец выноски: "   startPnt = acadDoc.Utility.GetPoint(, prompt1) 'запрашиваем у пользователя первую точку выноски   endPnt = acadDoc.Utility.GetPoint(startPnt, prompt2) 'запрашиваем у пользователя вторую точку выноски  'заполняем массив точек для MLeader     points(0) = startPnt(0)     points(1) = startPnt(1)     points(2) = 0        points(3) = endPnt(0)     points(4) = endPnt(1)     points(5) = 0  Set AML = acadDoc.ModelSpace.AddMLeader(points, xx) 'вставляем примитив в автокад и заполняем ниже его свойства AML.TextString = ss AML.ArrowheadType = acArrowNone 'если нужна другая высота текста - эту позицию меняем тут, или в настройках Mleader в AutoCAD AML.TextHeight = 250 AML.TextLeftAttachmentType = acAttachmentBottomOfTopLine AML.TextRightAttachmentType = acAttachmentBottomOfTopLine AML.LandingGap = 2  Dim entHandle As String  entHandle = AML.Handle 'получаем хэндл выноски, чтобы вставить его в соседнюю ячейку, чтобы в дальнейшем можно было обновить данные в выноске прямо из эксель  ActiveCell.Offset(0, 1).Value = entHandle     acadDoc.Application.Update 'меняю цвет ячейки, откуда получил текст, чтобы было понятно, что текст обработан.  ActiveCell.Cells.Interior.ColorIndex = 6 End Sub 

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

Dim blockObj As Object 'обозвали блок  'вставили блок, маркер воздухообмена - это имя вашего блока, который должен быть уже в чертеже: 'можно сделать так, чтобы блок вставлялся автоматически из чертежа-донора, но я на это уже не заморачивался  Set blockObj = acadDoc.ModelSpace.InsertBlock(startPnt, "Маркер воздухообмена", 1, 1, 1, 0, [])  'заполняем атрибуты, можно сделать по-умнее, но мне лень было разбираться, я сделал по рабоче-крестьянски (работает и ладно)  Dim varAttributes As Variant     varAttributes = blockObj.GetAttributes     varAttributes(0).TextString = ss1 'приток     varAttributes(1).TextString = ss2 'вытяжка     varAttributes(2).TextString = ss 'описание помещения      Dim entHandle As String 'тут я получаю хэндл нашего блока и пишу его в соседнюю ячейку, для того, чтобы можно было при изменении текста в Excel обновить просто блок в AutoCAD.  entHandle = blockObj.Handle ActiveCell.Offset(0, 3).Value = entHandle 

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

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

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

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

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

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

ссылка на оригинал статьи http://habrahabr.ru/post/261461/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *