Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Леонтьев Б.К. Я изучаю Microsoft Office Visio 2003 (PDF)

.pdf
Скачиваний:
681
Добавлен:
02.05.2014
Размер:
919.27 Кб
Скачать

Использование редактора Visual Basic

261

 

 

 

Эта команда устанавливает альбомную ориентацию листа в доку менте. У объекта Application (приложение, в данном случае Visio 2003) есть подобъект ActiveDocument (активный документ), у этого подобъекта есть еще подобъект — PageSetup (параметры страницы), далее следует подобъект Orientation (ориентация листа), которому присваивается зна чение wdOrientLandscape — альбомная ориентация листа.

Такой же вид имеет и команда получения информации об ориен тации листа — она будет выглядеть так:

p = Application.ActiveDocument.PageSetup.Orientation.

После ее выполнения значение переменной р будет wdOrient# Landscape или wdOrientPortrait соответственно. При написании команд редактор Visual Basic for Applications постоянно подсказывает возможные варианты следующего шага. Так, к примеру, стоит написать в тексте про граммы слово Application и поставить точку, как сразу появятся возмож ные варианты продолжения.

Можно мышкой выбрать нужный вариант, и он обязательно бу дет правильным — не в смысле верности алгоритма (это остается на со вести программиста), а в смысле соответствия правилам синтаксиса и иерархии объектов, а также правописания слова. Затем можно вновь по ставить точку, и вновь будет выдан список возможных вариантов про должения.

Есть также команда завершения слова — можно не писать целиком слово Application, а набрать Appli и нажать Ctrl+пробел. Редактор допишет слово сам или предоставит возможность выбора слова, если его однознач но нельзя определить по первым буквам. Он как бы «ведет» программис та по процессу написания программы, позволяя ему сосредоточиться не на банальном синтаксисе языка, а на решаемой программой проблеме, и не держать в памяти правила написания каждой команды.

Даже если программист не воспользуется предоставляемой под сказкой и введет всю команду вручную, то редактор не даст ему так про сто двинуться дальше, если в элементарном синтаксисе данной команды будет ошибка, выдав сообщение «Ошибка компиляции».

Еще одним серьезным достоинством редактора Visual Basic for Applications 6.3 является наличие прекрасной справочной системы. По ставив курсор на любую команду или название объекта Visual Basic for Applications и нажав клавишу F1, можно получить подробную справку о том, зачем нужна эта команда, каков ее синтаксис и даже посмотреть пример ее использования и скопировать его себе, если необходимо.

262

Использование редактора Visual Basic

 

 

 

Подобная дружественность редактора Visual Basic for Applications дает прекрасную возможность для самостоятельного изучения этого язы ка программирования.

Поставив перед любой командой знак апострофа, можно ее за комментировать, т. е. исключить из выполнения. В этом случае Visual Basic for Applications не будет ее выполнять. Кроме того, после знака апо строфа можно написать пояснения к соответствующей части программы для себя и других программистов. Все комментарии отображаются в ре дакторе Visual Basic for Applications зеленым цветом.

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

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

В случае, если выбрать какой нибудь элемент формы, а из его кон текстного меню пункт Properties, то откроется «Окно свойств». Здесь можно задать все доступные свойства каждого элемента (к примеру, его цвет, цвет границы, надпись, состояние — доступно/недоступно для из менений), поместить на элемент картинку из внешнего файла. Все эти свойства также можно задавать программно, однако некоторые, вроде той же картинки, стоит задавать только в этом окне.

Окно «Просмотр объектов», вызываемое кнопкой F2, является кратким справочником по всем возможным свойствам и методам (т.е. действиям, командам) объектов Visual Basic for Applications.

Можно посмотреть, какие свойства или методы доступны для каждого объекта, какие объекты в принципе существуют в Visual Basic for Applications, вызвать справочный файл для каждого объекта, свойства или метода.

Все модули, входящие в состав проекта, можно сохранить в текс товом файле. Модуль будет сохранен в текстовом файле с расширением

.BAS. Можно просто перетащить название модуля в окно «Проводника» Windows, удерживая левую кнопку мыши, — редактор Visual Basic for Applications поддерживает механизм Drag'n'Drop.

Использование редактора Visual Basic

263

 

 

 

Отладка программы

В Visio 2003 редактор Visual Basic for Applications обладает широки ми возможностями отладки программы, т. е. поиска в ней алгоритмиче ских и языковых ошибок.

Следует учесть, что язык Visual Basic for Applications не компилиру емый, а интерпретируемый (готовая программа представляет собой текст исходного кода, хранящийся в шаблоне или документе, который перево дится в машинные коды при каждом ее запуске, в то время как конечный продукт средств создания программ на остальных языках программиро вания представляет собой файл с исполняемым машинным кодом).

Именно по этой причине после завершения написания кода и ус пешной его отладки программа готова к использованию.

Для запуска на выполнение готовой или записанной программы из редактора Visual Basic for Applications необходимо нажать клавишу F5. Программа начнет выполняться, и, если в ней вдруг найдутся ошибки в записи команд или обращения к неизвестным командам, будет выдано соответствующее сообщение.

В случае, если возникает ошибка вследствие неправильного ис пользования команд, то редактор Visual Basic for Applications выдает диа логовое окно, в котором приводится описание ошибки.

Через меню команд Debug можно перейти в режим отладки про граммы — специального состояния редактора Visual Basic for Applica tions, в котором программа может исполняться построчно, а програм мист имеет возможность видеть значения всех переменных программы и даже принудительно задавать эти значения. Также в режим отладки мож но перейти из редактора Visual Basic for Applications, поставив курсор в текст программы и нажав клавишу F8.

В режиме отладки программисту доступны следующие возможно

сти:

Пошаговое исполнение программы

Выполняются все команды последовательно, но выполнение каж дой команды требует нажатия кнопки F8. В случае, если программа где то выдает ошибку алгоритма, то можно посмотреть, на каком конкретно этапе это происходит. При пошаговом исполнении в редакторе желтым цветом подсвечивается команда, которая будет выполнена следующей.

Просмотр значений переменных

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

264

Использование редактора Visual Basic

 

 

 

значения переменных в этом окне принимают те значения, которые они имеют в программе. Это очень полезно для отладки алгоритма програм мы, когда необходимо найти ошибку во внутренней логике программы, связанную с неправильной или недостаточно точной разработкой поряд ка действий.

Точки останова

В случае, если программа длинная, то проходить по всем ее строч кам с помощью кнопки F8 — занятие не слишком интересное и прият ное. В этом случае лучше использовать точки останова — отметки в тек сте программы, где ее исполнение должно остановиться, а сама программа перейдет в режим отладки. Для задания точки останова нуж но щелкнуть левой кнопкой мыши на сером левом поле окна модуля, и тогда появится коричневая строка с кружочком на месте точки останова.

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

Окно контрольного значения

В этом окне можно задать определенное выражение, значение ко торого будет подсчитываться параллельно с выполнением программы. Кроме того, выделив в режиме отладки какое нибудь выражение и нажав Shift+F9, можно увидеть его значение, а также добавить это выражение в окно контрольного значения и отслеживать его дальнейшие изменения.

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

Окно отладки

В текст программы можно вставить специальную команду Debug.Print (a+b, к примеру). Тогда при выполнении этой команды в «Окно отладки» будет печататься то, что задано в ее параметрах. Возмож ности применения этого окна многообразны. В него могут выводиться сообщения в случае выполнения какого либо условия. Могут отобра жаться и промежуточные результаты вычислений для контроля их пра вильности — чтобы не смотреть и не искать нужное выражение в окнах «Локальные переменные» или «Контрольное значение», а видеть их сразу на экране.

Использование редактора Visual Basic

265

 

 

 

Окно отладки можно использовать даже как маленький калькуля тор или командную строку, и тогда при нажатии Enter после ввода ко манды она будет тут же выполнена! Надо только перед самой командой писать слово Print, и тогда команда выдаст результат в этом же окне.

Стек вызова

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

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

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

Настройка вызова программы

Когда программа написана и отлажена, необходимо придать ей «товарный вид» — убрать лишние команды и модули, создать способ вы зова программы (кнопку или пункт меню) или панель инструментов для кнопок. Без этого даже с очень хорошо написанной программой сможет работать лишь ее создатель, да и то не всегда. К тому же красивое оформ ление всегда радует глаз.

Для начала нужно просмотреть весь код и выкинуть все лишнее — закомментированные ненужные команды, просто излишние коммента рии. Потом следует определить, какие модули и формы являются компо нентами готовой программы, а какие, возможно, были написаны для других программ или в качестве экспериментальных, и запомнить их на звания.

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

Советы

Команда On Error Resume Next — обработчик ошибок. При воз никновении ошибки в тексте (связанной, скажем, с обращением к несу

266

Использование редактора Visual Basic

 

 

 

ществующему объекту) он продолжит выполнение программы с той ко манды, которая следует за вызвавшей ошибку. Обработчик ошибок мо жет также выглядеть как On Error GoTo метка, и тогда при ошибке про изойдет переход к указанной в нем метке, а программа продолжит выполняться именно с нее.

Для того, чтобы ускорить исполнение программы, работающей с текстом, в ее начало нужно поставить команду Application.ScreenUpdating = False, а в конец — Application.ScreenUpdating = True (если только не тре буется контролировать происходящие изменения). Эти команды позво ляют системе не тратить время и силы на постоянное обновление экрана и отображение изменений. Но если все же нужно обновить экран, то сле дует использовать команду Application.ScreenRefresh.

На сайте www.microsoft.ru/offext можно найти огромное число ма кросов и шаблонов. Изучение их текста помогает освоить Visual Basic for Applications, узнать много новых приемов и команд. Можно даже послать на конкурс свою программу макрос, а если она будет признана достой ной, то и выиграть приз!

В случае, если исходный текст программы на Visual Basic for Applications закрыт от просмотра паролем, а вы его забыли, то не огорчай тесь: в Интернет по адресу www.passwords.ru есть программа Advanced VBA Password Recovery, позволяющая восстановить забытый пароль. Ее английская версия требует оплаты и регистрации, а русская — бесплатна).

Во многих программах для Windows используется такой элемент, как ProgressBar — индикатор, показывающий течение того или иного процесса. Причем он есть практически во всех программах инсталлято рах. К сожалению, в VBA этот элемент отсутствует, но его можно создать самостоятельно. Делается он следующим образом (предполагается, что есть часть программы, в которой выполняется продолжительный цикл, т. е. известное число однотипных операций). Создаем небольшую форму и помещаем на нее надпись с пояснительным текстом (в частности, Label1) и две другие (скажем, Label2 и Label3), низкие и широкие, располагая их одну над другой. Зададим этим формам, к примеру, следующие коорди наты и размеры:

Label2: Top — 45, Left — 15, Height — 15, Width — 250

Label3: Top — 45, Left — 15, Height — 15, Width — 0

Для Label2 укажем в качестве фонового цвета серый, а для Label3 — зеленый.

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

Использование редактора Visual Basic

267

 

 

 

Private Sub UserForm_Activate()

…остальной текст программы, которая должна выполняться во время отображения ProgressBar’а…

Unload Me

End Sub

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

Ширину любой надписи можно изменять программно. Поэтому для отображения ProgressBar вставим в текст строки, изменяющие ши рину надписи Label3. Например, некий цикл, который нужно снабдить ProgressBar, в программе выполняется n раз. Тогда ширина надписи Label3 будет определяться командой в теле этого цикла по формуле: Label3.Width = (scet / n)*250, где scet — счетчик цикла, а 250 — ширина надписи Label2. После каждой такой команды следует вставлять инст рукцию Me.Repaint, чтобы перерисовать форму с учетом новых парамет ров третьей надписи, поскольку автоматической перерисовки до полно го отображения формы не происходит — это совершится тогда, когда закончится обработка события UserForm_Activate() и форма будет выгру жена. В случае, если форма с ProgressBar должна долго находиться на эк ране без изменений, то рекомендуется почаще использовать команду Me.Repaint, так как без перерисовки внешний вид формы может быть ис порчен окнами других приложений.

Итак, текст для формы с ProgressBar должен иметь следующий

вид:

Private Sub UserForm_Activate() Me.Repaint

For t=1 to n

‘n — количество необходимых выполнений команд цикла

… … … … нужные команды программы в цикле

...

...

...

...

Label3.Width = ((t / n) * 250) Me.Repaint

Next t Unload Me End Sub

268

Использование редактора Visual Basic

 

 

 

В то место основной программы, в котором должен находиться цикл с ProgressBar, следует поместить команду вызова этой формы (здесь: UserForm.Show), не забыв объявить передаваемые в цикл и из цикла переменные основной программы как Public. Цикл как бы «выно сится за пределы» основной программы и помещается в обработчик со бытия UserForm_Activate.

Разумеется, текст можно изменять и улучшать. Например, не сколько раз использовать ProgressBar в одной форме, каждый раз обну ляя ширину третьей надписи. А еще можно поместить на одну форму не сколько обработчиков ProgressBar, где один из них показывает выполнение всего задания, а другой — его текущей части. В общем, есть простор для творчества.

Хранение в документе скрытой информации

Иногда в документ нужно записать какую нибудь информацию «для внутреннего пользования», в частности такую, которая позволила бы при следующей обработке документа программой использовать опре деленные предыдущие данные и сделать такую запись с помощью свой ства Variable:

ActiveDocument.Variables.Add Name:="x1",

Value:="Первая переменная"

ActiveDocument.Variables.Add Name:="x2",

Value:=12

Прочитать эти переменные можно с помощью похожей функции:

y1 = ActiveDocument.Variables("x1").Value

y2 = ActiveDocument.Variables("x2").Value

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

For Each per In ActiveDocument.Variables

Debug.Print per.Name + " " + per.Value

Next per

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

Использование редактора Visual Basic

269

 

 

 

Глава 9.

Прием событий

Итак, посредством Microsoft Office Visio 2003 вы можете «улуч шить» ваши проекты и решения, используя встроенный в это приложе ние язык программирования Microsoft Visual Basic for Applications (VBA) версии 6.3.

Visual Basic — простейшее средство разработки для создания боль шинства типов приложений, поэтому неудивительно, что оно позволяет проще всего реализовать прием событий. Даже, если вы активный сто ронник C++, особенно при создании собственных интерфейсов, вы должны знать, что на Visual Basic гораздо легче разрабатывать клиент ские приложения в Microsoft Office Visio 2003, которые принимают собы тия хотя бы от таких серверов, как Internet Explorer 6.0. К примеру, авто матизируя сервер на Visual Basic, вы прежде всего должны объявить переменную типа сервера, который вы автоматизируете: вы просто зада ете зарезервированное слово WithEvents, чтобы сообщить о том, что хо тите получать события от данного сервера.

Глава 10. Мониторинг событий

С появлением элемента управления WebBrowser control в Microsoft Internet Explorer создание Интернет приложений значительно упрости лось. Для того, чтобы добавить функции просмотра Web узлов в свое приложение, достаточно использовать управляющий элемент WebBrow# ser. Он позволяет обращаться к любому URL адресу, перемещаться по списку истории посещений или переходить непосредственно на домаш нюю страницу пользователя. К вашим услугам любые возможности обо зревателя Internet Explorer. С помощью WebBrowser вы также способны автоматически управлять Internet Explorer 6.0.

Конечно, управление Internet Explorer 6.0 — это прекрасно. Но ес ли вы не знаете, что делает Internet Explorer в каждый конкретный мо мент, значит, по прежнему не способны на полный контроль. Поэтому Internet Explorer предоставляет интерфейс событий Event interface, через который можно отслеживать его активность и выполнять определенные действия.

Предположим, что в Microsoft Office Visio 2003 вы создаете прило жение, предназначенное для использования в интрасети предприятия и хотите запретить пользователям просмотр внешних серверов Интернет.

270

Использование редактора Visual Basic

 

 

 

«Прослушивая» события, происходящие в Internet Explorer, ваше прило жение определит момент запроса пользователем внешнего URL, а затем полностью отменит этот переход. Для реализации данного механизма вам потребуется знать, какой тип события запускает Internet Explorer 6.0, как обеспечить прием и реализовать обработку событий в своем прило жении.

Что такое события? Для уведомления своих клиентов о каком то событии СОМ объект отправляет сообщение. Это сообщение так и на зывается — событие (event), а процесс передачи сообщения называется запуском события (event firing). Но если событие запущено, а его никто не ждет, то какой в нем смысл? Очевидно, что клиентское приложение, управляющее СОМ объектом, должно «прислушиваться» к инициализи руемым событиям. Когда клиентское приложение «хочет» получать со бытия от СОМ объекта, оно сообщает об этом СОМ объекту.

СОМ объект сможет «разговаривать» со своим клиентом, если он поддерживает один или более исходящих интерфейсов (outgoing inter face). Такие интерфейсы реализуются клиентом, и каждый из них под ключается к СОМ объекту через отдельную точку подключения (connec tion point). Любая точка подключения представлена интерфейсом IConnectionPoint. Часть клиента, обеспечивающая исходящие интер фейсы, известна как приемник событий (event sink); СОМ объект, кото рый поддерживает данные интерфейсы, называется подключаемым объ ектом (connect able object). Для того, чтобы быть подключаемым объектом и поддерживать точки подключения, объект должен реализо вывать интерфейс IConnectionPointContainer, через который клиенты бу дут узнавать, какие исходящие интерфейсы поддерживает сервер.

Каждый подключаемый объект реализует этот интерфейс. Кли ент, желающий получать события, может узнать через IConnection# PointContainer, какие точки подключения поддерживает подключаемый объект. Клиент способен получить указатель на IConnectionPoint# Container, просто вызвав Querylnterface, используя указатель на другой интерфейс. Затем клиент применяет один из двух методов данного ин терфейса для получения указателя на точку подключения.

С помощью EnumConnectionPoints он получает список указателей на все точки подключения, которые поддерживаются этим подключае мым объектом. Другой метод, FindConnectionPoint, позволяет клиенту спрашивать у подключаемого объекта, поддерживает ли он тот или иной интерфейс. Клиент указывает идентификатор интерфейса (IID) той точ ки подключения, которая его интересует. В случае, если подключаемый объект поддерживает такой интерфейс, он вернет указатель на интер фейс ICormectionPoint для соответствующей точки подключения.

Использование редактора Visual Basic

271

 

 

 

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

Соединение с определенной точкой подключения подключаемого объекта клиент устанавливает по методу Advise. В сущности клиент «го ворит» объекту: «Вот приемник событий, который я реализовал для дан ной точки подключения. Пожалуйста, отправляй ему все события». Кли ент должен передать своему приемнику событий указатель на интерфейс Unknown. Подключаемый объект использует этот указатель для запроса к клиенту об интерфейсе приемника событий, поддерживаемом данной точкой подключения. Кроме того, для получения событий приемник со бытий должен реализовывать IDispatch или сам интерфейс приемника событий (в Internet Explorer 6.0 для приема событий вы, как правило, бу дете применять метод IDispatch).

При каждом запуске события подключаемый объект вызывает IDispatch::Invoke (если вы реализуете сам интерфейс приемника собы тий, подключаемый объект может напрямую вызывать методы приемни ка событий).

Этот метод возвращает «cookie», который должен быть использо ван при разрыве соединения. Когда клиент хочет разорвать связь с под ключаемым объектом, он вызывает метод Unadvise и передает «cookie», который он получил при вызове Advise.

Несколько слов о других методах. GetConnection#PointContainer позволяет получить указатель на интерфейс IConnectionPointContainer для подключаемого объекта данной точки подключения. GetConnec# tionlnterface возвращает IID исходящего интерфейса, управляемого кон кретной точкой подключения. Данный метод позволяет клиенту преоб разовывать указатель на интерфейс IConnectionPoint в IID. Этот IID определяет точный интерфейс, на который указывает интерфейс

IConnectionPoint.

Прием событий

Существует несколько способов приема событий — в зависимости от инструмента разработки, применяемого для создания приложения в Microsoft Office Visio 2003.

272

Использование редактора Visual Basic

 

 

 

Прием событий в Microsoft Office Visio 2003, созданном с помо щью Visual Basic, будет существенно отличаться от приема событий в приложении, написанном на C++ (и, естественно, будет осуществляться гораздо проще). Даже при использовании Active Template Library (ATL), Microsoft Foundation Classes (MFC) или обычного C++ способы приема событий будут различны.

Прием событий в Microsoft Office Visio 2003

Убедитесь, что вы установили ссылку на shdocvw.dll в своем проек те Microsoft Office Visio 2003. В случае, если вы не сделали этого, Visual Basic не сможет довести такую ссылку до Internet Explorer. Далее, просто создайте экземпляр этого сервера, применяя зарезервированное слово

New или метод CreateObject.

Когда вы создаете экземпляр сервера, Visual Basic автоматически инициализирует приемник событий и управляет им — все очень просто. Вам не придется беспокоиться о получении указателя на контейнер то чек подключения (connection point container), а затем — о поиске необхо димой точки подключения. Visual Basic сделает это за вас. Понятно, что введя код создания сервера, нужно вставить вызовы методов, которые будут обрабатывать запускаемые этим сервером события. Вы можете оп ределить, какие события поддерживаются объектом, заглянув в окно

Procedures/Events.

Каждый раз, когда Internet Explorer 6.0 запускает событие, в текс товое окно помещается описание этого события. Создать такой код не сложно. Сначала с использованием зарезервированного слова WithEvents задается величина переменной, представляющей экземпляр Internet Explorer. Затем создаются функции обработчики событий (event handler function) для всех событий, которые вас интересуют. Этот пример под держивает только некоторое подмножество событий. Вы можете по сво ему усмотрению добавлять функции обработчики событий для любых других событий.

Глава 11. «Профи»

Управление событиями в «комбобоксе»

Две проблемы могут приключиться, когда смущенный юзер пол зает по комбобоксу при помощи мышки вверх и вниз, а затем нажатием на Enter делает свой юзерский выбор. Во первых, нажатие на серую стре лочку вызывает два события: Change и Click. Во вторых, нажатие на Enter

Использование редактора Visual Basic

273

 

 

 

перемещает фокус к следующему элементу формы, тогда как нажатие на кнопку мыши не вызывает подобного эффекта (то есть фокус остается на комбобоксе). Поэтому, если ваш код помещен в секцию события Change, то на стрелочки вверх/вниз (клавиатурой) вызовет это событие, чего вы, естественно, не хотите. Напротив, если вы помещаете свой код только в секцию события Lost Focus и юзер щелкает мышью на своем выборе, то фокус не уйдет из комбобокса, а юзер будет созерцать текст, который он выбрал своей мышью, и думать, почему это ничего не происходит. Ниже приведенное решение «фильтрует базар» событий Click, генерирующих ся нажатиями на стрелочки клавиатуры, и вынуждает контрол потерять фокус.В секции Declarations формы введите следующее:

В VB надо поменять тип флага на integer.

Dim bNoise as Boolean

True означает, что происходит «шум», на который не следует реагировать.

Этот код введите в секции события Form_Load: bNoise = False

Этот код введите в событии KeyDown комбобокса:

Private Sub cbTest_KeyDown(KeyCode As _ Integer, Shift As Integer)

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

If KeyCode = vbKeyDown Or KeyCode _ = vbKeyUp Then bNoise = True

End Sub

Этот код вводится в событие Click комбобокса:

Private Sub cbTest_Click() If bNoise Then

Ignore Noise events (up or down arrow) bNoise = False Else

Увести фокус с контрола

SendKeys "{TAB}", True End If

End Sub

Теперь вам остается написать код, содержащий реакцию на выбор юзера, и занести его в секцию события LostFocus комбика.

274

Использование редактора Visual Basic

 

 

 

Комментирование и раскомментирование блоков кода

VB позволяет вам разом закомментировать целый блок кода, а за тем также быстро раскомментировать его. Это очень полезно при отлад ке, когда вам не нужно исполнять целый ряд операторов, и в то же время вы не можете их удалить вот так вот просто за здорово живешь. Между тем, пара кнопок Comment/Uncomment присутствует только в меню Edit, который надо специально вызывать. Для того, чтобы быстро вызвать ме ню Edit, кликните правой кнопкой мыши на любом меню в VB, и выбе рите затем команду Edit.

Значения по умолчанию для необязательных параметров

В случае, если вы когда либо программили на VB4, то вы возмож но пользовались мощным инструментом под названием Необязательные параметры (Optional parameters).

VB 6.3 пошел еще дальше: теперь эти параметры могут быть любо го типа (не только Variants), и могут появляться в процедурах Property. Вы можете теперь задавать для них значение по умолчанию.

Property Get Value _ (Optional index As Long = 1) End Property

Вы можете теперь делать это без бывшего ранее обязательным (и очень медленным) тестом IsMissing:

Property Get Value _ (Optional index As Long)

If IsMissing(index) Then index = 1

...

End Property

Центрирование формы на экране

Все знают о коде, позволяющем вам центрировать форму на экра не вне зависимости от графического разрешения. Теперь вы можете до стичь того же результата, всего лишь присвоив значение vbStartUpScreen (=2) новому свойству StartUpPosition формы. Вы даже можете отцентри ровать форму относительно ее родительского окна, присвоив значение vbStartUpOwner (=1). Присвоение можно сделать в окне Property соответ ствующей формы. Когда вы центрируете форму внутри родительского окна, не забудьте добавить второй аргумент в методе Show.

Form2.Show vbModal, Me

Использование редактора Visual Basic

275

 

 

 

Не все шаблоны созданы одинаково

В отличие от других продуктов Office 2003, шаблоны Word 2003 со держат business#application engine, который хранится отдельно от доку ментов, использующих этот engine. Основанные на шаблонах книги Excel и презентации PowerPoint хранят в себе шаблоны, на основе кото рых они созданы.

На практике, все документы Word состоят из 2 х VBA проектов: первый проект создан на базе основного (оригинального, хранящегося в Word) шаблона (все документы Word основаны на шаблонах), а второй проект принадлежит самому документу Word. С другой стороны, книги Excel и презентации PowerPoint, созданные на шаблонах, содержат толь ко один VBA проект. Каждый файл содержит свою собственную копию проекта оригинального шаблона. Изменения, производимые в этом шаблоне, не затрагивают основной шаблон, хранящийся в приложении.

Настройка меню в VB

Вот несколько предложений по настройке IDE в Visual Basic 6.3.

Добавить закладки в панель инструментов можно, кликнув правой кнопкой мыши на кнопке General и выбрав Add Tab.

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

Вытащить кнопку любого пункта меню на тулбар можно, кликнув правой кнопкой на любом тулбаре и выбрав пункт Customize. Перейдите на закладку Commands, выберите нужный пункт меню в правом окошке и перетащите его на тулбар. Первыми кандидатами на добавление являют ся пункты Project#References, Project#Properties и Tools#Add Procedure.

Как создать совершенно новый тулбар на вкладке Toolbars диало гового окна Customize. После того, как вы определили содержимое буду щего тулбара, для добавления кнопок на этот тулбар используйте опи санную абзацем выше процедуру. Когда у вас на экране активизировано диалоговое окно Customize, кликните правой кнопкой на любой кнопке тулбара и вы сможете поменять рисунок кнопки, создать разделитель, спрятать/показать текст и т.д.

Как спрятать все окошки проекта

Когда вы работаете с несколькими проектами сразу, можно запу таться в нагромождении окошек из разных проектов. Однако, вы можете временно спрятать все окошки, относящиеся к данному проекту, щелк нув по пиктограмме проекта в окошке Project Explorer так, чтобы все вет ви, торчащие из него, исчезли. Тогда же свернутся и все окна, относящи

276

Использование редактора Visual Basic

 

 

 

еся к данному проекту. Эту возможность можно отменить, щелкнув на соответствующем квадратике на закладке General в меню Tools#Options.

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

В случае, если кликнуть правой кнопкой мыши в правом окошке Object Browser'а (там, где нарисованы члены классов), то выскочит кон текстное меню с командой Show Hidden Members. В случае, если щелк нуть на этой команде, то отныне Object Browser будет показывать все hid den свойства и методы (а также и классы) любой библиотеки, и вы можете использовать это для более детального исследования библиотек объектов.

Например, в библиотеке VBA есть hidden класс под названием _HiddenModule, в который входят многие известные функции VBA плюс три недокументированные: ObjPtr, StrPtr и VarPtr. ObjPtr возвра щает адрес private area экземпляра объекта, StrPtr возвращает адрес первого символа в строке, VarPtr возвращает адрес переменной или де скриптора строки (string descriptor, если имеем случай переменной типа string).

Адрес переменной

В Visual Basic 6.3 есть встроенная функция VarPtr.

Runtime library в VB4 включает эту функцию, но перед использова нием ее нужно сначала объявить:

#If Win16 Then

Declare Function VarPtr Lib "VB40016.DLL" (variable As Any) As Long

#Else

Declare Function VarPtr Lib "VB40032.DLL" (variable As Any) As Long

#End If

Эта функция полезна при передаче пользовательских типов (Type structure) во внешнюю процедуру API, и в этом типе какое либо из полей является адресом другой переменной или записи.

Когда BENCHMARK (измерения скорости работы программы) длятся сутками

Обычно, программисты на Visual Basic 6.3 измеряют скорость вы полнения кода при помощи Timer функции. Однако, если ваша про грамма должна завершиться на следующий день, то вы должны учесть, что значение, возвращаемое функцией Timer, ресетится в полночь. В слу

Использование редактора Visual Basic

277

 

 

 

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

Dim startTime As Date

StartTime = Now

'the code to be benchmarked

'...

Print "elapsedSeconds = " & Format$ ((Now — startTime) * 86400, "#####")

Вам понадобится функция Format$ для округления результата до целого.

APP.PATH может возвращать UNC пути

Visual Basic 6.3 может возвращать UNC путь, типа \\server\pro# grams\..., в зависимости от обстоятельств, от того как запущена програм ма и запущена она из Visual Basic 6.3 IDE или скомпилирована в EXE файл. Эта особенность может сильно испортить вам жизнь, если вы используете App.Path для установки текущего каталога при старте про граммы.

ChDrive App.Path

ChDir App.Path

Поскольку ChDrive на умеет обрабатывать UNC пути, этот код может вызвать фатальную ошибку времени выполнения, но может быть защищен использованием On Error Resume Next. Однако это не защитит вас от всех невзгод, могущих произойти. Наилучшее решение состоит в том, чтобы предоставить юзеру самому ввести каталог во время исполне ния программы, затем записать полученный путь в регистр или INI файл.

«Ускорьте» ваш код использованием CHOOSE

Вы можете использовать Choose там, где можно заменить массив или построить таблицы результатов, на стадии компиляции (compile# time), вместо того, чтобы делать это на стадии выполнения (run time). На пример, если вам надо знать значения факториалов чисел от 1 до 10, по пробуйте следующий пример (Choose производит выбор факториала из набора имеющихся значений вместо того, чтобы высчитывать фактори ал каждый раз заново):

Function Factorial(number As Integer) _ As Long

Factorial = Choose(number, 1, 2, 6, _ 24, 120, 720, 5040, 40320, _ 362880, 3628800)

End Function

278

Использование редактора Visual Basic

 

 

 

«ARRAY» — отныне это ошибочное имя для переменных

В случае, если вы часто используете имя array для переменных, вам придется пересмотреть ваш код при переносе его под Visual Basic 6.3. Это слово является теперь зарезервированным (reserved keyword) и не мо жет быть использовано в качестве имени переменной. Вы можете легко переделать ваш код при помощи команды Replace в IDE Visual Basic 6.3, не забудьте при этом черкнуть Find whole words only.

Запуск AUTOMATION MANAGER как HIDDEN задачи

В случае, если вы используете OLE Remote Automation, вы должны заранее запустить Automation Manager на сервере до того, как случится первая OLE remote communication. По умолчанию, это приложение visible, но вы можете его спрятать.

Для этого создайте ярлык для Automation Manager, который бы включал в командной строке переключатель /Hidden:

C:\Windows\System\AutMgr32.Exe /Hidden

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

Использование коллекции для отфильтровывания дублированных значений

Этот код иллюстрирует, как использовать коллекции (Collection) для генерации уникального набора величин из набора, содержащего дуб ликаты.

В этом примере сканируется массив строк и сортируются все уни кальные с использованием list#box контрола:

Sub Remove_Duplicates(arr() As String) Dim i As Long

Dim RawData As String

Dim DataValues As New Collection On Error Resume Next

Это вставлено для игнорирования ошибки 457 — Duplicate key.

For i = LBound(arr) To UBound(arr) RawData = arr(i)

DataValues.Add RawData, RawData

В случае, если Run time error 457 случилась, то повторяющееся значение игнорируется.

Next

On Error GoTo 0

Использование редактора Visual Basic

279

 

 

 

'Сохранение в List Box

'(свойство Sorted выставлено True) lstSortedData.Clear

For Each DataValue In DataValues lstSortedData.AddItem DataValue Next

End Sub

Запись текущей позиции и размера формы при помощи SAVESETTING

Функции SaveSetting и GetSetting облегчают написание сеттин гов. Эти две функции восстанавливают и запоминают текущие позиции формы:

Public Sub FormPosition_Get(F As Form)

'Считывает позицию формы F из

'ini/reg файла и соответственно

'позиционирует форму

Dim buf As String

Dim l As Integer, t As Integer Dim h As Integer, w As Integer Dim pos As Integer

buf = GetSetting(app.EXEName, _ "FormPosition", F.Tag, "")

If buf = "" Then

'defaults для центрирования формы F.Move (Screen.Width — F.Width) \ _ 2, (Screen.Height — F.Height) \ 2 Else

'выделить l,t,w,h и выставить форму pos = InStr(buf, ",")

l = CInt(Left(buf, pos — 1)) buf = Mid(buf, pos + 1)

pos = InStr(buf, ",")

t = CInt(Left(buf, pos — 1)) buf = Mid(buf, pos + 1)

pos = InStr(buf, ",")

w = CInt(Left(buf, pos — 1)) h = CInt(Mid(buf, pos + 1)) F.Move l, t, w, h

End If End Sub

Public Sub FormPosition_Put(F As Form)

'Пишет op,left,height и

280 Использование редактора Visual Basic

' width позиции формы F в reg/ini файл приложения Dim buf As String

buf = F.left & "," & F.top & "," & _ F.Width & "," & F.Height

SaveSetting app.EXEName,_ "FormPosition", F.Tag, buf End Sub

Вам следует поместить эти процедуры в модуль и вызывать их из событий Load и Unload форм. Вы должны написать имя формы в ее свой ство Tag, чтобы эти процедуры работали корректно:

Sub Form_Load()

FormPosition_Get Me

End Sub

Sub Form_Unload()

FormPosition_Put Me

End Sub

Зашифрованные пароли

Следующие две функции легко и эффективно шифруют/дешиф руют текстовый пароль. Функции имеют два аргумента: число от 1 до 10 чтобы сдвигать позицию символа ASCII в пароле, и собственно строка пароля. Функция EncryptPassword проходит через каждый символ строки DecryptedPassword, проверяет символ на четность/нечетность, и сдвигает его вверх/вниз согласно параметру Number. Эту делает зашифрованную строку нечитабельной. Зашифрованный пароль «укатывается» затем оператором XOR, который еще более запутывает строку. В приведенном ниже коде ограничен параметр Number числом 10, поскольку не надо де лать проверку на «неправильные» символы ASCII. Функция DecryptPass# word повторяет в обратном порядке процесс шифрования, применяя XOR, а затем сдвиг.

Function EncryptPassword(Number As _ Byte, DecryptedPassword As String)

Dim Password As String, Counter As Byte Dim Temp As Integer

Counter = 1

Do Until Counter = _ Len(DecryptedPassword) + 1

Temp = Asc(Mid(DecryptedPassword, _ Counter, 1))

If Counter Mod 2 = 0 Then 'see if even

Temp = Temp — Number Else