Visual Basic .NET на уроках информатики

Использование модулей и процедур

Разбить на страницы
Показывать лекцию целиком

В этой лекции вы узнаете, как:

  • создавать стандартные модули;
  • объявлять и использовать открытые переменные с глобальной областью видимости;
  • создавать пользовательские функции и процедуры, в целом известные как подпрограммы;
  • вызывать пользовательские процедуры.
  • Изучив программы и выполнив упражнения из лекций с 1 по 9, вы спокойно можете назвать себя средним программистом на Visual Basic. Вы изучили основы программирования на Microsoft Visual Basic .NET, и у вас есть навыки, необходимые для создания полезных утилит. В части 3 этой книги вы узнаете, как писать более сложные программы на Visual Basic. Начнем с изучения того, как создавать стандартные модули.

    Стандартный модуль - это отдельная часть программы, которая содержит глобальные, или открытые, переменные и процедуры типа Function и Sub. В этой лекции вы узнаете, как объявлять и использовать открытые переменные. Вы также узнаете, как создавать ваши собственные процедуры, и как вызывать их. Полученные вами при этом навыки будут особенно полезны при создании больших программных проектов.

    Что нового в Visual Basic .NET?

  • Стандартные модули по-прежнему поддерживаются в Visual Basic .NET, но теперь в них есть ключевые слова Module и End Module, которые обрамляют содержимое модуля в Редакторе кода. Открытые переменные объявляются в стандартных модулях так, как это делалось в Visual Basic 6.
  • Visual Basic .NET продолжает поддерживать ключевые слова Function и Sub, позволяя создавать ваши собственные процедуры. Однако синтаксис объявления и вызова подпрограмм на Visual Basic несколько изменился.
  • Если вы используете для объявления переменных настройку по умолчанию Option Explicit, то при объявлении функций также рекомендуется использовать объявление с указанием конкретного типа. Также рекомендуется указывать все типы в списке аргументов вашей процедуры. Если вы не присваиваете тип с помощью ключевого слова As, Visual Basic будет использовать для параметра тип по умолчанию Object - тип данных, который обычно менее эффективен, чем какой-то конкретный тип.
  • В Visual Basic .NET изменился способ передачи аргументов в процедуры. В Visual Basic 6 механизмом по умолчанию для передачи аргументов была передача по ссылке ( ByRef ), что означало, что изменения в аргументах в рамках процедуры будут переданы обратно в вызывающий код. В Visual Basic .NET способом передачи аргументов по умолчанию является передача по значению ( ByVal ), что означает, что изменения в аргументах в рамках процедуры не передаются обратно в вызывающий код. Вы можете явно указать поведение передаваемых аргументов, используя при объявлении аргументов ключевые слова ByRef или ByVal. Если необходимо, можно указать ByRef, чтобы получить ту же функциональность, которая была в Visual Basic 6.
  • При вызове процедур в Visual Basic .NET вокруг списка аргументов требуется наличие пары круглых скобок. Среда разработки Microsoft Visual Studio добавит их для вас сама - даже если ваши процедуры не требуют никаких аргументов. (Скобки будут добавлены, даже если аргументы не требуются.)
  • Теперь у программистов есть возможность использовать оператор Return, с помощью которого результат вычисления функции передается обратно в вызывающую процедуру. Также поддерживается и старый метод - присвоение значения имени функции.
  • Работа со стандартными модулями

    Когда вы будете писать длинную программу, у вас, скорее всего, будет несколько форм и процедур событий, которые используют одни и те же переменные и процедуры. По умолчанию переменные локальны для процедуры события, что означает, что они могут быть прочитаны и изменены только в той процедуре события, в которой они созданы. Вы также можете объявить переменные в верхней части программного кода формы и присвоить переменным более широкую область видимости, распространяющуюся на всю форму. Однако если вы создаете в проекте несколько форм, переменные, объявленные в верхней части формы, будут доступны только в той форме, в которой они объявлены. Точно также, процедуры событий по умолчанию объявляются как частные ( private ) и являются локальными для той формы, в которой они созданы. Например, нельзя вызвать процедуру события Button1_Click из второй формы с именем Form2, если процедура события объявлена в Form1 как частная.

    Примечание. О том, как добавлять в проект дополнительные формы, речь пойдет в лекции 15.

    Чтобы сделать переменные и процедуры доступными для всех форм и процедур событий проекта, их можно объявить в одном или нескольких стандартных модулях проекта. Стандартный модуль, или модуль кода, - это специальный файл с расширением .vb. Он содержит переменные и процедуры, которые могут быть использованы в любом месте программы. (В предыдущей версии Visual Basic модули имели расширение .bas.) Точно так же, как и в случае с формами, стандартные модули показаны в Solution Explorer (Обозреватель решений) отдельно, и стандартный модуль может быть сохранен на диск с помощью команды Save Module1 As (Сохранить Module1 как) из меню File (Файл) . Однако, в отличие от форм, стандартные модули содержат только код и не имеют интерфейса пользователя.

    Стандартный модуль

    Чтобы создать новый стандартный модуль в программе, щелкните на кнопке Add New Item (Добавить компонент) на стандартной панели инструментов или на команде Add New Item (Добавить компонент) в меню Project (Проект). Откроется диалоговое окно, которое позволит выбрать шаблон Module и запросит у вас имя этого модуля. После этого в Редакторе кода появится новый пустой модуль. Первый стандартный модуль программы имеет имя по умолчанию Module1.vb, но вы можете изменить это имя, щелкнув правой кнопкой мыши на модуле в Обозревателе решений или с помощью команды Save Module1.vb As (Сохранить Module1.vb как) из меню File (Файл). Попробуйте создать в проекте пустой стандартный модуль.

    Создание и сохранение стандартного модуля

  • Запустите Visual Studio, и создайте в папке c:\vbnet03sbs\Гл.10 новый проект с именем My Module Test. Будет создан новый проект, и в Конструкторе Windows Forms появится пустая форма.
  • Щелкните на команде Add New Item (Добавить компонент) в меню Project. Появится диалоговое окно Add New Item (Добавление нового элемента).
  • Выберите шаблон Module. В текстовом поле Name (Имя) появится имя по умолчанию Module1.vb.

    Совет. Диалоговое окно Add New Item (Добавление нового элемента) имеет несколько контейнеров, которые доступны для использования в ваших проектах. Каждый из этих контейнеров имеет различные характеристики и включает начальный код, который поможет вам их использовать. Наиболее часто используемыми контейнерами являются модули, формы Windows и классы. Модули - это контейнеры, в которых можно поместить процедуры общего назначения и объявления переменных, которые доступны для всего проекта. У вас уже есть опыт использования форм Windows, так как каждый новый проект включает форму. За дополнительной информацией о формах обратитесь к лекции 15. Классы нужны для разработки ваших собственных объектов со свойствами, методами и событиями. Дополнительная информация о классах содержится в лекции 17.
  • Щелкните на кнопке Open (Открыть). Visual Basic добавит в ваш проект стандартный модуль с именем Module1. Этот модуль появится в Редакторе кода, как показано на рисунке вверху следующей страницы. Поле списка Method Name (Имя метода) указывает, что открыт раздел общих объявлений стандартного модуля. Переменные и процедуры, объявленные здесь, будут доступны для всего проекта. (В дальнейшем вы попробуете объявить переменные и процедуры.)

  • Чтобы увидеть окно Обозревателя решений, сделайте двойной щелчок мышью на строке заголовка Solution Explorer (Обозреватель решений), а затем выберите Module1.vb. Обозреватель решений будет выглядеть так, как показано ниже.

    Обозреватель решений содержит в списке компонент проекта стандартный модуль, который вы добавили в программу. Имя Module1 указывает на имя файла модуля по умолчанию. (Visual Studio создает файл на диске, когда вы открываете новый модуль в первый раз.) Позже вы измените это имя файла.

  • Чтобы увидеть полный размер окна Properties (Свойства), сделайте двойной щелчок мышью на строке его заголовка. Как показано на рисунке вверху следующей страницы, окно Properties (Свойства)отображает свойства объекта Module1.vb.

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

  • Измените свойство FileName на Math Functions.vb или другое имя файла, которое звучит достаточно выразительно, и нажмите на (Enter). (Здесь вам предоставляется значительная свобода действий, так как этот проект предназначен только для тестирования - вы не будете создавать математические функции или другое "содержимое" модуля.) Имя файла для вашего стандартного модуля в окне Properties (Свойства), в Обозревателе решений, в Редакторе кода и на диске обновится.
  • Верните окна Properties (Свойства)и Обозреватель решений в их нормальные прикрепленные положения, сделав двойной щелчок мышью на их строках заголовков.
  • Как видите, работа со стандартными модулями в проекте очень похожа на работу с формами. В следующем упражнении вы добавите в стандартный модуль открытую переменную.

    Совет. Чтобы удалить стандартный модуль из проекта, щелкните на модуле в Обозревателе решений, а затем на команде Exclude From Project (Исключить из проекта) в меню Project (Проект). Exclude From Project (Исключить из проекта) не удаляет модуль с вашего жесткого диска, но удаляет связь между указанным модулем и текущим проектом. Эффект этой команды можно отменить, щелкнув на команде Add Existing Item (Добавить существующий компонент) в меню файл, выбрав файл, который вы хотите добавить в проект, и затем щелкнув на Open (Открыть).

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

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

    Public RunningTotal As Integer

    объявляет открытую переменную с именем RunningTotal типа Integer.

    В следующих упражнениях демонстрируется использование в стандартном модуле открытой переменной с именем Wins. Вы пересмотрите "Семерку" - первую программу из этой книги - и будете использовать переменную Wins для записи того, сколько раз вы выигрывали за время работы игрового автомата.

    Примечание. "Семерка" - это программа игрового автомата из лекции 2.

    Доработка проекта "Семерка"

  • Чтобы сохранить изменения, щелкните на кнопке Save All (Сохранить все) на стандартной панели инструментов, а затем на команде Close Solution (Закрыть решение) из меню File (Файл) . Команда Close Solution (Закрыть решение) убирает из среды разработки текущее решение и проекты.
  • Откройте проект Track Wins, расположенный в папке c:\vbnet03sbs\ Гл.10\track wins. Этот проект откроется в среде разработки.
  • Если форма не отображается, отобразите ее сейчас. Вы увидите следующий интерфейс пользователя.

    Решение Track Wins - это та же самая программа игрового автомата, которую вы создали в лекции 2. Она позволяет пользователю щелкать на "вращающей" кнопке и отображать в трех полях вывода чисел "случайные" числа, и если в одном из этих полей появится число "7", компьютер выдаст звуковой сигнал и отобразит растровое изображение, показывающее старинный рисунок выплаты денег. Я просто переименовал в этой лекции решение "Семерка", чтобы не изменять его оригинальную версию.

  • Чтобы запустить программу, щелкните на кнопке Start (Начать) на стандартной панели инструментов.
  • Щелкните шесть или семь раз на кнопке Крутить, а затем на кнопке Выход. Вы выиграете первые пять игр (в каждой из них появится число "7"), а затем удача покинет вас. Если помните, каждый раз, когда вы щелкаете на кнопке Крутить, программа для генерации трех случайных чисел использует функцию Rnd. Если одно из этих чисел равно "7", то процедура события кнопки Крутить ( Button1_Click ) отображает картинку выплаты денег и подает звуковой сигнал.
  • Теперь, чтобы расширить эту программу, вы должны отредактировать форму и добавить в проект стандартный модуль.

    Добавление стандартного модуля

  • Откройте форму проекта Track Wins.
  • Щелкните на элементе управления Label в окне области элементов, а затем создайте под меткой Счастливая семерка новую прямоугольную метку.
  • Установите для новой метки и формы свойства, приведенные в следующей таблице. Чтобы облегчить идентификацию новой метки в коде программы, необходимо изменить имя объекта этой метки на lblWins.

    Объект Свойство Установка
    Label5 Font Arial, Bold Italic (Жирный курсив), 12-point (12 пунктов)
    ForeColor Green (на закладке Custom)
    Name lblWins
    Text "Выигрышей: 0"
    TextAlign MiddleCenter
    Form1 Text "Счастливая семерка"

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

    Теперь вы должны добавить в проект новый стандартный модуль.

  • Щелкните на команде Add New Item (Добавить компонент) в меню Project (Проект), выберите шаблон Module, а затем щелкните на Open (Открыть). В Редакторе кода появится модуль с именем Module1.vb.
  • Переместите курсор на пустую строку между операторами Module Module1 и End Module, введите Public Wins As Short, а затем нажмите на (Enter). Этот оператор программы объявляет в программе открытую целочисленную переменную типа Short. Он идентичен обычным объявлениям переменных, которые вы делаете в коде ваших программ, за исключением ключевого слова Public вместо ключевого слова Dim. При запуске программы каждая процедура события этой программы получит доступ к этой переменной. Ваш стандартный модуль должен выглядеть примерно так.

  • В Обозревателе решений щелкните на Form1.vb, далее на кнопке View Designer (Просмотреть конструктор), а затем сделайте двойной щелчок на кнопке Крутить. В Редакторе кода появится процедура события Button1_Click для кнопки Крутить.
  • Введите в этой процедуре события после оператора Beep() следующие операторы:

    Wins = Wins + 1
    lblWins.Text = "Выигрышей: "  Wins

    Это та часть кода программы, которая увеличивает открытую переменную Wins, если при "вращении" появляется "7". Второй оператор использует оператор конкатенации (), с помощью которого присваивает объекту lblWins строку в формате Выигрышей: X, где X - это число выигрышей. Законченная процедура события выглядит так.

  • Чтобы сохранить все изменения на диске, щелкните на кнопке Save All (Сохранить все) на стандартной панели инструментов.

    Примечание. Готовая программа называется Final Track Wins и расположена в папке c:\vbnet03sbsГл.10\final track wins.

    Опиция Save All (Сохранить все) сохраняет изменения не только в модуле, но и в форме и в процедурах событий.

  • Чтобы запустить программу, щелкните на кнопке Start (Начать).
  • Щелкните 10 раз на кнопке Крутить. Метка Выигрышей: отслеживает ваши выигрыши. Каждый раз, когда вы выигрываете, она увеличивается на 1. За 10 "вращений" вы выигрываете шесть раз, как показано на рисунке ниже.

  • Чтобы выйти из программы, щелкните на кнопке Закрыть.
  • Открытые переменные и переменные форм

    В предыдущем упражнении вы использовали открытую переменную для хранения количества выигрышей в программе игрового автомата. В качестве альтернативы можно объявить переменную Wins в форме в верхней части кода программы формы. Обе методики приведут к одному и тому же результату, так как и открытая переменная, и переменная, объявленная в области общих объявлений формы, имеют область видимости, распространяющуюся на всю форму. Однако открытые переменные отличаются тем, что они сохраняют свои значения во всех формах и стандартных модулях проекта - другими словами, во всех компонентах, которые принадлежат к одному пространству имен. Ключевое слово пространства имен проекта устанавливается автоматически, когда вы в первый раз сохраняете проект. Текст пространства имен можно увидеть или изменить, выбрав проект в Solution Explorer (Обозревателе решений) и щелкнув на команде Properties (Свойства) из меню Project (Проект), а затем проверить или изменить текст в текстовом поле Root Namespace (Корневое пространство имен).

    Открытая переменная Wins была полезна в предыдущей процедуре потому, что она сохраняла свое значение на протяжении всех 10 вызовов процедуры события Button1_Click. Если объявить Wins локально в процедуре события Button1_Click, то эта переменная каждый раз сбрасывалась бы, как это счетчик километража в автомобиле. Использование в стандартном модуле открытой переменной позволяет избежать ненужных сбросов. Открытые переменные аналогичны счетчику пройденного пути в автомобиле.

    Создание процедур

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

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

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

    Например, представьте программу, которая содержит три механизма печати растровых изображений: команду меню с именем Print, кнопку Печать на панели инструментов и значок принтера с поддержкой drag-and-drop. В каждую из этих трех процедур событий можно поместить одни и те же операторы печати, а можно обрабатывать запросы на печать из всех трех источников с помощью одной процедуры в стандартном модуле. Процедуры общего назначения экономят время написания программы, снижают вероятность ошибок, уменьшают размер программы, упрощают сопровождение и повышают читаемость процедур событий.

    Преимущества процедур общего назначения

    Процедуры общего назначения предоставляют следующие преимущества:

  • позволяют связать часто используемую группу операторов программы со знакомым именем;
  • устраняют повторяющиеся строки. Вы можете один раз определить процедуру и заставить вашу программу выполнять ее любое количество раз;
  • делают программы более читаемыми. Программу, разбитую на набор частей, воспринимать легче, чем программу, сделанную в виде одного большого фрагмента;
  • упрощают разработку программы. Программы, разделенные на логические единицы, легче разрабатывать, писать и отлаживать. Если вы пишете программу в группе разработчиков, то вы можете обмениваться процедурами и модулями, а не целыми программами;
  • могут повторно использоваться в других проектах и решениях. Можно легко встроить процедуры из стандартного модуля в другие программные проекты;
  • расширяют язык Visual Basic. Зачастую процедуры могут выполнять задачи, которые не могут быть выполнены отдельными ключевыми словами Visual Basic.
  • Подпрограмма типа Function

    Подпрограмма типа Function - это группа операторов, расположенных между оператором Function и оператором End Function. Операторы в функции выполняют осмысленную работу - обычно обрабатывают текст, введенные пользователем данные или вычисляют числовое значение. Вы вызываете функцию в программе, поместив в оператор программы имя этой функции и все требуемые для нее аргументы. Аргументы - это данные, используемые для работы функции, и они должны быть заключены в круглые скобки и разделены запятыми. В целом использование подпрограммы типа Function в точности совпадает с использованием встроенных функций или методов, таких, как Int, Rnd или FromFile.

    Совет. Функции, объявленные в стандартном модуле, по умолчанию являются открытыми. Это позволяет использовать их в любой процедуре события.

    Синтаксис функций

    Базовый синтаксис функции имеет следующий вид:

    Function название_функции ([аргументы]) As тип
    	операторы_функции
    	[Return значение]
    End Function

    Важными являются следующие синтаксические элементы.

  • название_функции - это имя создаваемой вами функции.
  • As тип - это пара ключевых слов, которые определяют возвращаемый тип функции. (В Visual Basic 6 указание конкретного типа было необязательно, но в Visual Basic .NET оно крайне рекомендуется.)
  • аргументы - это необязательный список аргументов (разделенных запятыми), используемых в данной функции. Каждый аргумент должен быть объявлен с указанием конкретного типа данных. (По умолчанию Visual Basic добавляет к каждому аргументу ключевое слово ByVal, которое указывает на то, что в функцию через данный аргумент передается копия значения, и все изменения значения этого аргумента не будут возвращены в вызывающий код.)
  • операторы_функции - это блок операторов, который выполняет работу функции. Первые операторы в этой функции обычно объявляют локальные переменные, которые будут использоваться только внутри этой функции, а остальные операторы выполняют работу функции.
  • Return - это новый оператор Visual Basic .NET. Он позволяет указать, когда нужно выйти из блока кода функции, чтобы возвратить значение в вызывающую программу, и каково это возвращаемое значение. Когда выполняется оператор Return, происходит выход из функции, так что если после оператора Return стоят другие операторы, они не будут выполнены. (В качестве альтернативы можно использовать синтаксис Visual Basic 6 и возвращать значение в вызывающий код, присвоив значение имени функции FunctionName.)
  • Квадратные скобки ([]) указывают на необязательные элементы синтаксиса. Visual Basic требует, чтобы эти элементы не были заключены в квадратные скобки.

    Функции всегда возвращают значение в вызывающий код через свое имя функции. По этой причине последний оператор функции часто является выражением присвоения, которое помещает окончательный результат вычислений функции в имя функции. Например, процедура Function с именем TotalTax вычисляет государственные и городские налоги для указанной суммы, а затем присваивает результат имени TotalTax, как показано ниже:

    Function TotalTax(ByVal Cost as Single) As Single
    	Dim StateTax, CityTax As Single
    	StateTax = Cost * 0.05 'Государственный налог 5%
    	CityTax = Cost * 0.015 'Городской налог 1.5%
    	TotalTax = StateTax + CityTax
    End Function

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

    Function TotalTax(ByVal Cost as Single) As Single
    	Dim StateTax, CityTax As Single
    	StateTax = Cost * 0.05 'Государственный налог 5%
    	CityTax = Cost * 0.015 'Городской налог 1.5%
    	Return StateTax + CityTax
    End Function

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

    Вызов подпрограммы типа Function

    Чтобы вызвать TotalTax в процедуре события, используйте оператор, аналогичный следующему:

    lblTaxes.Text = TotalTax(500)

    Этот оператор вычисляет общую сумму налогов, взимаемых с $500, а затем присваивает результат свойству Text объекта lblTaxes. Функция TotalTax также может принимать переменную в качестве аргумента, как показано в следующих операторах:

    Dim TotalCost, SalesPrice As Single
    SalesPrice = 500
    TotalCost = SalesPrice + TotalTax(SalesPrice)

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

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

    В следующем упражнении вы добавите в программу "Семерка" функцию, которая будет вычислять долю выигрышей в игре, т.е. процентное выражение игр, в которых появляется хотя бы одна семерка. Для этого требуется добавить в стандартный модуль функцию с именем HitRate и открытую переменную Spins. Затем вызывать функцию HitRate каждый раз при щелчке на кнопке Крутить. Результаты будут отображаться в новой метке на форме, которую вы создадите.

    Функция для вычисления соотношения выигрышей и проигрышей

  • Отобразите форму программы "Семерка". Появится интерфейс пользователя нашего игрового автомата.
  • Создайте с помощью элемента управления Label новую метку под меткой Wins. Установите для этой метки следующие свойства:

    Объект Свойство Установка
    Label5 Font Arial, Bold Italic (Жирный курсив), 12-point (12 пунктов)
    ForeColor Red (на закладке Custom)
    Name lblRate
    Text "0.0%"
    TextAlign MiddleCenter

    Ваша формы должна выглядеть примерно так:

  • Щелкните в Обозревателе решений на модуле Module1.vb, а затем на кнопке View Code (Просмотреть код). В Редакторе кода появится стандартный модуль Module1.
  • После оператора Public Wins As Short введите следующее объявление открытой переменной:

    Public Spins As Short

    Теперь стандартный модуль включает две открытые переменные ( Wins и Spins ), которые будут доступны всем процедурам проекта. Spins будет использоваться как счетчик для хранения числа сыгранных вами игр.

  • Добавьте в модуль пустую строку, а затем введите следующее объявление функции:

    Function HitRate(ByVal Hits As Short, ByVal Tries As Short) As String
    	Dim Percent As Single
    	Percent = Hits / Tries
    	Return Format(Percent, "0.0%")
    End Function

    После того, как вы введете первую строку кода функции, Visual Basic автоматически добавит оператор End Function. После ввода остальной части кода функции ваш экран должен стать идентичным следующему.

    Функция HitRate определяет процентное соотношение выигрышей, поделив аргумент Hits на аргумент Tries, а затем форматирует представление результата с помощью функции Format. Функция HitRate объявлена как строковая, так как функция Format возвращает строковое значение. Аргументы Hits и Tries - это места хранения двух коротких целых переменных, которые передаются в функцию при ее вызове. Функция HitRate является функцией общего назначения и может быть использована с любыми целыми числами или переменными, а не только с Wins и Spins.

  • Снова отобразите форму, а затем сделайте двойной щелчок мышью на кнопке Крутить формы Счастливая семерка, чтобы вывести на экран процедуру события Button1_Click.
  • Под четвертой строкой процедуры события ( Label3.Text = CStr(Int(Rnd() * 10)) ) введите следующий оператор:

    Spins = Spins + 1

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

  • Прокрутите окно Редактора кода вниз, а затем в качестве последней строки процедуры события Button1_Click (между операторами End If и End Sub ) введите следующий оператор:

    lblRate.Text = HitRate(Wins, Spins)

    При вводе функции HitRate обратите внимание, как Visual Studio автоматически отображает имена и типы аргументов только что созданной вами функции HitRate (это очень удобная подсказка).

    Целью этого оператора является вызов функции HitRate с использованием переменных Wins и Spins в качестве ее аргументов. Возвращаемый результат - это процентное соотношение в строковом формате, и это значение при каждой игре присваивается свойству Text метки lblRate формы. Это все, что касается данной задачи!

  • Чтобы сохранить файлы вашего проекта, щелкните на кнопке Save All (Сохранить все).
  • Теперь запустите эту программу.

    Запуск программы "Семерка"

  • Чтобы запустить измененную программу "Семерка", щелкните на кнопке Start (Начать).

    Примечание. Готовая программа Final Track Wins расположена в папке c:\vbnet03sbs\Гл.10\final track wins.
  • Щелкните 10 раз на кнопке Крутить. После того, как вы щелкнете на кнопке Крутить пять раз, число побед останется равным 100.0%. Вы каждый раз выигрываете. Однако если вы продолжите щелкать, то число побед изменится на 83.3%, 71.4%, 75.0% (еще одна победа), 66.7% и 60.0% (всего 6 раз из 10). После 10 игр ваш экран будет выглядеть так, как показано на рисунке ниже.

    Если вы продолжите щелкать, то заметите, что количество выигрышей упадет до 28%. Функция HitRate показывает, что в начале игры вы были слишком удачливы, но затем вам пришлось столкнуться с реальностью.

  • Когда вы закончите работать с программой, щелкните на кнопке Закрыть. Программа остановится, и вернется среда разработки.

    Совет. Чтобы программа выдавала случайные наборы чисел каждый раз, когда вы ее запускаете, поместите в процедуре события Form_Load оператор Randomize. За дополнительными инструкциями обратитесь к разделу "Следующий шаг: внесение изменений в программу" лекции 2.
  • Подпрограмма типа Sub

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

    Синтаксис процедуры Sub

    Базовый синтаксис процедуры Sub имеет вид:

    Sub название_процедуры ([аргументы])
    	операторы_процедуры
    End Sub

    Важными являются следующие синтаксические элементы:

  • название_процедуры - это имя создаваемой вами процедуры Sub ;
  • аргументы - это необязательный список аргументов (разделенных запятыми, если их больше одного), используемых в процедуре Sub. Каждый аргумент должен быть объявлен с указанием конкретного типа данных. (По умолчанию Visual Studio добавляет к каждому аргументу ключевое слово ByVal, которое указывает на то, что в функцию через данный аргумент передается копия значения, и все изменения значения этого аргумента не будут возвращены в вызывающий код.);
  • операторы_процедуры - это блок операторов, который выполняет работу процедуры.
  • При вызове процедуры Sub количество и типы аргументов, передаваемых в процедуру, должны совпадать с количеством и типом аргументов, указанных при объявлении процедуры, и вся группа аргументов должна быть заключена в круглые скобки. Если переменные, передаваемые в процедуру Sub, изменяются при ее выполнении, то обновленные переменные не возвращаются, если процедура не объявляет эти аргументы с помощью ключевого слова ByRef. По умолчанию процедуры Sub объявляются в стандартном модуле открытыми, так что они могут вызываться любой процедурой события проекта.

    Важно! В Visual Basic .NET все вызовы процедур Sub должны содержать после имени процедуры круглые скобки. Если в процедуру не передается ни одного аргумента, то требуется наличие пустых круглых скобок. Это изменение по сравнению с предыдущими версиями Visual Basic, в которых круглые скобки требовались только тогда, когда в процедуру передавался аргумент по значению. Далее в этой лекции вы узнаете о передаче переменных по ссылке и по значению.

    Например, следующая процедура Sub получает строковый аргумент, представляющий имя человека. Если эта процедура Sub объявлена в стандартном модуле, то она может быть вызвана из любой процедуры события программы.

    Sub BirthdayGreeting (ByVal Person As String)
    	Dim Msg As String
    	If Person <> "" Then
    		Msg = "С днем рождения "  Person  "!"
    	Else
    		Msg = "Имя не указано."
    	End If
    	MsgBox(Msg, , "Наилучшие пожелания")
    End Sub

    Процедура BirthdayGreeting получает имя приветствуемого человека через аргумент Person - эта строковая переменная передается при вызове процедуры по значению. Если значение Person не пустое (имеет значение, отличное от null ), то указанное в ней имя используется для создания строки сообщения, которое будет отображено с помощью функции MsgBox. Если аргумент равен null, процедура выводит сообщение "Имя не указано".

    Вызов процедуры типа Sub

    Чтобы вызвать в программе процедуру Sub, укажите имя этой процедуры, а затем список аргументов, требуемых для этой процедуры. Например, чтобы вызвать процедуру BirthdayGreeting, можно ввести следующий оператор:

    BirthdayGreeting("Роберт")

    В этом примере процедура BirthdayGreeting вставляет имя "Роберт" в строку сообщения, и отобразит следующее окно сообщения.

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

    Dim NewName As String
    Do
       NewName = InputBox("Введите имя того, у кого сегодня день рождения.", "Список дней рождения")
       BirthdayGreeting(NewName)
    Loop Until NewName = ""

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

    Использование процедуры Sub для управления вводом данных

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

    Создание процедуры Sub для текстового поля

  • В меню File (Файл) щелкните на команде Close Solution (Закрыть решение). Visual Studio закроет текущий проект (игровой автомат "Семерка").
  • В папке c:\vbnet03sbs\Гл.10 создайте новый проект Windows Application (Приложение Windows) на Visual Basic с именем My Text Box Sub. Будет создан новый проект, и в Конструкторе Windows Forms появится пустая форма.
  • Используя элемент управления TextBox, создайте два текстовых поля, расположенных в центре формы рядом друг с другом. Вы будете использовать эти текстовые поля для хранения имен сотрудников, которых вы будете прикреплять к двум отделам. Сегодня вы будете принимать собственные кадровые решения.
  • Используя элемент управления Label, создайте над этими текстовыми полями две метки. Эти метки будут содержать названия отделов.
  • Используя элемент управления Button, создайте три кнопки, по одной под каждым из текстовых полей, и одну в нижней части формы. Первые две кнопки вы будете использовать для добавления сотрудников в их отделы, последнюю кнопку - для выхода из программы.
  • Установите для объектов формы свойства, приведенные в таблице. Так как текстовые поля будут содержать более одной строки, установите для них свойство Multiline на значение True, а свойство ScrollBars на значение Vertical. Эти установки обычно используются тогда, когда в текстовых полях отображается несколько строк текста. Также необходимо установить их свойства TabStop на значение False, а свойства ReadOnly на значение True, чтобы запретить пользователю изменять информацию.

    Объект Свойство Установка
    TextBox1 Multiline True
    Name txtSales
    ReadOnly True
    ScrollBars Vertical
    TabStop False
    Text (empty)
    TextBox2 Multiline True
    Name txtMkt
    ReadOnly True
    ScrollBars Vertical
    TabStop False
    Text (empty)
    Label1 Font Bold
    Name lblSales
    Text "Продажи"
    Label2 Font Bold
    Name lblMkt
    Text "Маркетинг"
    Button1 Name btnSales
    Text "Добавить имя"
    Button2 Name btnMkt
    Text "Добавить имя"
    Button3 Name btnQuit
    Text "Выход"
    Form1 Text "Включить в состав отдела"
  • Измените размер и положение объектов так, чтобы ваша форма выглядела аналогично рисунку вверху следующей страницы.

    Теперь нужно добавить стандартный модуль и создать процедуру Sub общего назначения с именем AddName.

  • Щелкните на команде Add New Item (Добавить компонент) в меню Project (Проект), выберите шаблон Module, а затем щелкните на Open (Открыть). В Редакторе кода появится новый стандартный модуль.
  • Введите между операторами Module Module1 и End Module следующую процедуру AddName:

    Sub AddName(ByVal Team As String, ByRef ReturnString As String)
    	Dim Prompt, Nm, WrapCharacter As String
    	Prompt = "Введите сотрудника отдела  "  Team  "."
    	Nm = InputBox(Prompt, "Окно ввода")
    	WrapCharacter = Chr(13) + Chr(10)
    	ReturnString = Nm  WrapCharacter
    End Sub

    Эта процедура Sub общего назначения использует для запроса у пользователя имени сотрудника функцию InputBox. Она получает при ее вызове два аргумента: Team, являющийся строкой, содержащей название отдела, и ReturnString, который содержит пустую строковую переменную, которая будет содержать отформатированное имя сотрудника. ReturnString объявлена с ключевым словом ByRef, так что все изменения, сделанные в этом аргументе в процедуре будут переданы через этот аргумент обратно в вызывающий код.

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

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

    Dim SalesPosition As String
    AddName("Продажи", SalesPosition)
    txtSales.Text = txtSales.Text  SalesPosition

    Вызов Sub-процедуры AddName включает один аргумент, передаваемый по значению ("Продажи") и один аргумент, передаваемый по ссылке ( SalesPosition ). Последняя строка использует аргумент, переданный по ссылке для добавления текста в текстовое поле txtSales. Оператор конкатенации () добавляет новое имя в конец текста в этом текстовом поле.

  • Откройте в Редакторе кода раскрывающийся список Class Name (Имя класса) и щелкните на объекте btnMkt, а затем откройте раскрывающийся список Method Name (Имя метода) и щелкните на событии Click. В Редакторе кода появится процедура события btnMkt_Click.
  • Введите в этой процедуре события следующие операторы:

    Dim MktPosition As String
    AddName("Маркетинг", MktPosition)
    txtMkt.Text = txtMkt.Text  MktPosition

    Эта процедура события идентична btnSales_Click, за исключением того, что она посылает в процедуру AddName слово "Маркетинг" и обновляет текстовое поле txtMkt. Имя возвращаемой локальной переменной (MktPosition) было изменено для того, чтобы сделать его интуитивно более понятным.

  • Откройте раскрывающийся список Class Name (Имя класса) и щелкните на объекте btnQuit, а затем откройте раскрывающийся список Method Name (Имя метода) и щелкните на событии Click. В Редакторе кода появится процедура события btnQuit_Click.
  • Введите в процедуре события btnQuit_Click оператор End.
  • Щелкните на кнопке Save All (Сохранить все) стандартной панели инструментов.
  • Теперь запустите программу Text Box Sub.

    Запуск программы Text Box Sub

  • Чтобы запустить программу, щелкните на кнопке Start (Начать) на стандартной панели инструментов.

    Примечание. Готовая программа Text Box Sub лежит в папке c:\vbnet03sbs\Гл.10\text box sub.
  • Щелкните на кнопке Добавить имя под текстовым полем Продажи, а затем введите в поле ввода Мария Палермо. (Можете ввести любое другое имя.) Ваше поле ввода должно выглядеть примерно так.

  • Чтобы добавить это имя в текстовое поле Продажи, щелкните на кнопке OK. Имя появляется в этом текстовом поле.
  • Щелкните на кнопке Добавить имя под текстовым полем Маркетинг, введите в поле ввода Маркетинг имя Александр Петров, а затем нажмите на (Enter). Имя появляется в этом текстовом поле Маркетинг. Ваш экран должен выглядеть примерно так.

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

    При обсуждении подпрограмм Function и Sub вы узнали, что аргументы передаются в процедуры по значению или по ссылке. Использование ключевого слова ByVal указывает, что переменные должны быть переданы в процедуру по значению (тип передачи по умолчанию). Все изменения, сделанные в переменной, переданной по значению, не передаются обратно в вызывающую процедуру. Однако, как вы узнали при написании программы Text Box Sub, использование ключевого слова ByRef указывает, что переменные должны быть переданы в процедуру по ссылке, что означает, что все изменения, сделанные в переменной в рамках процедуры, будут переданы обратно в вызывающий код. Передача по ссылке может дать значительные преимущества, если вы позаботитесь о том, чтобы случайно не изменить переменную в процедуре. Рассмотрим объявление и вызов следующей процедуры Sub:

    Sub CostPlusInterest(ByRef Cost As Single, ByRef Total As Single)
    	Cost = Cost * 1.05 'добавляем 5% к цене:
    	Total = Int(Cost)  'переводим в целое и возвращаем
    End Sub
    .
    .
    .
    Dim Price, TotalPrice As Single
    Price = 100
    TotalPrice = 0
    CostPlusInterest(Price, TotalPrice)
    MsgBox(Price  " плюс 5% получится "  TotalPrice)

    В этом примере программист передает в процедуру CostPlusInterest по ссылке две переменные одинарной точности: Price и TotalPrice. Программист планирует использовать обновленную переменную TotalPrice в последующем вызове MsgBox, но, к сожалению, забыл, что переменная Price в процедуре CostPlusInterest на одном из промежуточных шагов также обновляется. (Так как Price была передана по ссылке, изменения в Cost автоматически приводят к изменениям в Price.) При запуске программы это приводит к следующему некорректному результату.

    Вероятно, программист хотел отобразить следующее сообщение.

    Что использовать: ByVal или ByRef?

    Как же следует исправить показанную выше ошибку в процедуре CostPlusInterest? Простейшим способом является объявление аргумента Cost с помощью ключевого слова ByVal, как показано в следующем операторе программы:

    Sub CostPlusInterest(ByVal Cost As Single, ByRef Total As Single)

    Объявление Cost с использованием ByVal позволяет безопасно изменять в процедуре CostPlusInterest параметр Cost, не передавая эти изменения обратно в вызывающую процедуру. Сохранение объявления Total с помощью ByRef позволяет изменять передаваемую переменную, и в вызывающую процедуру будут переданы только эти изменения. В общем, если вы используете ByRef только тогда, когда это необходимо, в ваших программах будет меньше ошибок.

    Вот некоторые рекомендации о том, когда следует использовать ByVal, а когда - ByRef.

  • Используйте ByVal, когда вы не хотите, чтобы процедура изменяла передаваемую в нее через аргумент переменную.
  • Используйте ByRef, когда хотите позволить процедуре изменять передаваемую в нее переменную.
  • Когда сомневаетесь, используйте ключевое слово ByVal.
  • Краткая справка по лекции 10

    Чтобы Сделайте следующее
    Создать новый модуль Щелкните на кнопке Add New Item (Добавить новый компонент) на стандартной панели инструментов, а затем выберите шаблон Module (Модуль) или щелкните на кнопке Add New Item (Добавить новый компонент) в меню Project (Проект), а затем выберите шаблон Module (Модуль).
    Сохранить модуль под новым именем Выберите модуль в Solution Explorer (Обозревателе решений), щелкните на команде Save Module1.vb As (Сохранить как) в меню File (Файл), а затем укажите новое имя.
    Удалить модуль из программы Выберите модуль в Solution Explorer (Обозревателе решений), а затем щелкните на команде Exclude From Project (Исключить из проекта) в меню Project (Проект).
    Добавить в проект существующий модуль В меню Project (Проект) щелкните на команде Add Existing Item (Добавить существующий компонент).
    Создать открытую переменную Объявите переменную в стандартном модуле между ключевыми словами Module и End Module с помощью ключевого слова Public. Например: Public TotalSales As Integer
    Создать открытую функцию

    Поместите операторы функции в стандартном модуле между ключевыми словами Function и End Function. Функции по умолчанию объявляются как открытые. Например:

    Function HitRate(ByVal Hits As Short, ByVal _
    	Tries As Short) As String
    	Dim Percent As Single
    	Percent = Hits / Tries
    	Return Format(Percent, "0.0%")
    End Function
    Вызвать процедуру типа Function Введите в операторе программы имя функции и все необходимые аргументы и присвойте ее переменной или свойству, имеющим соответствующий тип. Например: lblRate.Text = HitRate(Wins, Spins)
    Создать открытую процедуру типа Sub

    Поместите операторы процедуры в стандартном модуле между ключевыми словами Sub и End Sub. Процедуры Sub по умолчанию объявляются как открытые. Например:

    Sub CostPlusInterest(ByVal Cost As Single, _
    	ByRef Total As Single)
    	Cost = Cost * 1.05
    	Total = Int(Cost)
    End Sub
    Вызвать процедуру типа Sub Введите в операторе программы имя процедуры и все необходимые аргументы. Например: CostPlusInterest(Price, TotalPrice)
    Передать аргумент по значению Используйте при объявлении процедуры ключевое слово ByVal. Например: Sub GreetPerson(ByVal Name As String)
    Передать аргумент по ссылке Используйте при объявлении процедуры ключевое слово ByRef. Например: Sub GreetPerson(ByRef Name As String)
    Страницы:

    В этой лекции вы узнаете, как:

  • создавать стандартные модули;
  • объявлять и использовать открытые переменные с глобальной областью видимости;
  • создавать пользовательские функции и процедуры, в целом известные как подпрограммы;
  • вызывать пользовательские процедуры.
  • Изучив программы и выполнив упражнения из лекций с 1 по 9, вы спокойно можете назвать себя средним программистом на Visual Basic. Вы изучили основы программирования на Microsoft Visual Basic .NET, и у вас есть навыки, необходимые для создания полезных утилит. В части 3 этой книги вы узнаете, как писать более сложные программы на Visual Basic. Начнем с изучения того, как создавать стандартные модули.

    Стандартный модуль - это отдельная часть программы, которая содержит глобальные, или открытые, переменные и процедуры типа Function и Sub. В этой лекции вы узнаете, как объявлять и использовать открытые переменные. Вы также узнаете, как создавать ваши собственные процедуры, и как вызывать их. Полученные вами при этом навыки будут особенно полезны при создании больших программных проектов.

    Что нового в Visual Basic .NET?

  • Стандартные модули по-прежнему поддерживаются в Visual Basic .NET, но теперь в них есть ключевые слова Module и End Module, которые обрамляют содержимое модуля в Редакторе кода. Открытые переменные объявляются в стандартных модулях так, как это делалось в Visual Basic 6.
  • Visual Basic .NET продолжает поддерживать ключевые слова Function и Sub, позволяя создавать ваши собственные процедуры. Однако синтаксис объявления и вызова подпрограмм на Visual Basic несколько изменился.
  • Если вы используете для объявления переменных настройку по умолчанию Option Explicit, то при объявлении функций также рекомендуется использовать объявление с указанием конкретного типа. Также рекомендуется указывать все типы в списке аргументов вашей процедуры. Если вы не присваиваете тип с помощью ключевого слова As, Visual Basic будет использовать для параметра тип по умолчанию Object - тип данных, который обычно менее эффективен, чем какой-то конкретный тип.
  • В Visual Basic .NET изменился способ передачи аргументов в процедуры. В Visual Basic 6 механизмом по умолчанию для передачи аргументов была передача по ссылке ( ByRef ), что означало, что изменения в аргументах в рамках процедуры будут переданы обратно в вызывающий код. В Visual Basic .NET способом передачи аргументов по умолчанию является передача по значению ( ByVal ), что означает, что изменения в аргументах в рамках процедуры не передаются обратно в вызывающий код. Вы можете явно указать поведение передаваемых аргументов, используя при объявлении аргументов ключевые слова ByRef или ByVal. Если необходимо, можно указать ByRef, чтобы получить ту же функциональность, которая была в Visual Basic 6.
  • При вызове процедур в Visual Basic .NET вокруг списка аргументов требуется наличие пары круглых скобок. Среда разработки Microsoft Visual Studio добавит их для вас сама - даже если ваши процедуры не требуют никаких аргументов. (Скобки будут добавлены, даже если аргументы не требуются.)
  • Теперь у программистов есть возможность использовать оператор Return, с помощью которого результат вычисления функции передается обратно в вызывающую процедуру. Также поддерживается и старый метод - присвоение значения имени функции.
  • Работа со стандартными модулями

    Когда вы будете писать длинную программу, у вас, скорее всего, будет несколько форм и процедур событий, которые используют одни и те же переменные и процедуры. По умолчанию переменные локальны для процедуры события, что означает, что они могут быть прочитаны и изменены только в той процедуре события, в которой они созданы. Вы также можете объявить переменные в верхней части программного кода формы и присвоить переменным более широкую область видимости, распространяющуюся на всю форму. Однако если вы создаете в проекте несколько форм, переменные, объявленные в верхней части формы, будут доступны только в той форме, в которой они объявлены. Точно также, процедуры событий по умолчанию объявляются как частные ( private ) и являются локальными для той формы, в которой они созданы. Например, нельзя вызвать процедуру события Button1_Click из второй формы с именем Form2, если процедура события объявлена в Form1 как частная.

    Примечание. О том, как добавлять в проект дополнительные формы, речь пойдет в лекции 15.

    Чтобы сделать переменные и процедуры доступными для всех форм и процедур событий проекта, их можно объявить в одном или нескольких стандартных модулях проекта. Стандартный модуль, или модуль кода, - это специальный файл с расширением .vb. Он содержит переменные и процедуры, которые могут быть использованы в любом месте программы. (В предыдущей версии Visual Basic модули имели расширение .bas.) Точно так же, как и в случае с формами, стандартные модули показаны в Solution Explorer (Обозреватель решений) отдельно, и стандартный модуль может быть сохранен на диск с помощью команды Save Module1 As (Сохранить Module1 как) из меню File (Файл) . Однако, в отличие от форм, стандартные модули содержат только код и не имеют интерфейса пользователя.

    Стандартный модуль

    Чтобы создать новый стандартный модуль в программе, щелкните на кнопке Add New Item (Добавить компонент) на стандартной панели инструментов или на команде Add New Item (Добавить компонент) в меню Project (Проект). Откроется диалоговое окно, которое позволит выбрать шаблон Module и запросит у вас имя этого модуля. После этого в Редакторе кода появится новый пустой модуль. Первый стандартный модуль программы имеет имя по умолчанию Module1.vb, но вы можете изменить это имя, щелкнув правой кнопкой мыши на модуле в Обозревателе решений или с помощью команды Save Module1.vb As (Сохранить Module1.vb как) из меню File (Файл). Попробуйте создать в проекте пустой стандартный модуль.

    Создание и сохранение стандартного модуля

  • Запустите Visual Studio, и создайте в папке c:\vbnet03sbs\Гл.10 новый проект с именем My Module Test. Будет создан новый проект, и в Конструкторе Windows Forms появится пустая форма.
  • Щелкните на команде Add New Item (Добавить компонент) в меню Project. Появится диалоговое окно Add New Item (Добавление нового элемента).
  • Выберите шаблон Module. В текстовом поле Name (Имя) появится имя по умолчанию Module1.vb.

    Совет. Диалоговое окно Add New Item (Добавление нового элемента) имеет несколько контейнеров, которые доступны для использования в ваших проектах. Каждый из этих контейнеров имеет различные характеристики и включает начальный код, который поможет вам их использовать. Наиболее часто используемыми контейнерами являются модули, формы Windows и классы. Модули - это контейнеры, в которых можно поместить процедуры общего назначения и объявления переменных, которые доступны для всего проекта. У вас уже есть опыт использования форм Windows, так как каждый новый проект включает форму. За дополнительной информацией о формах обратитесь к лекции 15. Классы нужны для разработки ваших собственных объектов со свойствами, методами и событиями. Дополнительная информация о классах содержится в лекции 17.
  • Щелкните на кнопке Open (Открыть). Visual Basic добавит в ваш проект стандартный модуль с именем Module1. Этот модуль появится в Редакторе кода, как показано на рисунке вверху следующей страницы. Поле списка Method Name (Имя метода) указывает, что открыт раздел общих объявлений стандартного модуля. Переменные и процедуры, объявленные здесь, будут доступны для всего проекта. (В дальнейшем вы попробуете объявить переменные и процедуры.)

  • Чтобы увидеть окно Обозревателя решений, сделайте двойной щелчок мышью на строке заголовка Solution Explorer (Обозреватель решений), а затем выберите Module1.vb. Обозреватель решений будет выглядеть так, как показано ниже.

    Обозреватель решений содержит в списке компонент проекта стандартный модуль, который вы добавили в программу. Имя Module1 указывает на имя файла модуля по умолчанию. (Visual Studio создает файл на диске, когда вы открываете новый модуль в первый раз.) Позже вы измените это имя файла.

  • Чтобы увидеть полный размер окна Properties (Свойства), сделайте двойной щелчок мышью на строке его заголовка. Как показано на рисунке вверху следующей страницы, окно Properties (Свойства)отображает свойства объекта Module1.vb.

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

  • Измените свойство FileName на Math Functions.vb или другое имя файла, которое звучит достаточно выразительно, и нажмите на (Enter). (Здесь вам предоставляется значительная свобода действий, так как этот проект предназначен только для тестирования - вы не будете создавать математические функции или другое "содержимое" модуля.) Имя файла для вашего стандартного модуля в окне Properties (Свойства), в Обозревателе решений, в Редакторе кода и на диске обновится.
  • Верните окна Properties (Свойства)и Обозреватель решений в их нормальные прикрепленные положения, сделав двойной щелчок мышью на их строках заголовков.
  • Как видите, работа со стандартными модулями в проекте очень похожа на работу с формами. В следующем упражнении вы добавите в стандартный модуль открытую переменную.

    Совет. Чтобы удалить стандартный модуль из проекта, щелкните на модуле в Обозревателе решений, а затем на команде Exclude From Project (Исключить из проекта) в меню Project (Проект). Exclude From Project (Исключить из проекта) не удаляет модуль с вашего жесткого диска, но удаляет связь между указанным модулем и текущим проектом. Эффект этой команды можно отменить, щелкнув на команде Add Existing Item (Добавить существующий компонент) в меню файл, выбрав файл, который вы хотите добавить в проект, и затем щелкнув на Open (Открыть).

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

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

    Public RunningTotal As Integer

    объявляет открытую переменную с именем RunningTotal типа Integer.

    В следующих упражнениях демонстрируется использование в стандартном модуле открытой переменной с именем Wins. Вы пересмотрите "Семерку" - первую программу из этой книги - и будете использовать переменную Wins для записи того, сколько раз вы выигрывали за время работы игрового автомата.

    Примечание. "Семерка" - это программа игрового автомата из лекции 2.

    Доработка проекта "Семерка"

  • Чтобы сохранить изменения, щелкните на кнопке Save All (Сохранить все) на стандартной панели инструментов, а затем на команде Close Solution (Закрыть решение) из меню File (Файл) . Команда Close Solution (Закрыть решение) убирает из среды разработки текущее решение и проекты.
  • Откройте проект Track Wins, расположенный в папке c:\vbnet03sbs\ Гл.10\track wins. Этот проект откроется в среде разработки.
  • Если форма не отображается, отобразите ее сейчас. Вы увидите следующий интерфейс пользователя.

    Решение Track Wins - это та же самая программа игрового автомата, которую вы создали в лекции 2. Она позволяет пользователю щелкать на "вращающей" кнопке и отображать в трех полях вывода чисел "случайные" числа, и если в одном из этих полей появится число "7", компьютер выдаст звуковой сигнал и отобразит растровое изображение, показывающее старинный рисунок выплаты денег. Я просто переименовал в этой лекции решение "Семерка", чтобы не изменять его оригинальную версию.

  • Чтобы запустить программу, щелкните на кнопке Start (Начать) на стандартной панели инструментов.
  • Щелкните шесть или семь раз на кнопке Крутить, а затем на кнопке Выход. Вы выиграете первые пять игр (в каждой из них появится число "7"), а затем удача покинет вас. Если помните, каждый раз, когда вы щелкаете на кнопке Крутить, программа для генерации трех случайных чисел использует функцию Rnd. Если одно из этих чисел равно "7", то процедура события кнопки Крутить ( Button1_Click ) отображает картинку выплаты денег и подает звуковой сигнал.
  • Теперь, чтобы расширить эту программу, вы должны отредактировать форму и добавить в проект стандартный модуль.

    Добавление стандартного модуля

  • Откройте форму проекта Track Wins.
  • Щелкните на элементе управления Label в окне области элементов, а затем создайте под меткой Счастливая семерка новую прямоугольную метку.
  • Установите для новой метки и формы свойства, приведенные в следующей таблице. Чтобы облегчить идентификацию новой метки в коде программы, необходимо изменить имя объекта этой метки на lblWins.

    Объект Свойство Установка
    Label5 Font Arial, Bold Italic (Жирный курсив), 12-point (12 пунктов)
    ForeColor Green (на закладке Custom)
    Name lblWins
    Text "Выигрышей: 0"
    TextAlign MiddleCenter
    Form1 Text "Счастливая семерка"

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

    Теперь вы должны добавить в проект новый стандартный модуль.

  • Щелкните на команде Add New Item (Добавить компонент) в меню Project (Проект), выберите шаблон Module, а затем щелкните на Open (Открыть). В Редакторе кода появится модуль с именем Module1.vb.
  • Переместите курсор на пустую строку между операторами Module Module1 и End Module, введите Public Wins As Short, а затем нажмите на (Enter). Этот оператор программы объявляет в программе открытую целочисленную переменную типа Short. Он идентичен обычным объявлениям переменных, которые вы делаете в коде ваших программ, за исключением ключевого слова Public вместо ключевого слова Dim. При запуске программы каждая процедура события этой программы получит доступ к этой переменной. Ваш стандартный модуль должен выглядеть примерно так.

  • В Обозревателе решений щелкните на Form1.vb, далее на кнопке View Designer (Просмотреть конструктор), а затем сделайте двойной щелчок на кнопке Крутить. В Редакторе кода появится процедура события Button1_Click для кнопки Крутить.
  • Введите в этой процедуре события после оператора Beep() следующие операторы:

    Wins = Wins + 1
    lblWins.Text = "Выигрышей: "  Wins

    Это та часть кода программы, которая увеличивает открытую переменную Wins, если при "вращении" появляется "7". Второй оператор использует оператор конкатенации (), с помощью которого присваивает объекту lblWins строку в формате Выигрышей: X, где X - это число выигрышей. Законченная процедура события выглядит так.

  • Чтобы сохранить все изменения на диске, щелкните на кнопке Save All (Сохранить все) на стандартной панели инструментов.

    Примечание. Готовая программа называется Final Track Wins и расположена в папке c:\vbnet03sbsГл.10\final track wins.

    Опиция Save All (Сохранить все) сохраняет изменения не только в модуле, но и в форме и в процедурах событий.

  • Чтобы запустить программу, щелкните на кнопке Start (Начать).
  • Щелкните 10 раз на кнопке Крутить. Метка Выигрышей: отслеживает ваши выигрыши. Каждый раз, когда вы выигрываете, она увеличивается на 1. За 10 "вращений" вы выигрываете шесть раз, как показано на рисунке ниже.

  • Чтобы выйти из программы, щелкните на кнопке Закрыть.
  • Открытые переменные и переменные форм

    В предыдущем упражнении вы использовали открытую переменную для хранения количества выигрышей в программе игрового автомата. В качестве альтернативы можно объявить переменную Wins в форме в верхней части кода программы формы. Обе методики приведут к одному и тому же результату, так как и открытая переменная, и переменная, объявленная в области общих объявлений формы, имеют область видимости, распространяющуюся на всю форму. Однако открытые переменные отличаются тем, что они сохраняют свои значения во всех формах и стандартных модулях проекта - другими словами, во всех компонентах, которые принадлежат к одному пространству имен. Ключевое слово пространства имен проекта устанавливается автоматически, когда вы в первый раз сохраняете проект. Текст пространства имен можно увидеть или изменить, выбрав проект в Solution Explorer (Обозревателе решений) и щелкнув на команде Properties (Свойства) из меню Project (Проект), а затем проверить или изменить текст в текстовом поле Root Namespace (Корневое пространство имен).

    Открытая переменная Wins была полезна в предыдущей процедуре потому, что она сохраняла свое значение на протяжении всех 10 вызовов процедуры события Button1_Click. Если объявить Wins локально в процедуре события Button1_Click, то эта переменная каждый раз сбрасывалась бы, как это счетчик километража в автомобиле. Использование в стандартном модуле открытой переменной позволяет избежать ненужных сбросов. Открытые переменные аналогичны счетчику пройденного пути в автомобиле.

    Создание процедур

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

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

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

    Например, представьте программу, которая содержит три механизма печати растровых изображений: команду меню с именем Print, кнопку Печать на панели инструментов и значок принтера с поддержкой drag-and-drop. В каждую из этих трех процедур событий можно поместить одни и те же операторы печати, а можно обрабатывать запросы на печать из всех трех источников с помощью одной процедуры в стандартном модуле. Процедуры общего назначения экономят время написания программы, снижают вероятность ошибок, уменьшают размер программы, упрощают сопровождение и повышают читаемость процедур событий.

    Преимущества процедур общего назначения

    Процедуры общего назначения предоставляют следующие преимущества:

  • позволяют связать часто используемую группу операторов программы со знакомым именем;
  • устраняют повторяющиеся строки. Вы можете один раз определить процедуру и заставить вашу программу выполнять ее любое количество раз;
  • делают программы более читаемыми. Программу, разбитую на набор частей, воспринимать легче, чем программу, сделанную в виде одного большого фрагмента;
  • упрощают разработку программы. Программы, разделенные на логические единицы, легче разрабатывать, писать и отлаживать. Если вы пишете программу в группе разработчиков, то вы можете обмениваться процедурами и модулями, а не целыми программами;
  • могут повторно использоваться в других проектах и решениях. Можно легко встроить процедуры из стандартного модуля в другие программные проекты;
  • расширяют язык Visual Basic. Зачастую процедуры могут выполнять задачи, которые не могут быть выполнены отдельными ключевыми словами Visual Basic.
  • Подпрограмма типа Function

    Подпрограмма типа Function - это группа операторов, расположенных между оператором Function и оператором End Function. Операторы в функции выполняют осмысленную работу - обычно обрабатывают текст, введенные пользователем данные или вычисляют числовое значение. Вы вызываете функцию в программе, поместив в оператор программы имя этой функции и все требуемые для нее аргументы. Аргументы - это данные, используемые для работы функции, и они должны быть заключены в круглые скобки и разделены запятыми. В целом использование подпрограммы типа Function в точности совпадает с использованием встроенных функций или методов, таких, как Int, Rnd или FromFile.

    Совет. Функции, объявленные в стандартном модуле, по умолчанию являются открытыми. Это позволяет использовать их в любой процедуре события.

    Синтаксис функций

    Базовый синтаксис функции имеет следующий вид:

    Function название_функции ([аргументы]) As тип
    	операторы_функции
    	[Return значение]
    End Function

    Важными являются следующие синтаксические элементы.

  • название_функции - это имя создаваемой вами функции.
  • As тип - это пара ключевых слов, которые определяют возвращаемый тип функции. (В Visual Basic 6 указание конкретного типа было необязательно, но в Visual Basic .NET оно крайне рекомендуется.)
  • аргументы - это необязательный список аргументов (разделенных запятыми), используемых в данной функции. Каждый аргумент должен быть объявлен с указанием конкретного типа данных. (По умолчанию Visual Basic добавляет к каждому аргументу ключевое слово ByVal, которое указывает на то, что в функцию через данный аргумент передается копия значения, и все изменения значения этого аргумента не будут возвращены в вызывающий код.)
  • операторы_функции - это блок операторов, который выполняет работу функции. Первые операторы в этой функции обычно объявляют локальные переменные, которые будут использоваться только внутри этой функции, а остальные операторы выполняют работу функции.
  • Return - это новый оператор Visual Basic .NET. Он позволяет указать, когда нужно выйти из блока кода функции, чтобы возвратить значение в вызывающую программу, и каково это возвращаемое значение. Когда выполняется оператор Return, происходит выход из функции, так что если после оператора Return стоят другие операторы, они не будут выполнены. (В качестве альтернативы можно использовать синтаксис Visual Basic 6 и возвращать значение в вызывающий код, присвоив значение имени функции FunctionName.)
  • Квадратные скобки ([]) указывают на необязательные элементы синтаксиса. Visual Basic требует, чтобы эти элементы не были заключены в квадратные скобки.

    Функции всегда возвращают значение в вызывающий код через свое имя функции. По этой причине последний оператор функции часто является выражением присвоения, которое помещает окончательный результат вычислений функции в имя функции. Например, процедура Function с именем TotalTax вычисляет государственные и городские налоги для указанной суммы, а затем присваивает результат имени TotalTax, как показано ниже:

    Function TotalTax(ByVal Cost as Single) As Single
    	Dim StateTax, CityTax As Single
    	StateTax = Cost * 0.05 'Государственный налог 5%
    	CityTax = Cost * 0.015 'Городской налог 1.5%
    	TotalTax = StateTax + CityTax
    End Function

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

    Function TotalTax(ByVal Cost as Single) As Single
    	Dim StateTax, CityTax As Single
    	StateTax = Cost * 0.05 'Государственный налог 5%
    	CityTax = Cost * 0.015 'Городской налог 1.5%
    	Return StateTax + CityTax
    End Function

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

    Вызов подпрограммы типа Function

    Чтобы вызвать TotalTax в процедуре события, используйте оператор, аналогичный следующему:

    lblTaxes.Text = TotalTax(500)

    Этот оператор вычисляет общую сумму налогов, взимаемых с $500, а затем присваивает результат свойству Text объекта lblTaxes. Функция TotalTax также может принимать переменную в качестве аргумента, как показано в следующих операторах:

    Dim TotalCost, SalesPrice As Single
    SalesPrice = 500
    TotalCost = SalesPrice + TotalTax(SalesPrice)

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

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

    В следующем упражнении вы добавите в программу "Семерка" функцию, которая будет вычислять долю выигрышей в игре, т.е. процентное выражение игр, в которых появляется хотя бы одна семерка. Для этого требуется добавить в стандартный модуль функцию с именем HitRate и открытую переменную Spins. Затем вызывать функцию HitRate каждый раз при щелчке на кнопке Крутить. Результаты будут отображаться в новой метке на форме, которую вы создадите.

    Функция для вычисления соотношения выигрышей и проигрышей

  • Отобразите форму программы "Семерка". Появится интерфейс пользователя нашего игрового автомата.
  • Создайте с помощью элемента управления Label новую метку под меткой Wins. Установите для этой метки следующие свойства:

    Объект Свойство Установка
    Label5 Font Arial, Bold Italic (Жирный курсив), 12-point (12 пунктов)
    ForeColor Red (на закладке Custom)
    Name lblRate
    Text "0.0%"
    TextAlign MiddleCenter

    Ваша формы должна выглядеть примерно так:

  • Щелкните в Обозревателе решений на модуле Module1.vb, а затем на кнопке View Code (Просмотреть код). В Редакторе кода появится стандартный модуль Module1.
  • После оператора Public Wins As Short введите следующее объявление открытой переменной:

    Public Spins As Short

    Теперь стандартный модуль включает две открытые переменные ( Wins и Spins ), которые будут доступны всем процедурам проекта. Spins будет использоваться как счетчик для хранения числа сыгранных вами игр.

  • Добавьте в модуль пустую строку, а затем введите следующее объявление функции:

    Function HitRate(ByVal Hits As Short, ByVal Tries As Short) As String
    	Dim Percent As Single
    	Percent = Hits / Tries
    	Return Format(Percent, "0.0%")
    End Function

    После того, как вы введете первую строку кода функции, Visual Basic автоматически добавит оператор End Function. После ввода остальной части кода функции ваш экран должен стать идентичным следующему.

    Функция HitRate определяет процентное соотношение выигрышей, поделив аргумент Hits на аргумент Tries, а затем форматирует представление результата с помощью функции Format. Функция HitRate объявлена как строковая, так как функция Format возвращает строковое значение. Аргументы Hits и Tries - это места хранения двух коротких целых переменных, которые передаются в функцию при ее вызове. Функция HitRate является функцией общего назначения и может быть использована с любыми целыми числами или переменными, а не только с Wins и Spins.

  • Снова отобразите форму, а затем сделайте двойной щелчок мышью на кнопке Крутить формы Счастливая семерка, чтобы вывести на экран процедуру события Button1_Click.
  • Под четвертой строкой процедуры события ( Label3.Text = CStr(Int(Rnd() * 10)) ) введите следующий оператор:

    Spins = Spins + 1

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

  • Прокрутите окно Редактора кода вниз, а затем в качестве последней строки процедуры события Button1_Click (между операторами End If и End Sub ) введите следующий оператор:

    lblRate.Text = HitRate(Wins, Spins)

    При вводе функции HitRate обратите внимание, как Visual Studio автоматически отображает имена и типы аргументов только что созданной вами функции HitRate (это очень удобная подсказка).

    Целью этого оператора является вызов функции HitRate с использованием переменных Wins и Spins в качестве ее аргументов. Возвращаемый результат - это процентное соотношение в строковом формате, и это значение при каждой игре присваивается свойству Text метки lblRate формы. Это все, что касается данной задачи!

  • Чтобы сохранить файлы вашего проекта, щелкните на кнопке Save All (Сохранить все).
  • Теперь запустите эту программу.

    Запуск программы "Семерка"

  • Чтобы запустить измененную программу "Семерка", щелкните на кнопке Start (Начать).

    Примечание. Готовая программа Final Track Wins расположена в папке c:\vbnet03sbs\Гл.10\final track wins.
  • Щелкните 10 раз на кнопке Крутить. После того, как вы щелкнете на кнопке Крутить пять раз, число побед останется равным 100.0%. Вы каждый раз выигрываете. Однако если вы продолжите щелкать, то число побед изменится на 83.3%, 71.4%, 75.0% (еще одна победа), 66.7% и 60.0% (всего 6 раз из 10). После 10 игр ваш экран будет выглядеть так, как показано на рисунке ниже.

    Если вы продолжите щелкать, то заметите, что количество выигрышей упадет до 28%. Функция HitRate показывает, что в начале игры вы были слишком удачливы, но затем вам пришлось столкнуться с реальностью.

  • Когда вы закончите работать с программой, щелкните на кнопке Закрыть. Программа остановится, и вернется среда разработки.

    Совет. Чтобы программа выдавала случайные наборы чисел каждый раз, когда вы ее запускаете, поместите в процедуре события Form_Load оператор Randomize. За дополнительными инструкциями обратитесь к разделу "Следующий шаг: внесение изменений в программу" лекции 2.
  • Подпрограмма типа Sub

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

    Синтаксис процедуры Sub

    Базовый синтаксис процедуры Sub имеет вид:

    Sub название_процедуры ([аргументы])
    	операторы_процедуры
    End Sub

    Важными являются следующие синтаксические элементы:

  • название_процедуры - это имя создаваемой вами процедуры Sub ;
  • аргументы - это необязательный список аргументов (разделенных запятыми, если их больше одного), используемых в процедуре Sub. Каждый аргумент должен быть объявлен с указанием конкретного типа данных. (По умолчанию Visual Studio добавляет к каждому аргументу ключевое слово ByVal, которое указывает на то, что в функцию через данный аргумент передается копия значения, и все изменения значения этого аргумента не будут возвращены в вызывающий код.);
  • операторы_процедуры - это блок операторов, который выполняет работу процедуры.
  • При вызове процедуры Sub количество и типы аргументов, передаваемых в процедуру, должны совпадать с количеством и типом аргументов, указанных при объявлении процедуры, и вся группа аргументов должна быть заключена в круглые скобки. Если переменные, передаваемые в процедуру Sub, изменяются при ее выполнении, то обновленные переменные не возвращаются, если процедура не объявляет эти аргументы с помощью ключевого слова ByRef. По умолчанию процедуры Sub объявляются в стандартном модуле открытыми, так что они могут вызываться любой процедурой события проекта.

    Важно! В Visual Basic .NET все вызовы процедур Sub должны содержать после имени процедуры круглые скобки. Если в процедуру не передается ни одного аргумента, то требуется наличие пустых круглых скобок. Это изменение по сравнению с предыдущими версиями Visual Basic, в которых круглые скобки требовались только тогда, когда в процедуру передавался аргумент по значению. Далее в этой лекции вы узнаете о передаче переменных по ссылке и по значению.

    Например, следующая процедура Sub получает строковый аргумент, представляющий имя человека. Если эта процедура Sub объявлена в стандартном модуле, то она может быть вызвана из любой процедуры события программы.

    Sub BirthdayGreeting (ByVal Person As String)
    	Dim Msg As String
    	If Person <> "" Then
    		Msg = "С днем рождения "  Person  "!"
    	Else
    		Msg = "Имя не указано."
    	End If
    	MsgBox(Msg, , "Наилучшие пожелания")
    End Sub

    Процедура BirthdayGreeting получает имя приветствуемого человека через аргумент Person - эта строковая переменная передается при вызове процедуры по значению. Если значение Person не пустое (имеет значение, отличное от null ), то указанное в ней имя используется для создания строки сообщения, которое будет отображено с помощью функции MsgBox. Если аргумент равен null, процедура выводит сообщение "Имя не указано".

    Вызов процедуры типа Sub

    Чтобы вызвать в программе процедуру Sub, укажите имя этой процедуры, а затем список аргументов, требуемых для этой процедуры. Например, чтобы вызвать процедуру BirthdayGreeting, можно ввести следующий оператор:

    BirthdayGreeting("Роберт")

    В этом примере процедура BirthdayGreeting вставляет имя "Роберт" в строку сообщения, и отобразит следующее окно сообщения.

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

    Dim NewName As String
    Do
       NewName = InputBox("Введите имя того, у кого сегодня день рождения.", "Список дней рождения")
       BirthdayGreeting(NewName)
    Loop Until NewName = ""

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

    Использование процедуры Sub для управления вводом данных

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

    Создание процедуры Sub для текстового поля

  • В меню File (Файл) щелкните на команде Close Solution (Закрыть решение). Visual Studio закроет текущий проект (игровой автомат "Семерка").
  • В папке c:\vbnet03sbs\Гл.10 создайте новый проект Windows Application (Приложение Windows) на Visual Basic с именем My Text Box Sub. Будет создан новый проект, и в Конструкторе Windows Forms появится пустая форма.
  • Используя элемент управления TextBox, создайте два текстовых поля, расположенных в центре формы рядом друг с другом. Вы будете использовать эти текстовые поля для хранения имен сотрудников, которых вы будете прикреплять к двум отделам. Сегодня вы будете принимать собственные кадровые решения.
  • Используя элемент управления Label, создайте над этими текстовыми полями две метки. Эти метки будут содержать названия отделов.
  • Используя элемент управления Button, создайте три кнопки, по одной под каждым из текстовых полей, и одну в нижней части формы. Первые две кнопки вы будете использовать для добавления сотрудников в их отделы, последнюю кнопку - для выхода из программы.
  • Установите для объектов формы свойства, приведенные в таблице. Так как текстовые поля будут содержать более одной строки, установите для них свойство Multiline на значение True, а свойство ScrollBars на значение Vertical. Эти установки обычно используются тогда, когда в текстовых полях отображается несколько строк текста. Также необходимо установить их свойства TabStop на значение False, а свойства ReadOnly на значение True, чтобы запретить пользователю изменять информацию.

    Объект Свойство Установка
    TextBox1 Multiline True
    Name txtSales
    ReadOnly True
    ScrollBars Vertical
    TabStop False
    Text (empty)
    TextBox2 Multiline True
    Name txtMkt
    ReadOnly True
    ScrollBars Vertical
    TabStop False
    Text (empty)
    Label1 Font Bold
    Name lblSales
    Text "Продажи"
    Label2 Font Bold
    Name lblMkt
    Text "Маркетинг"
    Button1 Name btnSales
    Text "Добавить имя"
    Button2 Name btnMkt
    Text "Добавить имя"
    Button3 Name btnQuit
    Text "Выход"
    Form1 Text "Включить в состав отдела"
  • Измените размер и положение объектов так, чтобы ваша форма выглядела аналогично рисунку вверху следующей страницы.

    Теперь нужно добавить стандартный модуль и создать процедуру Sub общего назначения с именем AddName.

  • Щелкните на команде Add New Item (Добавить компонент) в меню Project (Проект), выберите шаблон Module, а затем щелкните на Open (Открыть). В Редакторе кода появится новый стандартный модуль.
  • Введите между операторами Module Module1 и End Module следующую процедуру AddName:

    Sub AddName(ByVal Team As String, ByRef ReturnString As String)
    	Dim Prompt, Nm, WrapCharacter As String
    	Prompt = "Введите сотрудника отдела  "  Team  "."
    	Nm = InputBox(Prompt, "Окно ввода")
    	WrapCharacter = Chr(13) + Chr(10)
    	ReturnString = Nm  WrapCharacter
    End Sub

    Эта процедура Sub общего назначения использует для запроса у пользователя имени сотрудника функцию InputBox. Она получает при ее вызове два аргумента: Team, являющийся строкой, содержащей название отдела, и ReturnString, который содержит пустую строковую переменную, которая будет содержать отформатированное имя сотрудника. ReturnString объявлена с ключевым словом ByRef, так что все изменения, сделанные в этом аргументе в процедуре будут переданы через этот аргумент обратно в вызывающий код.

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

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

    Dim SalesPosition As String
    AddName("Продажи", SalesPosition)
    txtSales.Text = txtSales.Text  SalesPosition

    Вызов Sub-процедуры AddName включает один аргумент, передаваемый по значению ("Продажи") и один аргумент, передаваемый по ссылке ( SalesPosition ). Последняя строка использует аргумент, переданный по ссылке для добавления текста в текстовое поле txtSales. Оператор конкатенации () добавляет новое имя в конец текста в этом текстовом поле.

  • Откройте в Редакторе кода раскрывающийся список Class Name (Имя класса) и щелкните на объекте btnMkt, а затем откройте раскрывающийся список Method Name (Имя метода) и щелкните на событии Click. В Редакторе кода появится процедура события btnMkt_Click.
  • Введите в этой процедуре события следующие операторы:

    Dim MktPosition As String
    AddName("Маркетинг", MktPosition)
    txtMkt.Text = txtMkt.Text  MktPosition

    Эта процедура события идентична btnSales_Click, за исключением того, что она посылает в процедуру AddName слово "Маркетинг" и обновляет текстовое поле txtMkt. Имя возвращаемой локальной переменной (MktPosition) было изменено для того, чтобы сделать его интуитивно более понятным.

  • Откройте раскрывающийся список Class Name (Имя класса) и щелкните на объекте btnQuit, а затем откройте раскрывающийся список Method Name (Имя метода) и щелкните на событии Click. В Редакторе кода появится процедура события btnQuit_Click.
  • Введите в процедуре события btnQuit_Click оператор End.
  • Щелкните на кнопке Save All (Сохранить все) стандартной панели инструментов.
  • Теперь запустите программу Text Box Sub.

    Запуск программы Text Box Sub

  • Чтобы запустить программу, щелкните на кнопке Start (Начать) на стандартной панели инструментов.

    Примечание. Готовая программа Text Box Sub лежит в папке c:\vbnet03sbs\Гл.10\text box sub.
  • Щелкните на кнопке Добавить имя под текстовым полем Продажи, а затем введите в поле ввода Мария Палермо. (Можете ввести любое другое имя.) Ваше поле ввода должно выглядеть примерно так.

  • Чтобы добавить это имя в текстовое поле Продажи, щелкните на кнопке OK. Имя появляется в этом текстовом поле.
  • Щелкните на кнопке Добавить имя под текстовым полем Маркетинг, введите в поле ввода Маркетинг имя Александр Петров, а затем нажмите на (Enter). Имя появляется в этом текстовом поле Маркетинг. Ваш экран должен выглядеть примерно так.

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

    При обсуждении подпрограмм Function и Sub вы узнали, что аргументы передаются в процедуры по значению или по ссылке. Использование ключевого слова ByVal указывает, что переменные должны быть переданы в процедуру по значению (тип передачи по умолчанию). Все изменения, сделанные в переменной, переданной по значению, не передаются обратно в вызывающую процедуру. Однако, как вы узнали при написании программы Text Box Sub, использование ключевого слова ByRef указывает, что переменные должны быть переданы в процедуру по ссылке, что означает, что все изменения, сделанные в переменной в рамках процедуры, будут переданы обратно в вызывающий код. Передача по ссылке может дать значительные преимущества, если вы позаботитесь о том, чтобы случайно не изменить переменную в процедуре. Рассмотрим объявление и вызов следующей процедуры Sub:

    Sub CostPlusInterest(ByRef Cost As Single, ByRef Total As Single)
    	Cost = Cost * 1.05 'добавляем 5% к цене:
    	Total = Int(Cost)  'переводим в целое и возвращаем
    End Sub
    .
    .
    .
    Dim Price, TotalPrice As Single
    Price = 100
    TotalPrice = 0
    CostPlusInterest(Price, TotalPrice)
    MsgBox(Price  " плюс 5% получится "  TotalPrice)

    В этом примере программист передает в процедуру CostPlusInterest по ссылке две переменные одинарной точности: Price и TotalPrice. Программист планирует использовать обновленную переменную TotalPrice в последующем вызове MsgBox, но, к сожалению, забыл, что переменная Price в процедуре CostPlusInterest на одном из промежуточных шагов также обновляется. (Так как Price была передана по ссылке, изменения в Cost автоматически приводят к изменениям в Price.) При запуске программы это приводит к следующему некорректному результату.

    Вероятно, программист хотел отобразить следующее сообщение.

    Что использовать: ByVal или ByRef?

    Как же следует исправить показанную выше ошибку в процедуре CostPlusInterest? Простейшим способом является объявление аргумента Cost с помощью ключевого слова ByVal, как показано в следующем операторе программы:

    Sub CostPlusInterest(ByVal Cost As Single, ByRef Total As Single)

    Объявление Cost с использованием ByVal позволяет безопасно изменять в процедуре CostPlusInterest параметр Cost, не передавая эти изменения обратно в вызывающую процедуру. Сохранение объявления Total с помощью ByRef позволяет изменять передаваемую переменную, и в вызывающую процедуру будут переданы только эти изменения. В общем, если вы используете ByRef только тогда, когда это необходимо, в ваших программах будет меньше ошибок.

    Вот некоторые рекомендации о том, когда следует использовать ByVal, а когда - ByRef.

  • Используйте ByVal, когда вы не хотите, чтобы процедура изменяла передаваемую в нее через аргумент переменную.
  • Используйте ByRef, когда хотите позволить процедуре изменять передаваемую в нее переменную.
  • Когда сомневаетесь, используйте ключевое слово ByVal.
  • Краткая справка по лекции 10

    Чтобы Сделайте следующее
    Создать новый модуль Щелкните на кнопке Add New Item (Добавить новый компонент) на стандартной панели инструментов, а затем выберите шаблон Module (Модуль) или щелкните на кнопке Add New Item (Добавить новый компонент) в меню Project (Проект), а затем выберите шаблон Module (Модуль).
    Сохранить модуль под новым именем Выберите модуль в Solution Explorer (Обозревателе решений), щелкните на команде Save Module1.vb As (Сохранить как) в меню File (Файл), а затем укажите новое имя.
    Удалить модуль из программы Выберите модуль в Solution Explorer (Обозревателе решений), а затем щелкните на команде Exclude From Project (Исключить из проекта) в меню Project (Проект).
    Добавить в проект существующий модуль В меню Project (Проект) щелкните на команде Add Existing Item (Добавить существующий компонент).
    Создать открытую переменную Объявите переменную в стандартном модуле между ключевыми словами Module и End Module с помощью ключевого слова Public. Например: Public TotalSales As Integer
    Создать открытую функцию

    Поместите операторы функции в стандартном модуле между ключевыми словами Function и End Function. Функции по умолчанию объявляются как открытые. Например:

    Function HitRate(ByVal Hits As Short, ByVal _
    	Tries As Short) As String
    	Dim Percent As Single
    	Percent = Hits / Tries
    	Return Format(Percent, "0.0%")
    End Function
    Вызвать процедуру типа Function Введите в операторе программы имя функции и все необходимые аргументы и присвойте ее переменной или свойству, имеющим соответствующий тип. Например: lblRate.Text = HitRate(Wins, Spins)
    Создать открытую процедуру типа Sub

    Поместите операторы процедуры в стандартном модуле между ключевыми словами Sub и End Sub. Процедуры Sub по умолчанию объявляются как открытые. Например:

    Sub CostPlusInterest(ByVal Cost As Single, _
    	ByRef Total As Single)
    	Cost = Cost * 1.05
    	Total = Int(Cost)
    End Sub
    Вызвать процедуру типа Sub Введите в операторе программы имя процедуры и все необходимые аргументы. Например: CostPlusInterest(Price, TotalPrice)
    Передать аргумент по значению Используйте при объявлении процедуры ключевое слово ByVal. Например: Sub GreetPerson(ByVal Name As String)
    Передать аргумент по ссылке Используйте при объявлении процедуры ключевое слово ByRef. Например: Sub GreetPerson(ByRef Name As String)
    Вернуться к учебному плану