Visual2000 · Архив статей А.Колесова & О.Павловой

Советы тем, кто программирует на Visual Basic и MS Office/VBA

Андрей Колесов

© 1996, Андрей Колесов
Авторский вариант. Статья была опубликована c незначительной литературной правкой в журнале "КомпьютерПресс" N 5/96, с. 80-83.


Совет 8. Читайте литературу, русскую и американскую

При освоении системы программирования, тем более новой, нужна хорошая литература. Безусловно, помогает документация и встроенная справочная система, но этого явно недостаточно для нормальной работы. Во-первых, я абсолютно уверен, что у большинства пользователей VB в России документации просто нет. (Рекламная пауза: "Покупайте лицензионные продукты.") Во- вторых, назвать ее исчерпывающей и до конца понятной — никак нельзя. Здесь лучше всего вспомнить о том, что Коран — одна книга, а толкования к нему насчитывают тысячи томов. И в- третьих, оказывается, что довольно большое число отечественных программистов предпочитают описания на русском языке.

В начале марта в продаже появилась новая книга на тему VB: "Visual Basic 3.0, Visual Basic 4.0 для Windows" (Москва, ABF, 1996, 360 стр., тираж 11 тыс. экз.) Имя ее автора, Хачатура Арушанова, хорошо известно в среде российских VB-программистов по публикациям в прессе и активной деятельности в сети FIDO. Книга предназначена в первую очередь для начинающих VB- программистов. Основная ее часть — систематический справочник по языку (описание операторов), и в этом плане она очень хорошо дополняет книгу "Running Visual Basic 3 for Windows", о которой я упоминал в Совете 4. Вообще я должен сказать, что написание книги о VB является делом непростым. Здесь важно определить точку отсчета — базовые знания языка читателя. Для меня, как человека, имеющего опыт программирования в QuickBasic, операторы VB процентов на 80 давно известны, и мне интереснее прочитать о свойствах, методах и пр. Однако многие VB-программисты незнакомы с базовым языком.

Книга Арушанова, кроме справочника, содержит и другие интересные сведения, советы и пр. В общем — книга полезная, и здесь мое мнение совпадает с мнением многих моих знакомых, прочитавших ее. Но все же надо сказать, что вторая часть заголовка "... Visual Basic 4.0" не должна вводить в заблуждение читателя — в статьях самого Арушанова, опубликованных ранее в "ComputerWeek", говорится о VB 4.0 гораздо подробнее. Впрочем, это не должно расцениваться как упрек автору: VB 4.0 — это целый мир, охватить который в одной книге просто невозможно.

В связи с этим следует упомянуть, что в США в продаже постоянно имеется несколько десятков книг, освещающих самые различные аспекты программирования на VB (базы данных, мультимедиа, классы, объекты и пр). Как правило, они имеют объем от 500 до 1200 стр., включают дискету или CD-ROM с программными примерами и стоят от 30 до 45 долл. В каждом номере американского журнала VBPJ в специальном разделе публикуются аннотации этих книг. В конце прошлого года, в связи с выходом VB 4.0, появилось огромное количество книг, посвященных этой версии. Среди них есть и переиздания, и принципиально новые книги, число которых продолжает расти. Я привожу здесь информацию об американских изданиях не с целью подразнить российских пользователей "их" жизнью, а для того, чтобы сказать, что при желании все эти книги можно реально приобрести. Готов поделиться собственным опытом.

В начало статьи

Совет 9. Используйте оператор Option Explicit

Наличие оператора Option Explicit (он находится в части Declarations программного модуля) свидетельствует о том, что все переменные данного модуля должны быть объявлены с помощью операторов DIM или REDIM. При появлении необъявленных переменных выдается сообщение об ошибке при запуске программы.

Для управления автоматической установкой этого режима во всех создаваемых модулях и формах установите флажок Reqiure Variable Declaration в положение Yes/No. Это флажок находится в диалоговом окне Environment Options, обращение к которому выполняется через соответствующую команду в меню Tools (VB 4.0) или Options (VB 3.0).

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

Традиционно Basic (и не только он, но и, например, Fortran) использовал принцип "по умолчанию". Его смысл заключался в том, что первое появление названия переменной в тексте программы автоматически означало ее объявление — самого существования переменной и ее типа. Вроде бы, это облегчало жизнь программистам (не надо было писать одну-две строки в заголовке модуля), но проблемы, возникающие при отладке из-за неправильного написания имен переменных, могли быть весьма значительными. Приведем примеры таких ситуаций.

i% = 1: m = I

Здесь программист забыл поставить в идентификаторе знак "%", в результате появилась новая переменная i, а значение m стало равным 0, а не 1.

MainCount = 1: m = MaimCount

То же самое — ошибка в написании идентификатора из-за довольно сложного имени (бывает и сложнее).

Обнаружить такие ошибки в больших программах бывает непросто. Этих проблем не возникло бы, если бы был установлен режим Option Explicit и эти переменные были бы объявлены:

Dim i%, MainCount

Явное описание переменных является хорошим поводом подумать об оптимальном использовании переменных в программе. Еще один пример:

For i = 1 To 10
   ...
   If A > B Then i = 1 Else i= 2
Next

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

Dim i ' i - счетчик цикла

Такое описание подсказало бы программисту, что переменная i уже использована в других целях.

В начало статьи

Совет 10. Следите за правильным использованием типов данных

Смысл этого простого совета заключается в следующем. Время выполнения операций для числовых данных разных типов различается довольно значительно. Кроме того, для их хранения требуются различные размеры памяти. Поэтому следует выбирать оптимальный тип переменной в зависимости от ее применения. Это особенно актуально для больших программ, но привыкать к этому нужно сразу. Не забывайте, например, что переменные Integer всегда работают значительно быстрее, чем Single и Variant.

В связи с этим следует напомнить, что в VB имеются три варианта определения типа переменной:

Dim Variable[суффикс - %,#,!,&,$,@]
Dim Variable As ....
Dim Variable

  1. Объявление типа с помощью суффикса является "исторической" спецификой Basic, лет десять назад других вариантов просто не было. Вообще-то, это было довольно удобно — по имени переменной сразу был виден ее тип. До появления VB в литературе по Basic этот классический вариант всегда использовался в листингах программ. Но расширение числа типов данных (в VB 4.0 их уже двенадцать) сделало невозможным дальнейшее применение данного принципа объявления типа переменной.

  2. Вариант "As" — наиболее универсальный, именно он считается сегодня методически самым верным.

  3. К третьему варианту нужно относиться с осторожностью. В этом случае тип переменных зависит от имени первой буквы. В VB имеется возможность делать такие установки с помощью группы операторов типа DefXXX (Defint, Defsng и пр.). Следует помнить, что по умолчанию, начиная с VB 3.0, тип переменной является Variant (в более ранних версиях — Single).

Современный стиль программирования предполагает использование смысловых идентификаторов (например, "FileNumber", а не "Ifn"), поэтому такой способ определения типа переменной применяется все реже. Тем не менее он очень удобен для новой установки по умолчанию всех переменных модуля. Чаще всего это делается для установки целочисленного типа: Defint I-Z.

В начало статьи

Совет 11. Используйте оптимальные программные конструкции

Собственно это продолжение предыдущего совета.

Сначала некоторые общие соображения. Учитывая, что создание программы должно укладываться в определенные сроки, общая стратегия разработки строится следующим образом. Прежде всего как можно быстрее создается первый работающий вариант, а затем выполняется доводка, в первую очередь фрагментов программы, наиболее критичных с точки зрения быстродействия. Здесь достаточно четко действует известный закон статистики 20/80 ("20% населения выпивают 80% пива") — "20% программы занимают 80% времени ее выполнения" и соответственно "20% программы требуют 80% времени на их разработку". При этом, разумеется, не стоит пренебрегать "правилами хорошего тона" и в процессе написания первого варианта программы. В связи с этим очевидный совет: будьте особенно внимательны при написании больших циклов.

Рекомендации, касающиеся кода, связанного с обработкой числовых данных, хорошо известны:

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

Как это сделать?

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

Вариант 1:

a$ = "": For n% = 1 To 255: a$ = a$ + Chr$(n%): Next

Вариант 2:

a$ = Space$(255): For n% = 1 To 255: Mid$(a$,n%) = Chr$(n%): Next

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

В начало статьи

Совет 12. Пишите комментарии в программе

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

В начало статьи

Совет 13. Копируйте структуру меню в разные формы

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

В начало статьи

Совет 13a. Как выделить текст при попадании в поле

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

Sub SetSelected()
  Screen.ActiveControl.SelStart = 0
  Screen.ActiveControl.SelLength = _
    Len(Screen.ActiveControl.Text)
End Sub

А для каждого текстового поля включите такой текст:

Sub txtField_GotFocus()
  SetSelected
End Sub

В начало статьи

Совет 13b. Как реализовать режим замены в текстовом окне

Текстовые окна в Windows всегда работают в режиме вставки и не обеспечивают возможность работы в режиме замены. Однако последний можно легко эмулировать, как показано здесь:

Sub Text1_KeyPress(KeyAscii As Integer)
   If KeyAscii >= 32 Then
      If Text1.SelLength = 0 Then
         If Text1.SelStart < Len(Text1) Then
            Text1.SelLength = 1
         End If
      End If
   End If
End Sub

Если вводится какой-либо символ (при условии, что текст не был выделен), данный код выбирает текущий символ, устанавливая свойство SelLength равным 1, и позволяет тем самым заменить его вводимым символом.

В начало статьи

Совет 13c. Как сделать, чтобы клавиша Tab обрабатывалась как обычный символ

Для этого нужно установить свойство TabStop = False для всех элементов управления в активной форме. После этого вы сможете вводить символы "tab" (chr 9) в текстовые поля элементов управления. Если нужно, чтобы клавиша Tab "вела себя обычным образом" (то есть осуществляла переход к следующему элементу управления) для одного из элементов управления такой формы, то достаточно просто эмулировать ее работу с помощью следующего кода:

Sub Command2_KeyDown (KeyCode As Integer, _
  Shift As Integer)
  ' На примере 3-х командных кнопок
  If KeyCode = 9 Then
    If Shift = 0 Then
      Command1.SetFocus
      ' Tab - следующий элемент управления
    ElseIf Shift = 1 Then
      Command3.SetFocus
      ' Shift+Tab - предыдущий
    End If
  End If
End Sub

В начало статьи