Тверской государственный университет
Опубликован: 13.09.2006 | Доступ: свободный | Студентов: 3491 / 369 | Оценка: 4.65 / 4.29 | Длительность: 30:37:00
Специальности: Программист, Менеджер
Лекция 4:

Типы данных и переменные

< Лекция 3 || Лекция 4: 1234 || Лекция 5 >

Объявление переменных и констант простых типов

В своем развитии Visual Basic прошел сложный путь - от бестипового языка с примитивным способом объявления переменных к структурированному языку с хорошо определенными типами данных и структурами управления. Но рудименты продолжают жить, и потому в языке одновременно существуют разные по идеологии способы определения данных. В частности, переменные можно объявлять или не объявлять, и тогда тип ей будет присвоен по умолчанию или по первой букве имени или по специальному символу объявления типа, которым может заканчиваться имя. Явно объявить переменную можно как в начале блока, так и в том произвольном месте, где возникла необходимость использовать новую переменную. Всеми этими рудиментами пользоваться не следует. Если в начало модуля вставить оператор Option Explicit (Опция "Явно"), то явное объявление переменных в этом модуле становится обязательным. Мы рекомендуем придерживаться следующей стратегии:

Всегда используйте явное объявление типа. Всегда помещайте объявления переменных в начало блока. Включите в Редакторе VBA в меню Tools на вкладке Editor флажок Require Variable Declaration. В этом случае во всех модулях Ваших проектов будет автоматически появляться оператор Option Explicit. Тем самым, Вы принуждаете себя следить за соблюдением правил хорошего тона в программировании.

При объявлении переменной определяется ее тип и область видимости - область, где имя переменной видимо и, значит, возможен доступ к ее значению. Важно понимать, что переменные можно объявлять на двух уровнях - уровне процедуры и уровне модуля . Для объявления переменных используются операторы Dim, Public, Private и Static. Первый можно использовать на обоих уровнях, Public и Private - на уровне модуля, Static - только на уровне процедуры.

Переменные, объявленные на уровне процедуры, называются локальными по отношению к данной процедуре. Их областью видимости является только та процедура, в которой они объявлены. Переменные уровня модуля являются глобальными . Они объявляются в разделе Declarations, который есть у каждого модуля. Область видимости глобальных переменных может распространяться:

  • на все процедуры одного модуля, в котором они объявлены; такие глобальные переменные, называемые закрытыми ( Private ), должны быть объявлены на уровне модуля либо оператором Private либо оператором Dim ;
  • на весь программный проект - все процедуры всех модулей данного проекта; такие глобальные переменные, называемые открытыми ( Public ), должны быть объявлены оператором Public.

Локальные переменные уровня процедуры могут быть объявлены оператором Static, что делает их статическими. У таких переменных увеличивается время жизни. Обычные локальные переменные рождаются при входе в процедуру, видимы только в ней и "умирают", выходя из процедуры. Это значит, что память под переменные отводится при входе в процедуру, а при выходе она освобождается. Область видимости статических переменных по-прежнему - процедура, но время жизни иное, так как у них не отбирается память при выходе, - она просто становится временно недоступной. Поэтому при повторном входе в процедуру статические переменные восстанавливают те значения, что у них были при последнем выходе. Статические переменные - это хранители информации между многократными вызовами одной и той же процедуры. Чтобы статические переменные имели смысл, необходима первоначальная инициализация переменных, - они должны иметь хоть какие-то значения уже при первом вхождении в процедуру. Вот как VBA инициализирует переменные в момент их объявления:

  • 0 - для численных значений;
  • пустая строка ("") - для строк переменной длины;
  • строка, содержащая нули, - для строк фиксированной длины;
  • Empty (значение, указывающее на отсутствие инициализации) - для типа Variant ;
  • для массивов и записей (типа, определенного программистом), каждый элемент инициализируется в соответствии с указанными правилами.
Синтаксис объявления простых переменных

Объявление простых переменных имеет следующий синтаксис:

{Dim | Private | Public | Static }<имя переменной> [ As <имя типа>]
      [, <имя переменной> [ As <имя типа>]]…

Вначале идет имя оператора, а потом список объявлений переменных, где роль разделителя играет запятая. Каждое объявление связывает имя переменной с ее типом, заданным конструкцией As. Будьте внимательны, VBA неприятно отличается в этом вопросе от других языков программирования. Здесь, как обычно, одним оператором можно объявить произвольное число переменных, но следует в каждом объявлении указывать конструкцию As, иначе переменным без As будет приписан тип Variant. На наш взгляд, то, что одним As нельзя объявить список переменных одного типа, - некий синтаксический "прокол", приводящий, если не к серьезным ошибкам, то к излишнему и не предполагаемому употреблению типа Variant.

Заметьте, есть и приятное отклонение, - имена переменных в VBA можно задать, используя русский алфавит.

Приведем пример, где действуют модули Father и Mother, в каждом из которых объявлены глобальные (общие и закрытые) переменные. В каждом из модулей объявлены две процедуры, взаимно вызывающие друг друга. Отладочная печать в процедурах позволит проследить за изменением значений глобальных, локальных и статических переменных. Вот тексты модулей Father и Mother - объявления глобальных переменных и процедур:

'Option Explicit
Public Fx As Byte, Fz As Integer
Private Fy As Integer

Public Sub Start()
	'Инициализация глобальных переменных
	Fx = 10: Fy = 11: Fz = 12
	Mx = 20: My = 21: Mz = 22
	Father1
End Sub

Public Sub Father1()
	Dim Fz As Byte 'Локальная переменная
	Fx = Fx + 2
	Fy = Mx - 2
	Fz = 1
	Debug.Print "Father1: Fx=", Fx, " Fy =", Fy, "Fz =", Fz
'Вызов процедуры другого модуля
	Mother1
End Sub

Здесь мы приводим тексты модуля Mother:

'Option Explicit
Public Mx As Byte
Private My As Integer

Public Sub Mother1()
	'Объявление статической переменной
	Static Count As Byte
	Count = Count + 1
	Mx = Mx - 2: Fz = My + 2
	Debug.Print "Mother: Статическая переменная Count =", Count
	'Вызов процедуры Father другого модуля или заключительной - Finish
	If Fx < Mx Then Father1 Else Finish
End Sub

Public Sub Finish()
	'Заключительная печать
	Debug.Print "Finish: Fx = ", Fx, "Fy =", Fy, "Fz =", Fz
	Debug.Print "Mx =", Mx, "My =", My, "Mz =", Mz
	'Объявления разных типов и печать значений, полученных при объявлении
	Dim B As Byte, I As Integer, L As Long
	Dim Sng As Single, D As Double, C As Currency
	Dim SF As String * 7, SV As String, Dat As Date
	Dim O As Object, V
	Debug.Print "B =", B, "I=", I, "L=", L
	Debug.Print "Sng =", Sng, "D =", D; "C=", C
	Debug.Print "SF =", SF, "SV =", SV, "Dat=", Dat
	If O Is Nothing Then Debug.Print "Объект не определен"
	If V = Empty Then Debug.Print "Variant переменные не инициализированы"
End Sub
3.1.

Запустив процедуру Start модуля Father, мы получили такие результаты отладочной печати:

Father1: Fx=	12	Fy =	18	Fz =	1 
Mother: Статическая переменная Count =	1 
Father1: Fx=	14	Fy =	16	Fz =	1 
Mother: Статическая переменная Count =	2 
Father1: Fx=	16	Fy =	14	Fz =	1 
Mother: Статическая переменная Count =	3 
Finish: Fx =16	Fy =	Fz =	2 
Mx =	14	My =	0	Mz =	
B =	0	I=	0	L=	0 
Sng =	0	D =	0	 C=	0 
SF =	SV =	Dat=	0:00:00 
Объект не определен
Variant переменные не инициализированы

Дадим краткий комментарий:

  • Процедуры Father и Mother трижды взаимно вызывают друг друга. Статическая переменная Count подсчитывает число сделанных обращений.
  • Процедура Father печатает значения глобальных переменных Fx, Fy и локальной переменной Fz. Заметьте, локальное объявление "сильнее" глобального.
  • Процедура Finish печатает заключительные значения переменных Fx, Fy, Fz, Mx, My и Mz. Здесь печатается значение глобальной переменной Fz, а значения двух переменных - Fy и Mz - не определены. Дело в том, что Fy - закрытая переменная модуля Father, а Mz вообще не объявлялась. И все же ошибки не возникает, так как действуют объявления по умолчанию и обе эти переменные считаются объявленными в модуле Mother и по умолчанию имеют тип Variant. Именно здесь кроется причина возможных ошибок, во избежание которых мы и советовали включить оператор Option Excplicit. Будь это сделано, - появились бы предупреждающие сообщения. У нас эти опции написаны, но специально закомментированы для демонстрации эффекта их отсутствия. Если их включить, то ошибка сразу встретится в процедуре Start -- ведь переменные My и Mz не определены в модуле Father.
  • Вторая часть процедуры Finish носит самостоятельный характер, - она демонстрирует объявления всех простых типов и печать значений, получаемых переменными при объявлении. Заметьте, как проверяется неопределенность объекта и пустота значений переменных.
Объявления по умолчанию

Настоятельно рекомендуем: не используйте средств, о которых мы сейчас расскажем. Мы и приводим их в первую очередь для того, чтобы дать подобный совет. Все необъявленные явно переменные по умолчанию считаются объявленными и имеют тип Variant. В VBA есть старомодные средства Бэйсика, позволяющие не объявлять переменную явно, но устанавливать ее тип по первому или последнему символу имени переменной. Имена переменных VBA могут заканчиваться специальным символом, позволяющим установить тип этой переменной:

  • % - Integer ;
  • & - Long ;
  • ! - Single ;
  • # - Double ;
  • @ - Currency ;
  • $ - String.

Есть еще одна возможность определения типа по первой букве имени. С этой целью в язык введена серия операторов DefType (по одному на каждый тип DefBool, DefInt и т. д.), определяющих свой диапазон букв для каждого типа. Если первая буква имени необъявленной переменной входит в тот или иной диапазон, ей приписывается соответствующий тип. Эти операторы устанавливаются на уровне модуля и действуют на все его процедуры.

Концевой символ установления типа сильнее, чем DefType, а тот сильнее стандартного "умолчания" Variant. Но все они - архаизмы, не приличествующие современному стилю программирования.

Константы

Одними переменными не обойтись, - нужны и константы. Для каждого простого типа есть соответствующие ему константы. Синтаксис построения констант задается так, чтобы по ее значению однозначно можно было приписать ей тип. Поэтому в отличие от переменных константы могут не объявляться, не иметь имени и появляться там, где надо, заданные своими значениями.

Но в VBA можно объявлять именованные константы, задавая в момент объявления значение константы и, возможно, ее тип. Вообще объявление константы во многом напоминает объявление переменной. Однако в этот момент задается значение, которое уже нельзя изменить. Рассмотрим синтаксис оператора Const, используемого

[Public | Private] Const <имя константы> [As type] = <константное выражение>

Вот пример определения классической константы:

Public Const pi As Double = 3.141593

Как и переменные, именованные константы можно объявлять на уровне процедуры или модуля. В первом случае используется только ключевое слово Const, во втором - дополнительно можно задать спецификаторы Public или Private, позволяющие объявить константу общей для всех модулей или закрытой. По умолчанию глобальные константы имеют статус Private. У локальных констант, объявленных в процедурах, областью видимости является процедура. Если не определить тип константы, он будет восстановлен по значению константного выражения. Но иногда лучше это делать самому.

Встроенных констант огромное количество. Есть, например, встроенные константы, связанные с тем или иным приложением, например, Excel или Word. Обычно они имеют соответствующий префикс ( xl, wd и т. д.). Но есть и встроенные константы самого VBA. Они позволяют задавать тип календаря, дни недели, цвет, клавиши и могут применяться в конкретной ситуации, скажем, при работе с окном сообщений. Большинство таких констант начинается с префикса vb, например:

vbWhite, vbSunday, vbKeyEscape, vbOKOnly.
< Лекция 3 || Лекция 4: 1234 || Лекция 5 >
полина есенкова
полина есенкова
Дмитрий Вологжин
Дмитрий Вологжин
Добрый день, прошел тесты с 1 по 9, 10 не сдал, стал читать лекцию и всё пройденные тесты с 1 по 9 сбросились, когда захотел пересдать 10 тест.