Мы поможем в написании ваших работ!



ЗНАЕТЕ ЛИ ВЫ?

Структура проекта. Окно Project Explorer.

Поиск

Работа с несколькими модулями

А теперь посмотрите, как выглядит проект предыдущего раздела в окне Project Explorer.

Он имеет такой или такой вид в зависимости от того, нажата или нет правая из трех кнопок на панели окна. В обоих случаях отображается одна и та же информация, а именно тот факт, что проект Project1 состоит из трех модулей: формы Form1, формы Form2 и модуля кода Module1. Только в первом случае для нашего удобства модули одного типа объединены в воображаемые папки.

Каждый из модулей сохраняется на диске в своем файле. Имя файла вы видите в скобках. Щелкая в окне Project Explorer по нужному модулю, а затем по одной из двух кнопок слева на панели окна, мы можем удобно переключаться между различными окнами модулей.

Вы можете удалять модули из проекта, щелкая правой клавишей мыши в окне Project Explorer по ненужному модулю, а затем в открывшемся контекстном меню выбирая Remove. Так, если у вас простой вычислительный проект, вы вообще можете удалить все формы, обойдясь одним только модулем кода. Для ввода информации в компьютер вам достаточно будет использовать InputBox, для вывода - MsgBox, а для вычислений - процедуры в модуле кода.

Работа с несколькими проектами

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

Откройте сначала обычным образом один проект. Чтобы открыть еще и другой, вам нельзя использовать, как вы привыкли, File ® Open Project (открыть проект), так как при этом уже открытый проект закроется. Нужно использовать File ® Add Project (добавить проект). Откроется диалоговое окно, глядя в которое вы должны решить, хотите ли вы добавить в среду разработки новый проект (закладка New) или же один из уже существующих (закладка Existing). Затем выбираете нужный проект и ® Open. Теперь на экране вы можете видеть одновременно все формы и окна кода обоих проектов.

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

Вот как выглядит Project Explorer в среде Visual Basic с двумя проектами:

 

 

Какой из двух проектов будет запускаться, когда вы привычно нажмете кнопку Start на панели инструментов? Вы сами можете это задать, щелкнув правой клавишей мыши в окне Project Explorer по названию нужного проекта, а затем в открывшемся контекстном меню выбрав Set as Start Up. Аналогичным образом можно удалить проект из среды (не с диска), выбрав в этом же контекстном меню Remove Project.

Зоны видимости

Зоны видимости переменных

А теперь поговорим о важном средстве обеспечения удобства и надежности программирования на Visual Basic - о механизме задания зон видимости переменных, процедур и других элементов Visual Basic. В 17.2 мы уже сталкивались с этим механизмом, когда переменные, объявленные внутри процедуры, являлись локальными в процедуре, то есть невидимыми снаружи процедуры. Поэтому их нельзя было использовать в других процедурах модуля. Если вы подзабыли этот раздел, то сейчас перечтите.

Перечли? Хорошо. Для переменных в Visual Basic определены 3 зоны видимости:

  Локальные переменные процедуры Видны только внутри процедуры, в которой они объявлены Объявляются оператором Dimвнутри процедуры
  Локальные переменные модуля Видны везде внутри модуля, в котором они объявлены. Из других модулей не видны Объявляются оператором Dim или Privateв верхней части модуля, снаружи процедур
  Глобальные (общедоступные) переменныепроекта Видны отовсюду из всех модулей проекта Объявляются оператором Publicв верхней части модуля, снаружи процедур

Как видите, первая зона - самая узкая, третья - самая широкая. Пример окна кода:

Public a As Integer 'Глобальная переменная

Private b As Integer 'Локальная переменная модуля

 

Private Sub Command1_Click()

Private c As Integer 'Локальная переменная процедуры

.......

End Sub

С первыми двумя зонами видимости вы знакомы. С третьей зоной сейчас познакомимся. Вот как можно из одного модуля обращаться к глобальным переменным, объявленным в другом модуле. Пусть в нашем проекте созданы две формы: Form1 и Form2. Вот окно кода формы 1:

Public a As Integer

Private Sub Command1_Click()

Form2.Show

a = 10

End Sub

Оператор Public объявляет переменную a как глобальную (или общедоступную), видимую изо всех модулей. Щелкнув по кнопке формы 1, вы присваиваете переменной a значение 10.

Вот окно кода формы 2:

Private Sub Command1_Click()

Debug.Print Form1.a

End Sub

Щелкнув по кнопке формы 2, вы печатаете 10 - правильное значение переменной a.

 

Как видите, для того, чтобы обратиться к переменной, объявленной в другом модуле, необходимо указать хозяина переменной. Visual Basic привык, что у чужих элементов хозяин должен быть указан, если же хозяин не указан, значит элемент "свой". Попробуем вместо Debug.Print Form1.a написать просто Debug.Print a. Поскольку хозяин не указан, Visual Basic поймет, что переменная a "своя", то есть принадлежит форме 2. (Это ничего, что она не объявлена, Visual Basic все равно считает ее существующей.) А поскольку "своей" переменной a ничего не присвоено, то ничего и не будет напечатано. В пошаговом режиме вы увидите, что если в форме 1 значение a равно 10, то в форме 2 значение a равно Empty (a=Empty). По английски это значит "пусто", то есть переменной не было присвоено никакого значения.

 

Итак, если мы хотим, чтобы переменная была видна во всем проекте, мы объявляем ее оператором Public. Такая переменная называется глобальной. Если же мы хотим, чтобы переменная была видна только в своем модуле (была локальной в модуле), мы объявляем ее оператором Dim. Вместо оператора Dim принято использовать оператор Private. По действию они неотличимы, но английский смысл слова Private (частная собственность, вход запрещен) лучше подходит к случаю, поэтому программисты в основном используют его.

Зоны видимости процедур

Процедуры могут быть или глобальными или локальными

Для процедур в Visual Basic определены 2 зоны видимости:

  Локальные процедуры модуля Видны везде внутри модуля, в котором они объявлены. Из других модулей не видны Объявляются оператором Private
  Глобальные (общедоступные) процедурыпроекта Видны из всех модулей проекта Объявляются оператором Public

Вот пример использования глобальной процедуры П2.

Окно кода формы 1:

Private Sub Command1_Click()

Form2.П2

End Sub

Окно кода формы 2:

Public Sub П2()

Debug.Print "Выполнилась процедура П2"

End Sub

Щелчком по кнопке формы 1 мы печатаем текст "Выполнилась процедура П2".

Зоны видимости констант и типов

Для констант в Visual Basic так же, как и для переменных, определены 3 зоны видимости:

  Локальные константы процедуры Видны только внутри процедуры, в которой они объявлены Объявляются оператором Constвнутри процедуры
  Локальные константы модуля Видны везде внутри модуля, в котором они объявлены. Из других модулей не видны Объявляются оператором Const в верхней части модуля, снаружи процедур
  Глобальные (общедоступные) константыпроекта Видны изо всех модулей проекта Объявляются оператором Public Constв верхней части модуля кода (и только в нем).

 

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

Public Enum tip

a

b

End Enum

Тогда в окне кода формы 2 вы можете объявить переменную:

Dim s As tip

Кстати, в определении перечислимого типа можно убрать слово Public. Visual Basic по умолчанию считает перечислимые типы глобальными.

 

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

Затенение

 

Переменные разных модулей или разных процедур вполне могут иметь одинаковые имена. Спрашивается, как Visual Basic определяет, какая из видимых одноименных переменных имеется в виду в каждом конкретном случае? Здесь вступает в действие эффект затенения: из нескольких одноименных переменных всегда имеется в виду более локальная переменная, то есть та, чья зона видимости меньше. То есть переменные, локальные в процедуре, имеют предпочтение перед переменными, локальными в модуле, а те - перед глобальными переменными. В этом есть глубокий смысл. Программист, объявляющий переменные в своей процедуре, может не заботиться о том, что где-то в модуле есть переменные с тем же именем. А программист, объявляющий переменные в своем модуле, может не заботиться о том, что переменные с тем же именем есть где-то в проекте.

Пример: Имеется проект из двух форм. Окно кода формы 1:

Public a As Integer

Private Sub Command1_Click()

Form2.Show

a = 1

End Sub

Окно кода формы 2:

Public a As Integer

Private b As Integer

 

Private Sub Command1_Click()

a = 2

Debug.Print Form1.a 'Печатается 1

Debug.Print a 'Печатается 2

b = 3

Debug.Print b 'Печатается 3

End Sub

 

Private Sub Command2_Click()

Dim a As Integer

Dim b As Integer

a = 4

Debug.Print a 'Печатается 4

b = 5

Debug.Print b 'Печатается 5

End Sub

 

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

Теперь несколько слов о пользе модуля кода. Удобство его в том, что он не является "хозяином". Глобальные переменные, константы, типы, процедуры, определенные в нем, являются всеобщим достоянием и могут употребляться в любых других модулях, не требуя указания "хозяина". Модуль кода и используется как вместилище таких глобальных элементов, нужных в других модулях.

 

Префиксы имен

Пусть в вашем проекте вы придумали кнопке имя Сумма, текстовому полю имя Сумма и переменной тоже имя Сумма. Так делать, конечно, нельзя: все имена перепутаются. Но и отказываться от одинаковых имен тоже никак не хочется, потому что они на ваш взгляд наиболее удачно передают смысл своих обладателей. Для того, чтобы не оказаться в такой ситуации, профессиональные программисты используют префиксы - приставки к именам. У всех элементов одной природы префикс одинаков, у элементов разной природы он разный. В нашем случае кнопка будет иметь имя cmdСумма, текстовое поле - txtСумма, переменная типа Double - dblСумма.

 

Вот какие префиксы рекомендует Microsoft для элементов управления:

 


Check box chk
Combo box, drop-down list box cbo
Command button cmd
Common dialog dlg
Directory list box dir
Drive list box drv
File list box fil
Form frm
Frame fra
Horizontal scroll bar hsb
Image img
ImageList ils
Label lbl
Line lin
List box lst
Menu mnu
Picture box pic
ProgressBar prg
RichTextBox rtf
Shape shp
Slider sld
Text box txt
Timer tmr
Toolbar tlb
TreeView tre
UpDown upd
Vertical scroll bar vsb

 

А такие - для переменных:

 


Boolean bln
Byte byt
Collection object col
Currency cur
Date (Time) dtm
Double dbl
Error err
Integer int
Long lng
Object obj
Single sng
String str
User-defined type udt
Variant vnt

 

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

А теперь о чувстве меры. Некоторые имена, будь то имя переменной, формы или другого элемента, в программе используются очень часто. Если им давать "по науке" длинные имена с префиксами, то текст вашей программы будет очень громоздким. Поэтому никто на вас не обидится, если вы в цикле вместо

intПеременная_цикла = intПеременная_цикла + 1

y(intПеременная_цикла) = 2 * a(intПеременная_цикла)

напишете просто

i = i + 1

y(i) = 2 * a(i)

 

К чему все эти сложности?

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

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

Итак, сделать все переменные глобальными нельзя. Тогда, может быть, сделать их всех локальными? Тоже не получится, так как это крайне затруднит обмен информацией между процедурами и модулями. А без этого обмена проект рассыпется на отдельные процедуры, как карточный домик. Вот и получается, что переменные нужны разные - и глобальные и локальные, и никуда от этого не денешься. Надо разрешать и одноименные переменные. А раз так, то нужны и зоны видимости и эффект затенения.

Встает вопрос: какую зону видимости нам выбрать для каждой конкретной переменной? Объявлять ли ее глобальной, локальной в модуле или локальной в процедуре? Здесь совет один - любую переменную делайте как можно более локальной, пусть ее зона видимости будет как можно меньше. Если ее значение нужно только в одной процедуре и больше нигде, делайте ее локальной в этой процедуре. Если ее значение нужно в нескольких процедурах одного модуля, а в других модулях нет, то делайте ее локальной в этом модуле. И только если значение переменной нужно в нескольких модулях, делайте ее глобальной. Такой подход обеспечит вашему проекту максимальную надежность и удобство в отладке.

 

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

Задача: Переменная равна 3. Нужно увеличить ее на 2 и результат напечатать.

Дадим переменной имя intA. Вот простейшая программа для решения задачи:

Private intA As Integer

Private Sub Command1_Click()

intA = 3

intA = intA + 2

Debug.Print intA

End Sub

Однако простейшая программа нас не устраивает. Нам нужно показать всю прелесть параметров. Для этого мы будем действовать так же, как действовал Том Сойер в книге "Приключения Гекльберри Финна", когда ему нужно было освободить негра Джима из ветхого сарайчика, где того держали взаперти. Вместо того, чтобы просто отпереть дверь имевшимся у него ключом, Том придумал массу ненужных вещей вроде веревочной лестницы, отпиленной ножки кровати и т.п. И все для того, чтобы побег из заточения был обставлен "как положено".

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

Private intA As Integer

 

Private Sub Command1_Click()

intA = 3

П1

П2

End Sub

 

Private Sub П1()

intA = intA + 2

End Sub

 

Private Sub П2()

Debug.Print intA

End Sub

Программа работает. Но этого мало. Будем усложнять дальше. Добавим к нашим процедурам параметры:

Private intA As Integer

 

Private Sub Command1_Click()

intA = 3

П1 intA

П2 intA

End Sub

 

Private Sub П1(intAA As Integer)

intAA = intAA + 2

End Sub

 

Private Sub П2(intAAA As Integer)

Debug.Print intAAA

End Sub

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

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

Если ваша процедура сложная и делает что-нибудь полезное, то вы вполне можете захотеть использовать ее и в других проектах. Но в другом проекте переменные скорее всего имеют другие имена, например, вместо intA там используется intB. В этом случае вам придется переписывать текст процедуры (в нашем конкретном случае везде заменить intA на intB). А переписывать не хочется. В общем, процедура теряет свою универсальность. Чтобы и переписывать не надо было и универсальность не потерять, применяются параметры. Обратите внимание, что нашим процедурам с параметрами абсолютно все равно, что переменная имеет имя intA. Нигде внутри процедуры оно не встречается, поэтому процедура уверенно делает свое дело, каково бы имя ни было. Да и программисту как-то понятней, чем занимается процедура, если он видит в ее заголовке список параметров, да еще и с подробными комментариями. Это лучше, чем глядеть в тексте процедуры на переменную intA и вспоминать, что это, черт возьми, за переменная и в чем ее смысл. В общем, совет такой - с глобальными переменными и локальными переменными модуля работайте по возможности через параметры. Что значит "по возможности"? А то, что некоторые такие переменные буквально пронизывают все процедуры проекта и организовывать для них в каждой процедуре параметры - та овчинка, которая не стоит выделки. Обычно таких переменных бывает немного и их легко просто запомнить.

 



Поделиться:


Последнее изменение этой страницы: 2016-08-12; просмотров: 309; Нарушение авторского права страницы; Мы поможем в написании вашей работы!

infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 18.191.171.121 (0.01 с.)