На главную

Библиотека Интернет Индустрии I2R.ru

Rambler's Top100

Малобюджетные сайты...

Продвижение веб-сайта...

Контент и авторское право...

Забобрить эту страницу! Забобрить! Блог Библиотека Сайтостроительства на toodoo
  Поиск:   
Рассылки для занятых...»
I2R » И2Р Программы » Программирование » VBasic, VBS

VBA взрослеет. Cоздание утилиты для AutoCAD 2000 с помощью VBA

С появлением AutoCAD 2000, VBA в AutoCAD достиг совершеннолетия. Новая версия избавилась от многих ограничений начальной реализации VBA в AutoCAD R14, и добавила реальные функциональные возможности непосредственно к AutoCAD.

Чтобы почуствовать, что Вы можете теперь делать с помощью VBA, эта статья, представляет простую утилиту MRU +. Эта утилита, показанная на Рис.1, сохраняет список последних открытых чертежей, показывает Вам те, которые загружены в настоящее время, и позволяет Вам загружать и выгружать чертежы просто устанавливая галочку рядом с названием чертежа. Хотя это простая утилита, но MRU + демонстрирует многие из новых возможнстей VBA в AutoCAD, и должна помочь научить вас владеть средой VBA в AutoCAD

Рис.1 MRU+ - утилита, которая позволяет следить за недавно использоваными файлами AutoCAD

Рис.1 MRU+ - утилита, которая позволяет следить за недавно использоваными файлами AutoCAD

Добро пожаловать в VBA AutoCAD

Как уже было сказано, на примере MRU +, вы сможете увидеть многие из новых возможностей AutoCAD 2000. Эта статья не является обзором этого программного продукта, так что я не буду пытаться описать их всех; акцент ставится на предметах, которые важны разработчикам VBA. Однако, это отображает нескольких из основных усовершенствований в этой версии AutoCAD:
  • Впервые, AutoCAD имеет среду окружения MDI, позволяя Вам, открывать много чертежей в одно время. Каждый чертеж может содержать:
  • Множество закладок, отображающих различные варианты размещения чертежа.
  • Инструментальные средства для загрузки отдельных объектов и частей чертежей были по существу улучшены.
  • Трехмерное вращение в реальном времени, улучшенное твердотельное моделирование, и более гибкие виды, делают работу с трехмерным объектами намного проще.
  • Расширенная объектная модель впервые позволяет программам VBA, манипулировать меню и инструментальными панелями. VBA может также посылать команды непосредственно в командную строку AutoCAD.
  • Модель событий для AutoCAD и его чертежей существенно улучшена.
  • Вы можете открывать и сохранять файлы непосредственно из Интернет.
  • Новые мастера делают печать намного более просто чем это было в предыдущих версиях.
Этот список показывает только несколько из усовершенствований в этой версии. Для полного описания, см. http://www.cad.dp.ua/stats/rev2000.html.

Два типа проектов в VBA

AutoCAD 2000 позволяет хранить VBA, проекты или как часть документа (указывается как внедренный проект), или как отдельный файл (указывается как Глобальный проект). Каждый загруженный рисунок может иметь единственный внедренный проект, или не иметь внедренного проекта вообще. Кроме того, Вы можете иметь любое число глобальных проектов, загруженных в AutoCAD. Чтобы управлять этими двумя типами проектов, AutoCAD включает Диспетчер VBA (в падающем меню - Tools | Macro | VBA Manager). Этот инструмент, показанный на Рис.2, позволяет Вам выполнять следующие операции:
  • Извлекать внедренный проект из загруженного чертежа в глобальный проект
  • Внедрять загруженный глобальный проект в любой открытый чертеж
  • Создавать новый глобальный проект
  • Сохранять глобальный проект под новым названием
  • Загружать глобальный проект с жесткого диска
  • Выгрузить глобальный проект из памяти
  • Посмотреть макросы в любом или всех загруженных проектах
  • Запустить Редактор Visual Basic
Рис.2. Диалоговое окно VBA Manager позволяет Вам манипулировать внедренными и глобальными проектами VBA

Рис.2. Диалоговое окно VBA Manager позволяет Вам манипулировать внедренными и глобальными проектами VBA

Конечно, глобальный проект более предпочтителен для утилиты, разработанной, чтобы фиксировать информацию относительно множества чертежей. В случае MRU +, глобальный проект это фалй MRUPlus.dvb. Расширение "dvb" используется AutoCAD для глобальных проектов, сохраненных на диске.

Загрузка при запуске

AutoCAD 2000 автоматически не инициализирует VBA всякий раз, когда Вы его запускаете. Скорее, VBA загружается по требованию. Однако, имеются два способа когда Вы можете загружать и запускать код VBA при запуске. Во первых, Вы можете создавать глобальный проект VBA, с названием acad.dvb, и сохранять его в вашем каталоге AutoCAD. Любой проект с этим названием будет автоматически загружен при запуске AutoCAD. Далее, если это содержит макроc ( процедуру Sub ) с названием AcadStartup, эта макрокоманда будет автоматически выполняться, как только файл acad.dvb загружен.

Как вариант, Вы можете расположить команды AutoLisp в файле acad.lsp, который также должен быть в каталоге AutoCAD. Любая функция AutoLisp названая STARTUP в этом файле будет автоматически выполняться, когда файл загружен. Как вы будете видеть в этой статье, Autodesk сделала хорошую работу по созданию связи между старшим языком Lisp и более новым языком VBA, что бы стало возможно для кода Lisp, вызвать код VBA и наоборот.

Для приложения, хорошая мысль, модифицировать файл acad.lsp, чтобы загружать приложение при запуске. Большинство пользователей AutoCAD знакомы с изменением этого файла и с языком Autolisp, так что добавление строки кода, чтобы загрузить ваше приложение должно быть для них просто. Вы можете просто загружать приложение, или можете загружать приложение и запускать макрос из него в то же самое время.

Чтобы загрузить приложение, Вы можете использовать код Autolisp, чтобы вызвать команду AutoCAD vbaload:

(defun S::STARTUP()
   (command "_vbaload" "myproject.dvb")
)

Или, чтобы запустить процесс инициализации в приложении, Вы можете вызывать команду vbarun:

(defun S::STARTUP()
               (command "_-vbarun" "MRUPlus.dvb!basMRUPlus.LoadMRUPlus")
                  )

Аргумент команды vbarun может быть полностью квалифицирован в форме:

FileName!ModuleName.MacroName

Если указанный файл не загружен, он будет сначала загружен, и затем будет выполнен макрос. По умолчанию, команды vbarun или vbaload загружают файлы только из главного каталога AutoCAD. Если ваша утилита сохранена в другом месте, вы будете должны указать полный путь и имя файла в аргументе. В этом случае, Вы нуждаетесь в "escape" из знаков наклонной черты влево, удваивая их. Например, это имело силу бы в файле acad.lsp:

(defun S::STARTUP()
               (command "_vbaload" "c:\\Utilities\\myproject.dvb")
                  ) 

Управление Меню

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

Рис.3 показывает новый объекты AutoCAD, доступные для манипулирования инструментальной панелью и меню. Объект MenuBar контролирует все меню, в настоящее время отображенные в главной строке меню AutoCAD. Вы можете вставилять и удалять меню, вызывая методы InsertInMenuBar и RemoveFromMenuBar объекта PopupMenu.

Рис.3. Объекты для манипуляции меню и панелями инструментов

Рис.3. Объекты для манипуляции меню и панелями инструментов

Объект PopupMenu представляет стандартное падающее меню, или меню вызываемое по правой кнопке мыши. Объект PopupMenuItem представляет единственный пункт меню.

Система MenuGroups содержит набор объектов MenuGroup. Каждый MenuGroup может содержать меню и панели инструментов. Вы можете загружать группы меню из файла на диске. После того, как вы загрузили группу меню, ее содержание станет доступным, чтобы загрузиться в MenuBar или сокращенные меню.

Система Toolbars содержит объекты Toolbar, каждый из которых представляет панель инструментов. Индивидуальные кнопки панели представлены объектами ToolbarItem.

Утилита MRU + делает самую простую возможную операцию с этими объектами: Она прибавляет пункт меню, который отображает интерфейс пользователя к файловому меню. Это делается одной строкой кода:

Application.MenuBar(0).AddMenuItem 19, "MRU+", _
                    "_-vbarun ShowMRUPlus "

Этот код добавляет новый пункт к 20-й позиции (считая с нуля) системы PopupMenuItems на крайнем левом PopupMenu в установленному по умолчанию MenuBar (другими словами, к меню File). Второй аргумент - текст, который будет отображаться в меню, и третий аргумент - макрос меню AutoCAD, который вызывается, когда этот пункт меню выбран.

Использование макросов меню AutoCAD имеет почти тот же самый синтаксис как команды AutoCAD, но и имеет некоторые различия. Один из них - вызов команды vbarun, используя синтаксис подчеркивания и черты чтобы подавить показ диалогового окна, которое это обычно вызвало бы. Заметьте присутствие пробела после имени макроса VBA, для выполнения. В макросах меню, конечные пробелы интерпретируется как конец фрагмента входа. Без этого, название макрокоманды VBA было бы внесено в командную строку AutoCAD, но не выполненно.

Использование ThisDrawing

Хотя можно иметь несколько одновременно загруженных глобальных проектов VBA, они все используют единственный объект названный ThisDrawing. Этот объект представляет собой активный документ в интерфейсе пользователя AutoCAD, и имеет класс AcadDocument. (В отличие от многих других объектных моделей, в модели AutoCAD имена всех объектов начинаються с префикса "Acad", чтобы гарантировать однозначность в операциях). Если несколько проектов VBA включают обработчики для событий для объекта ThisDrawing, каждый из обработчиков событий вызывается по очереди.

Использование событий ThisDrawing просто. Каждый глобальный проект VBA, который Вы создаете автоматически, содержит пример объекта ThisDrawing который не может быть удален. В приложении MRU + событие ThisDrawing.BeginClose используется, чтобы сообщить главной форме, когда рисунок выгружается из пользовательского интерфейса. Это событие содержит минимум кода, чтобы вызвать метод public формы интерфейса пользователя, чтобы расположить соответствующий ListItem в ListView и не контролировать это.

Таблица ниже содержит списки событий, поддерживаемые ThisDrawing. Как Вы можете видеть, многие из этих событий - новые в AutoCAD. В частности события BeginShortcutMenu, BeginLisp, и Object позволяют осуществлять новые способы взаимодействия с другими языками программирования в AutoCAD.

События объекта AcadDocument

Имя события Новое Исполняется когда:
Activate Да Окно чертежа выбирается
BeginClose Да Пользователь или программа пытается закрыть чертеж
BeginCommand Да Запущена команда
BeginDoubleClick Да Пользователь осуществляет двойной щелчек мышью на любом объекте чертежа
BeginLisp Нет Lisp-выражение посылается на исполнение
BeginPlot Да Начинается операция печати
BeginRightClick Да Пользователей нажимает правую кнопку мыши на любом объекте в черетеже
BeginSave Да Пользователь начинает сохранять чертеж
BeginShortcutMenuCommand Да Пользователь выдает сокращенного меню коммандного режима
BeginShortcutMenuDefault Да Пользователь выдает сокращенное меню по умолчанию
BeginShortcutMenuEdit Да Пользователь выдает сокращенное меню EDIT
BeginShortcutMenuGrip Да Пользователь выдает сокращенное меню GRIP
BeginShortcutMenuOsnap Да Пользователь выдает сокращенное меню OSNAP
Deactivate Да Окно чертежа становиться не активным
EndCommand Нет Завершается выполнение команды
EndLisp Да Завершается вычисление Lisp-выражения
EndPlot Да Завершается операция печати
EndSave Да Завершается операция записи
EndShortcutMenu Да Любое сокращенное меню фактически появляется.
LayoutSwitched Да Пользователь переключатеся на другой layout
LispCancelled Да Выполнение lisp-выражения прервано
ObjectAdded Да Любой объект добавлен к чертежу
ObjectErased Да Любой объект удален из чертежа
ObjectModified Да Любой объект модифицирован
SelectionChanged Да Текущий набор выбора изменен
WindowChanged Да Окно максимизируется или минимизируется
WindowMovedOrResized Да Окно перемещается или изменяется его размер

Зацепление объекта Application

Помимо наличия ThisDrawing, который представляет активный документ, утилита MRU + также должна контролировать события объекта AcadApplication (представляющего непосредственно AutoCAD) чтобы знать, когда новый рисунок был открыт. В отличие от объекта ThisDrawing, однако, глобальные VBA объекты не получают автоматически образец объекта AcadApplication. К счастью, Вы можете использовать в VBA ключевое слово WithEvents, чтобы создать ваш собственный. Последовательность событий, что использует MRU+, чтобы зацепить cобытие EndOpen объекта AcadApplication, который испольняется всякий раз, когда открывается новый рисунок, выделенный в следующих абзацах.

Файл acad.lsp, как Вы уже видели, содержит код вызова процедуры LoadMRUPlus в basMRUPlus. Наряду с другим загрузочным кодом, эта процедура устанавливает образец частного класса называемого CApp и устанавливает одно из его свойств:

' Private class used to grab the application events. 
                  Private mApp As CApp
                    
                  Public Sub LoadMRUPlus()
                    ...
                     ' Get our event hook into the Application. 
                     Set mApp = New CApp
                     Set mApp.App = ThisDrawing.Application

Класс CApp существует исключительно как оболочка для объекта AcadApplication. Встроенный объект ThisDrawing содержит свойство Application что указывает на единственный образец объекта AcadApplication, что позволяет просто коду запуска находить это. Ниже показан код для класса CApp. Важным является здесь - то, что частная переменная типа AcadApplication объявлена WithEvents. Это специальное ключевое слово делает события AcadApplication доступными для кодирования в модули класса. Распечатка кода для утилиты MRU + в конце статьи.

Option Explicit
                    
                  ' This object will let us intercept events
                  ' for the Application object. 
                  Private WithEvents mApp As AcadApplication
                    
                  Private Sub mapp_EndOpen(ByVal FileName As String)
                     ' When a drawing is opened, add it to our MRU list. 
                    frmMRUPlus.AddFile FileName, Now, True
                  End Sub
                    
                  Public Property Set App(NewApp As AcadApplication)
                     ' This property must be set to hook things up. 
                     Set mApp = NewApp
                  End Property
                  FIGURE 5: The CApp class module.

События объекта AcadApplication полностью новые в AutoCAD 2000. В таблице ниже показан список новыех событий предмета AcadApplication.

События объекта AcadApplication

Имя события Когда исполняется
AppActivate AutoCAD получает фокус
AppDeactivate AutoCAD теряет фокус
ARXLoaded приложение ObjectARX загружается
ARXUnloaded приложение ObjectARX выгружается
BeginCommand Команда запущена из командной строки AutoCAD
BeginFileDrop Файл положен на рабочее пространство AutoCAD
BeginLisp Вычисляется Lisp-выражение
BeginModal Модальное диалоговое окно собирается отобразиться.
BeginOpen Чертеж собирается открыться
BeginPlot Чертеж отправляется на печать
BeginQuit Сессия AutoCAD собирается завершиться
BeginSave Документ отправле на сохранение
EndCommand Команда завершает исполнение
EndLisp Lisp-выражение вычислено
EndModal Модальный диалог отклонен.
EndOpen Чертеж открыт
EndPlot Чертеж напечатан
EndSave Чертеж сохранен
LispCancelled Вычисление Lisp-выражения прервано
NewDrawing Создан новый чертеж
SysVarChanged Изменено значение системной переменной
WindowChanged Окно минимизировано или максимизировано
WindowMovedOrResized Окно перемещено или изменен его размер

Заключение

С AutoCAD 2000, VBA в AutoCAD перестал быть являющийся интересным "доказательство концепции", и стал довольно полезным средством. Добавление структурированной объектной модели, способность загружать несколько VBA-проектов и выполнять код при загрузке, а так же интегрирование с Lisp, командной строкой, меню, и панелями инструментов - все это делает возможным писать полезные утилиты, объединенные со стандартным интерфейсом AutoCAD.

Хотя MRU + утилита, показанная здесь только как доказательство концепции, она демонстрирует все схемы, которые вы были бы должны делать с любой утилитой для AutoCAD. Autodesk вложил много усилия в создании VBA как первоклассной средой окружения для AutoCAD.

Код MRU+

                 
' *********************************************************
Option Explicit

Private Sub AcadDocument_BeginClose()
	' Whenever the user closes a drawing, uncheck
	' its name on the MRU form. 
	frmMRUPlus.UnCheck ThisDrawing.FullName
End Sub
                    
' *********************************************************
' Code attached to frmMRUPlus.
' *********************************************************
Option Explicit
  
' Arbitrary counter for generating unique
' keys for ListItems. 
Private mintDoc As Integer
  
Public Property Let Entries(NewEntries As Integer)
   	' Set the maximum number of entries to display. 
  	txtEntries.Text = NewEntries
  	sbEntries.Value = NewEntries
End Property
  
Public Sub AddFile(strFileName As String, _
  dblTime As Double, fChecked As Boolean)
  
   ' Add a file to the MRU list. Specifies the file name, 
  	' time, and whether it should be checked. If there are
  	' more than the specified number of entries on the list, 
  	' drops the oldest entry. 
   	Dim li As ListItem
   	Dim intI As Integer
  
   ' Check for a few common errors and fix 'em up. 
   If Len(strFileName) = 0 Then
     Exit Sub
   End If
   If Val(txtEntries.Text) < 1 Then
    txtEntries.Text = 10
   End If
  
   ' Look for an existing item with this name. 
   For intI = 1 To lvwMRU.ListItems.Count
     If lvwMRU.ListItems(intI).Text = strFileName Then
       Set li = lvwMRU.ListItems(intI)
       Exit For
     End If
   Next intI
  
   ' If there is no such item, we need to add one. 
   If li Is Nothing Then
     ' Check first to see whether we need to drop an item. 
     If lvwMRU.ListItems.Count >= txtEntries.Text Then
       Set li = lvwMRU.ListItems(1)
         ' Find the oldest item to drop. 
         For intI = 2 To lvwMRU.ListItems.Count
           If CDate(lvwMRU.ListItems(intI).SubItems(1)) < _
              CDate(li.SubItems(1)) Then
             Set li = lvwMRU.ListItems(intI)
             End If
           Next intI
          lvwMRU.ListItems.Remove li.Index
     End If
     ' Add the new item with an arbitrary key. 
     Set li = lvwMRU.ListItems.Add(, "K" & mintDoc, _
                 strFileName)
    li.SubItems(1) = CDate(dblTime)
    mintDoc = mintDoc + 1
   End If
   ' Whether the item was new or existed already, check it
   ' if it wasn't checked and should be checked. 
   If Not li.Checked Then
    li.Checked = fChecked
   End If
End Sub
  
Public Sub UnCheck(strFileName As String)
   ' Clears the checkmark next to an item. 
   Dim intI As Integer
   Dim li As ListItem
  
   ' Find the item to clear by comparing names. 
   For intI = 1 To lvwMRU.ListItems.Count
     If lvwMRU.ListItems(intI).Text = strFileName Then
       Set li = lvwMRU.ListItems(intI)
       Exit For
     End If
   Next intI
  
   ' And if we found it, uncheck it. 
   If Not li Is Nothing Then
    li.Checked = False
   End If
End Sub
  
Private Sub cmdClose_Click()
   ' This form stays resident, just hide it. 
  Me.Hide
End Sub
  
Private Sub lvwMRU_ItemCheck( _
   ByVal Item As MSComctlLib.ListItem)
   ' When the user checks or unchecks an item, load or
   ' unload the corresponding drawing. 
   Dim doc As AcadDocument
  
   If Not Item Is Nothing Then
     If Item.Checked Then
       ' Opening is a method of the Documents collection. 
      Application.Documents.Open Item.Text
     Else
       ' Closing is a method of the document. 
       For Each doc In Application.Documents
         If doc.FullName = Item.Text Then
          doc.Close
           Exit For
         End If
       Next doc
     End If
   End If
End Sub
  
Private Sub sbEntries_Change()
   ' Tie together the textbox and the spin button. 
  txtEntries.Text = sbEntries.Value
End Sub
  
Private Sub txtEntries_Change()
   ' Tie together the textbox and the spin button. 
  sbEntries.Value = txtEntries.Text
End Sub
  
Private Sub UserForm_Terminate()
   ' Write changes in settings to the registry. 
   Dim li As ListItem
   Dim intI As Integer
  
  SaveSetting "MRUPlus", "Options", "Entries", _
              txtEntries.Text
   For intI = 1 To lvwMRU.ListItems.Count
     Set li = lvwMRU.ListItems(intI)
    SaveSetting "MRUPlus", "Files", _
                "FileName" & intI, li.Text
    SaveSetting "MRUPlus", "Files", _
                 "FileTime" & intI, li.SubItems(1)
   Next intI
  
End Sub
  
' *********************************************************
' Code attached to basMRUPlus.
' *********************************************************
Option Explicit
  
' Private class used to grab the application events. 
Private mApp As CApp
  
Public Sub LoadMRUPlus()
   ' Startup code, meant to be called from acad.lsp. 
   Dim doc As AcadDocument
   Dim intI As Integer
   Dim intEntries As Integer
   Dim strName As String
  
   ' Get our event hook into the Application. 
   Set mApp = New CApp
   Set mApp.App = ThisDrawing.Application
  
   ' Add our menu item, ignoring error if it already exists. 
   On Error Resume Next
  
  Application.MenuBar(0).AddMenuItem 19, "MRU+", _
    "_-vbarun ShowMRUPlus "
   On Error GoTo 0
  
   ' Load the form. 
  Load frmMRUPlus
   ' Load any open drawings. 
   For Each doc In Application.Documents
    frmMRUPlus.AddFile doc.FullName, Now, True
   Next doc
  
   ' And load any names we saved in the registry from a
   ' previous session. 
   On Error Resume Next
  
  intEntries = GetSetting("MRUPlus", "Options", _
        "Entries", "10")
   If Err.Number <> 0 Then
    intEntries = 10
   End If
   On Error GoTo 0
  frmMRUPlus.Entries = intEntries
   For intI = 1 To intEntries
    strName = GetSetting("MRUPlus", "Files", _
       "FileName" & intI)
     If Len(strName) > 0 Then
      frmMRUPlus.AddFile strName, CDate(GetSetting( _
        "MRUPlus", "Files", "FileTime" & intI)), False
     End If
   Next intI
End Sub
  
Public Sub ShowMRUPlus()
   ' Make the form visible. 
  frmMRUPlus.show
End SubCApp
  
Option Explicit
  
' This object will let us intercept events
' for the Application object. 
Private WithEvents mApp As AcadApplication
  
Private Sub mapp_EndOpen(ByVal FileName As String)
   ' When a drawing is opened, add it to our MRU list. 
  frmMRUPlus.AddFile FileName, Now, True
End Sub
  
Public Property Set App(NewApp As AcadApplication)
   ' This property must be set to hook things up. 
   Set mApp = NewApp
End Property

Mike Gunderloy, перевод Виктор Ткаченко
OfficeVBA

Другие разделы
C, C++
Java
PHP
VBasic, VBS
Delphi и Pascal
Новое в разделе
Базы данных
Общие вопросы
Теория программирования и алгоритмы
JavaScript и DHTML
Perl
Python
Active Server Pages
Программирование под Windows
I2R-Журналы
I2R Business
I2R Web Creation
I2R Computer
рассылки библиотеки +
И2Р Программы
Всё о Windows
Программирование
Софт
Мир Linux
Галерея Попова
Каталог I2R
Партнеры
Amicus Studio
NunDesign
Горящие путевки, идеи путешествийMegaTIS.Ru

2000-2008 г.   
Все авторские права соблюдены.
Rambler's Top100