
2 семестр / vba_2002
.pdfРаспространение надстройки
Эту надстройку можно распространять среди других пользователей Excel, передавая им копию файла XLA (версия XLS им не понадобится). Также пользователям необходимо передать инструкции по установке надстройки. Если используется Office XP Developer Edition, то можно обратиться к специальному мастеру для создания файла S e t u p . e x e , который упростит установку надстроек конечными пользователями. После установки надстройки в меню Сервис будет содержаться новая команда Text Tools (Текстовые инструменты). Если файл защищен паролем, то код макроса не смогут просмотреть и модифицировать посторонкне пользователи. Исключение составляют те пользователи, которым известен пароль.
Изменение надстройки
Если в надстройку необходимо внести изменения, то ее вначале следует открыть, а после этого разблокировать. Для того чтобы разблокировать надстройку, активизируйте редактор VBE и дважды щелкните на имени проекта в окне Project. После этого на экране появится запрос на введение пароля. Внесите необходимые изменения и сохраните файл, не покидая редактор VBE (для этого выберите команду File^Save (ФайлОСохранить)).
Если создается надстройка, которая хранит данные на рабочем листе, потребуется установить свойство i s A d d l n рабочей книги в значение F a l s e . Это необходимо сделать перед просмотром рабочей книги в Excel. Свойство изменяется в диалоговом окне Properties при выделенном объекте ThisWorkbook.. После внесения изменений удостоверьтесь, что свойство I s A d d l n опять установлено в положение True. Если перед сохранением файла оставить это свойство установленным в значение F a l s e , то файл будет сохранен как обычная рабочая книга (хотя он имеет расширение . x l a ) . На данном этапе попытка использовать фийл в качестве надстройки с помощью диалогового окна Надстройки приведет к отображению сообщения об ошибке.
Список действий, необходимых для создания надстройки
Перед распространением надстройки осуществите проверку соответствия произведенных действий следующему списку.
Проверена ли надстройка на всех поддерживаемых платформах и версиях Excel? Присвоено ли проекту VBA новое имя? По умолчанию каждый проект называется VBAProject. Рекомендуется присваивать проекту описательное имя.
Анализирует ли надстройка структуру и названия папок компьютера?
Корректно ли отображается имя надстройки и ее описание при использовании диалогового окна Надстройки?
Если надстройка содержит функции VBA, которые не предназначены для использования в рабочей книге, были ли функции объявлены с областью действия Private? Если это не так, то такие функции будут отображены в диалоговом окне Мастер функций. Выполнялась ли принудительная повторная компиляция надстройки, позволяющая удостовериться в отсутствии синтаксических ошибок?
Учитывались ли вопросы межнационального использования? Например, если надстройка создает новый элемент меню Сервис, то процедура может завершиться сообщением об ошибке, если меню Сервис имеет не английское имя.
Оптимизирована ли надстройка на максимальное быстродействие? Дополнительная информация по этой теме приводится в разделе "Оптимизация производительности надстроек".
ЧастьV.Совершенныеметодыпрограммирования |
549 |
Сравнение файлов XLA и XLS
Итак, сравним файл надстройки XLA с исходным файлом XLS и рассмотрим методы оптимизации производительности надстройки. Речь пойдет о способах уменьшения размеров файлов, что позволит сократить время загрузки и уменьшить объем используемого дискового пространства и оперативной памяти.
Структура и размер файлов
Надстройка, основанная на файле XLS, имеет такой же размер, как и исходный файл рабочей книги. Код VBA файла XLA не сжимается и не оптимизируется, поэтому увеличение быстродействия не относится к достоинствам надстроек.
Членство в коллекциях
Надстройка является членом коллекции Addlns, но не выступает "официальным" членом коллекции Workbooks. К надстройке можно обращаться как к элементу коллекции Workbooks, указав в качестве индекса имя файла, в котором хранится надстройка. Следующий оператор создает объект, который представляет надстройку Myaddin . x l a :
Set TestAddin = Workbook{"Myaddin.xla")
На надстройки не допускается ссылаться с помощью числового индекса коллекции Workbooks. Если применить приведенный далее код для просмотра членов коллекции Workbooks, то надстройка Myaddin . x l a отображена не будет:
For Each w in Application . Workbooks MsgBox w.Name
Next w
С другой стороны, следующий цикл For Next позволяет отобразить надстройку Myaddin. x l a (если, конечно, Excel "знает11 о ней) в диалоговом окне Надстройки:
For Each a in Application.Addlns MsgBox a.Name
Next a
Окна
Обычные рабочие книги XLS отображаются в одном или нескольких окнах. Например, представленный далее оператор отображает количество окон активной рабочей книги:
MsgBox ActiveWorkbook.Windows.Count
Состоянием отображения каждого окна рабочей книги XLS можно управлять с помощью команды Окно^Скрыть или посредством значений свойства V i s i b l e . Следующий код скрывает все окна активной рабочей книги:
For Each Win In ActiveWorkbook.Windows
Win.Visible = False Next Win
Файлы надстроек никогда не отображаются и официально не имеют окон, хотя содержат рабочие листы (скрытые). Следовательно, в списке открытых окон меню Окно надстройки не представлены. Если надсфойка Myaddin. x l a открыта, то следующий оператор возвратит значение 0:
MsgBox Workbooks{"Myaddin.xla").Windows.Count
550 |
Глава 21. Создание и использование надстроек |

Листы
Файлы надстроек XLS, как и файлы XLS, могут содержать любое количество рабочих листов или листов диаграмм. Но, как было отмечено ранее в этой главе, файл XLS должен иметь как минимум один рабочий лист, чтобы можно было преобразовать этот файл в надстройку.
После открытия надстройки код VBA будет получать доступ к листам, содержащимся в надстройке, как к обычной рабочей книге. По причине того, что файлы надстроек не являются частью коллекции Workbooks, на надстройку необходимо ссылаться по имени, а не по индексному номеру. Следующий пример демонстрирует, как извлекать значения ячейки Al на первом рабочем листе надстройки Myaddin. x l a , открытой в момент выполнения этого кода.
MsgBox Workbooks("Myaddin.xla").Worksheets{1) _
.Range("Al"}.Value
Если надстройка содержит рабочий лист, который должен отображаться, то можно скопировать этот лист в открытую рабочую книгу или создать новую рабочую книгу на основе этого листа.
Например, представленный ниже код копирует первый рабочий лист надстройки и размещает его в активной рабочей книге (в качестве последнего листа рабочей книги).
Sub CopySheetFromAddin()
Sec AddinSheet = Workbooks("Myaddin.xla").Sheets(1) NuraSheets = ActiveWorkbook.Sheets.Count AddinSheet.Copy After:=ActiveWorkbook.Sheets(NumSheets)
End Sub
Создание рабочей книги на основе листа из надстройки осуществляется еще проще.
Sub CopySheetFromAddin()
Workbooks ("Myaddin.xla11) . Sheets (1) .Copy
End Sub
Предыдущий пример предполагает, что код находится в файле, отличном от файла надстройки. Код VBA в файле надстройки всегда может использовать объект Th:.s- workbook, чтобы задать ссылки на листы или диапазоны надстройки. Например, следующий оператор должен находиться в модуле кода VBA надстройки. Этот сператор отображает значение ячейки Al первого листа надстройки:
MsgBox ThisWorkbook.Sheets 1"Лист!"),Range("Al") .Value
Получение доступа к процедурам VBA надстройки
Доступ к процедурам VBA, которые сохраняются в надстройке, несколько отличается от доступа к процедурам файла обычной рабочей книги XLS. Если выполнить команду Сервиса Макрос, то диалоговое окно Макрос не будет содержать макросы, которые сохранены в открытой надстройке. Это вызвано попыткой Excel ограничить доступ к таким процедурам.
Если имя процедуры известно, то его можно ввести непосредственно в диалоговом окне Макрос и щелкнуть на кнопке Выполнить — процедура будет запущена. Процедура sub должна находиться в модуле кода общего назначения, а не в модулях кода конкретных объектов.
По причине того, что процедуры надстройки не отображаются в диалоговом окне Макрос, необходимо обеспечить другие способы обращения к этим процедурам. В число возможных вариантов решения проблемы входит использование стандартных методов: назначение комбинаций клавиш, опций меню и кнопок пользовательских панелей инструментов: а также косвенных методов1, создание процедур обработки событийОдним из главных выступает метод OnTime, который выполняет процедуру в определенное время суток.
ЧастьV.Совершенныеметодыпрограммирования |
551 |

Можно также воспользоваться методом Run объекта A p p l i c a t i o n для выполнения процедуры, содержащейся в надстройке. Например:
Application.Run "Myaddin.xlaIDisplayNames"
Еше одним вариантом можно считать использование команды Tools^>References редактора VBE, которая позволяет создать ссылку на надстройку. В итоге вы непосредственно ссылаетесь на одну ко процедур в коде VBA, не указывая имени файла. На самом деле необходимости в использовании метода Run не существует: процедуру можно вызывать непосредственно, пока она не объявлена с ключевым словом P r i v a t e , Представленный далее оператор выполняет процедуру DisplayNaines, которая содержится в надстройке, указанной с помощью команды Tools^References:
Call DisplayNames
Даже после создания ссылки на надстройку имена процедур не отображаются в диалоговом окне Макрос.
Поиск в защищенной надстройке
Диалоговое окно Макрос не отображает имена процедур, которые содержатся в надстройках. Однако порой требуется запустить подобную процедуру, когда надстройка защищена, что не позволяет обратиться к исходному коду для определения имени процедуры. Для решения подобной проблемы воспользуйтесь окном Object Browser.
Чтобыпродемонстрироватьэтотспособ,применимкомандуСервис^Надстройкидляустановки надстройки Мастер подстановок. Эта надстройка распространяется вместе с Excel, Она защищена от просмотра, что не позволяет просматривать исходный код ее макросов.
1.Активизируйте редактор VBE и выберите проект Lookup. xla в окне Project.
2.Нажмите клавишу <F2> для активизации окна Object Browser.
3.В выпадающем списке Libraries (Библиотеки) выберите lookup. Это приведет к отображениювсехклассовнадстройкиМастерподстановок.
4.Выберите различные элементы в списк(5 Classes (Классы), чтобы ознакомиться с классами и их элементами.
552 |
Глава 21. Создание и использование надстроек |

В простом примере, который приведен выше, класс Lookup_common является модулем и содержит целый ряд переменных, констант, процедур и функций. Одна из этих процедур DoLookupCommand выглядит как процедура, которая используется для запуска мастера. Для того чтобы проверить изложенную теорию, активизируйте Excel и выберите команду Сервис^Макрос^Макросы. Введите DoLookupCommand в поле Имя макроса и щелкните на кнопке Выполнить. Как и ожидалось, будет отображено первое диалоговое окно мастера подстановок.
После получения этой информации можно приступить к созданию кода VBA, который будет запускать мастер подстановок.
Функции определяются в надстройке подобно тому, как это осуществляется в рабочей книге XLS. К ним легко обращаться, поскольку Excel отображает имена функций в диалоговом окне Мастер функций (в категории Определенные пользователем). Единственным исключением являются функции, объявленные как Private . После такого объявления функция не будет отображаться в диалоговом окне Мастер функций. Именно поэтому объявление пользовательских функций с областью действия Privat e всегда оправдано, когда их необходимо использовать только в процедурах, но не в формулах рабочих листов.
Если необходимо просмотреть надстройку, которая не объявляет свои фун^ии как Private, установите надстройку Мастер подстановок. После этого щелкните на кнопке Вставка функции. В разделе Определенные пользователем будет отображен список, который состоит из более чем десяти функций, не предназначенных для использования на рабочих листах. Эти функции не могут быть вставлены в формулы, находящиеся на рабочих листах.
Как отмечалось ранее, можно использовать функции рабочих листов, которые находятся в надстройке, не указывая имени рабочей книги. Например, если в файле Newfuncs . x l s хранится функция MOVAVG, то необходимо использовать следующий оператор для обращения к функции из другой рабочей книги:
=Newfuncs.xls!MOVAVG(Al:A50)
Однако функция зачастую хранится в открытом файле надстройки. Тогда опустите ссылку на файл и используйте более простой синтаксис:
=MOVAVG(A1:A50)
Управление надстройками с помощью кода VBA
В этом разделе предоставляется информация, которая поможет создавать процедуры VBA, используемые для управления надстройками.
КоллекцияAddlns
Коллекция Addlns состоит из объектов всех надстроек, о которых знает Excel. В нее входят как установленные, так и не установленные надстройки. Команда Сервисенадстройки отображает диалоговое окно Нэдстройки, в котором перечислены вес члены коллекции Addlns . Возле названий надстроек расположены флажки, которые выставлены для установленных надстроек.
Часть V. Совершенные методы программирования |
553 |

Добавление элемента в коллекцию Addlns
Файлы надстроек, составляющие коллекцию Addlns, могут находиться в любой папке. Excel сохраняет неполный список файлов и папок, в которых они находятся, в системном реестре Windows. Excel 2002 хранит эту информацию но следующему пути:
HKEY_CURRENT_USER\Software\Microsoft\Office\10.0\Excel\Add-in Manager
Можно воспользоваться редактором реестра Windows (regedit.exe) для просмотра соответствующих параметров реестра. Обратите внимание на то, что "стандартные" надстройки, которые поставляются вместе с Excel, не указаны в этой записи реестра. Кроме того, файлы надстроек, которые хранятся в" указанной ниже папке, тоже будут добавлены в список (хотя и не будут указаны в системном реестре).
Windows\Application data\Microsoft\Addins
Вы можете добавить новый объект Addln в коллекцию Addlns как вручную, так и программно с помощью VBA. Для того чтобы вручную добавить новую надстройку в коллекцию, выберите СервисОНадстройки, щелкните на кнопке Обзор и найдите файл необходимой надстройки.
Добавить новый член в коллекцию Addlns с помощью VBA можно, воспользовавшись методом Add коллекции Addlns.
Application.Addlns.Add "с:\files\newaddin.xla"
После выполнения представленной выше операции коллекция Addlns будет содержать дополнительный элемент, а диалоговое окне» Надстройки отобразит новый элемент списка. Если надстройка уже существует в коллекции, то ничего не произойдет, и сообщение об ошибке не будет генерироваться.
Когда добавляемая надстройка находится на сменном носителе (например, на дискете или на компакт-диске), вы имеете возможность скопировать файл в папку библиотеки Excel с помощью метода Add. В следующем примере файл Myaddin.xla копируется с диска А: и добавляется в коллекцию Addlns. Второй аргумент (в данном случае равный True) указывает на необходимость копирования надстройки. Вели надстройка находится на жестком диске, то второй аргумент можно игнорировать:
Application.Addlns.Add "a:\Myaddin.xla", True
Добавление новой надстройки в коллекцию Addlns не приводит к ее установи. Для того чтобы установить надстройку, необходимо присвоить ее свойству Installed значение True.
Системный реестр не обновляется до того момента, пока Excel не завершит свою работу привычным способом. Если Excel завершает свою работу анормально (т.е. со сбоем), то имя надстройки не будет добавлено в системный реестр, а надстройка не становится частью коллекции Addlns при следующем запуске Excel.
Удаление элемента из коллекции Addlns
Как ни удивительно, однако не существует явного способа удаления элемента из коллекции Addlns. Коллекция Addlns не имеет метода D e l e t e или Remove. Одним из способов удаления надстройки из диалогового окна Надстройки является непосредственное редактирование параметра системного реестра (для этого используется программа r e g e d i t . exe). В результате надстройка не будет отображена в списке диалогового окна Надстройки при следующем запуске Excel. Обратите внимание на то, что данный метоп не применим ко всем файлам надстроек.
554 |
Глава 21. Создание и использование надстроек |

Еще одним способом удаления надстройки из коллекции Addlns является удаление, перемещение или переименование файла XLA, который содержит надстройку. При последующей попытке установки этой надстройки будет отображено предупреждение, которое показано на рис. 21.4. В этом предупреждений пользователю предоставляется возможность удалить надстройку из коллекции Addlns.
Рис.21.4.Такойхитроумныйспособудалениянадстройки из коллекции Addlns весьма эффективен
Свойства объекта Addln
Объект Addln является единственным членом коллекции Addlns . Например, для того чтобы отобразить имя файла, в котором содержится надстройка, являющаяся первым членом коллекции Addlns, можно воспользоваться следующим оператором.
MsgBox Addlns(1)-Name
Объект Addln имеет 14 свойств, информацию о которых можно получить в справочном руководстве. Пять свойств являются "скрытыми". Названия таких свойств довольно запуганы, поэтому мы рассмотрим некоторые наиболее важные свойства этого объекта.
Name
Это свойство содержит имя файла надстройки. Name — это свойство, предназначенное только для чтения, оно не позволяет изменить имя файла и указать другое значение свойства Name.
Path
Свойство, содержащее имя диска и папки, в которых содержится файл надстройки. Данное свойство не имеет наклонной черты и имени файла.
FullName
Это свойство содержит полное имя надстройки, которое состоит из имени диска, пути и имеки файла. Данное свойство бесполезное, поскольку эта информация предоставляется свойствами Name и P a t h . Следующие операторы в результате выполнения возвращают одинаковые строки:
MsgBox Addlns(I).Path & "\" & Addlns(1)-Name MsgBox Addlns(1).FullName
Title
Скрытое свойство, содержащее описательное имя надстройки. Свойство T i t l e отображается в диалоговом окне Надстройки. Данное свойство предназначено только для чтения, и единственный способ изменить значение этого свойства— это использовать команду Файл^Свойства (перейдите на вкладку Документ и введите текст в поле Название). Эту команду необходимо выполнять по отношению к файлу XLS до того, как он будет преобразован в надстройку.
Как правило, к члену коллекции обращаются с помощью значения свойства Name. Коллекция Addlns этим отличается от других коллекций. В ней вместо свойства Name для адресации
ЧастьV.Совершенныеметодыпрограммирования |
5J5 |

используется значение свойства T i t l e . Следующий пример отображает имя файла надстройки View Manager (т.е. View.xls), значение свойства T i t l e которой равно View Manager.
Sub ShowName{)
MsgBox Addlns("View Manager").Name End Sub
Можно, конечно, ссылаться на определенную надстройку по индексу, если индекс известен точно.
Comments
Это скрытое свойство хранит текст, который отображается в диалоговом окне Надстройки, описывающем определенную надстройку. Свойство Comments предназначено только для чтения. Единственный способ изменить его значение— использовать диалоговое окно Свойства до преобразования рабочей книги в надстройку. Описание может достигать 255 символов, но диалоговое окно Надстройки отображает из них только первые 100.
Installed
Свойство I n s t a l l e d имеет значение True, если надстройка установлена (т.е. в диалоговом окне Надстройки напротив имени надстройки установлен флажок). Установка свойства I n s t a l l e d в значение True приводит к загрузке надстройки. Установка этого свойства в значение F a l s e приводит к выгрузке надстройки из памяти. Ниже приведен пример установки (т.е. открытия) надстройки MS Query с помощью кода VBA.
Sub InstallQueryO
Addlns{"MS Query Add-In").Installed = True End Sub
После выполнения процедуры диалоговое окно Надстройки будет отображать установленный флажок напротив имени надстройки MS Query. Если надстройка уже установлена, то присвоение свойству I n s t a l l e d значения True не приведет к выполнению каких-либо действий. Для того чтобы отключить надстройку (удалить), установите свойство I n s t a l l e d в значение F a l s e .
Если надстройка открыта с помошью команды Фай^Открыть, то она не считается установленной. Следовательно, ее свойство installed будет иметь значение False.
Следующая процедура отображает количество надстроек, которые находятся в коллекции Addlns, и количество надстроек, которые установлены в данный момент. Легко заметить, что при подсчете установленных надстроек не учитываются надстройки, которые открыты с помощью команды Файл^ХЭткрыть.
Sub CountlnstalledAddlns() Dim Count As Integer
Dim Item As |
Addln |
Dim Msg As |
String |
Count = D |
|
For Each Item In Addlns |
|
If Item.Installed Then Count = Count + 1 |
|
Next Item |
|
Msg = "Надстройки: " &• Addlns.Count & Chr(13) |
|
Msg = Msg & |
"Установлено: " & Count |
MsgBox Msg |
|
End Sub |
|
556 |
Глава 21. Создание и использование надстроек |

Следующая процедура анализирует все надстройки в коллекции Addlns и удаляет из памяти все надстройки, установленные в данный момент. Данная процедура не влияет на надстройки, которые открыты с помощью команды Файл^Открыть.
Sub InstallAllO
Dim Count As Integer Dim Item As Addln Count = 0
For Each Item In Addlns
If Item.Installed Then Item.Installed = False Count = Count + 1
End If Next Item
MsgBox "Установлено " & Count & " надстроек" End Sub
С помощью значения свойства isAddin можно определить, является ли рабочая книга надстройкой. Это свойство предназначено как для чтения, так и для записи, поэтому рабочую книгу можно превратить в надстройку в результате устаневки свойства isAddin в значение True.
Получение доступа к надстройке как к рабочей книге
Как отмечалось ранее, существует два метода открытия надстройки: с помощью команды Файл^Открыть м с помощью команды Сервис^Надстройки. Второй метод более предпочтительный при управлении надстройками. На то существует особая причина: при открытии надстройки с помощью команды Файл^Открыть свойство I n s t a l l e d этой надстройки не устанавливается а значение True. Таким образом, данный файл невозможно закрыть с помощью диалогового окна Надстройки. Единственной возможностью закрыть эту надстройку является использование соответствующего оператора VBA. Например, можно применить оператор
W o r k b o o k s ( " M y a d d i n . x l a " ) . C l o s e
Использование метода close по отношению к установленной надстройке приводит к удалению надстройки из памяти, но не устанавливает ее свойство I n - s t a l l e d в значение False. Таким образом, диалоговое окно Надстройки все еще будет указывать эту надстройку в числе установленных, что может ввести пользователя в заблуждение. Правильным способом удаления установленных надстроек является установка их свойства i n s t a l l e d в значение False.
Итак, как вы заметили, возможность использования надстроек Excel является несколько неоднозначной. Разработчик должен быть особо внимателен к вопросам установки и удаления надстроек.
События объекта Addln
Объект Addln имеет два события: Addlnlnstall (событие возникает при установке надстройки) и AddlnUninstall (событие возникает при удалении надстройки). Можно создать процедуры обработки этих событий, которые размещаются в модуле кода объекта ThisWorkbook, соответствующего надстройке.
Следующий пример отображает окно сообщения в момент установки надстройки.
Private Sub Workbook_Addinlnstall()
MsgBox ThisWorkbook.Name & _ " установлена."
End Sub
Часть V. Совершенные методы программирования |
557 |

Не путайте событие A d d i n i n s t a l l и событие Open. Событие Addininstall возникает только при первой установке надстройки. Если необходимо выполнять определенный код каждый раз при открытии надстройки, то можно воспользоваться процедурой Workbook_Open.
Дополнительная информация о событиях приведена в главе 19.
Оптимизация производительности надстроек
Основное требование к надстройкам— эти максимальная производительность и эффективность. В настоящем разделе будут рассмотрены некоторые методы оптимизации надстроек.
Скорость выполнения кода
Если попросить десять программистов провести автоматизацию определенной задачи, то вполне вероятно, что в результате будет получено десять различных решений, Чаще всего производительность всех этих решений будет находиться на одинаковом уровне.
Ниже приводятся советы, которые можно использовать для обеспечения максимального быстродействия кода.
•При записи данных на рабочий лист установите свойство A p p l i c a t i o n . Screen - Updating в значение F a l s e .
•Объявляйте тип данных всех применяемых переменных, а в законченном коде любой ценой
избегайте использования переменных типов. Используйте оператор Option E x p l i c i t
в начале каждого модуля, чтобы сделать объявление типа переменной обязательным,
•Создавайте переменные, чтобы избежать длинных ссылок на объекты. Например, если
вы управляете объектом S e r i e s диаграммы, то необходимо создать переменную с помощью следующего кода:
Dim Si As Series
Set SI = ActiveWorkbook.Sheets(1).ChartObjects(1). Chart.SeriesCollection{1)
•Объявляйте переменные объектов конкретного типа. Избегайте использования As Object.
•Применяйте конструкцию With-End With для вызова нескольких методов и для изменения нескольких свойство одного объекта везде, где это возможно.
•Удалите избыточный код, особенно в записанных макросах.
•Если возможно, управляйте данными с помощью массивов VBA, а не диапазонов рабочих листов. Чтение и запись на рабочий лист занимает намного больше времени, чем обработка данных в памяти. Но это правило не всегда справедливо. Для получения наилучшего результата необходимо проверить быстродействие обоих вариантов.
•Избегайте связывания элементов управления пользовательских диалоговых окон с ячейками на рабочем листе, что можег привести к пересчету рабочего листа при каждом изменении элемента управления в диалоговом окне.
•Перед созданием надстройки компилируйте используемый код. Это приведет к увеличению размера файла, но избавит от необходимости компилировать код перед каждым запуском процедур.
558 |
Глава 21. Создание и использование надстроек |