
- •Основы алгоритмических языков программирования Понятие о языках программирования. Современные языки программирования высокого уровня
- •Лексические единицы языков программирования
- •Интегрированные среды разработки программ
- •История развития технологии vba
- •Интегрированная среда разработки vba
- •Составные части vba-проекта. Добавление пользовательского кода
- •Вывод отладочных сообщений. Пошаговое выполнение и инструменты отладки
- •Концепция памяти. Переменные и их декларация в языках программирования
- •Структурные операторы в алгоритмических языках программирования
- •Управляющие структуры выбора
- •Данная логическая операция имеет следующую таблицу истинности, в которой «0» соответствует значению false, а «1» – true (табл 1).
- •Остальные логические операторы являются двухоперандными. Операция логического умножения and имеет следующую таблицу истинности (табл 2):
- •Наконец операция логического исключающего или представляется следующей таблицей истинности (табл 4):
- •Реализация управляющих структур выбора в vb
- •Циклические управляющие структуры
- •Реализация циклических управляющих структур в vb
- •Цикл с постусловием имеет похожий синтаксис:
- •Основные положения процедурного программирования
- •Реализация процедурного программирования в Visual Basic
- •Фундаментальные структуры данных
- •Массивы в vb
- •Агрегация разнородных типов. Структурные типы данных
- •Тип данных определяемый пользователем в vb
- •Основы объектно-ориентированного программирования
- •Реализация основных идей объектно-ориентированного программирования в языке vb. Поля и методы. Конструирование объекта класса. Адресная природа объекта класса
- •Свойства и события в vb. Связь объекта класса и его клиентов
- •Интерфейс класса в vb и его наследование
Реализация процедурного программирования в Visual Basic
В языке VB процедура начинается с обязательного ключевого слова SUB за которым следует идентификатор процедуры и список параметров. Формат объявления процедуры в VB имеет следующий вид:
[Private | Public] Sub <procname> [(<param_1> As <type>, … <param_n>] As <type>)
[<statements>]
[Exit Sub]
[<statements>]
End Sub
Необязательные ключевые слова PRIVATEиPUBLICопределяют область видимости процедуры в рамках программного проекта. Подпрограммы в смысле видимости могут быть открытыми или закрытыми. Открытые подпрограммы отмечаются ключевым словомPUBLIC, а закрытыеPRIVATE. Область видимости закрытой подпрограммы ограничена модулем программного проекта, то есть вызов процедуры возможет только в других подпрограммах этого модуля. Напротив, открытые подпрограммы видимы и доступны в рамках программного проекта в целом, то есть в любом модуле программы.
Идентификатор процедуры подчиняется тем же правилам ЯП, что и другие идентификаторы. Процедура может не иметь параметров, но если они имеются, то должны быть перечислены в скобках. Перечисление формальных параметров, выступает подобно внутренним переменным и служит для прохождения из вызывающей подпрограммы значений или как говорят фактических параметров. Приведем пример простой процедуры на VB:
Public Sub MyFirstProc(AParam as Integer)
Dim sMessage as String
If AParam = 0 then
sMessage = "Hello world"
Else
sMessage = "Good bye, world"
End if
For I = 0 to 9
Debug.Print sMessage
Next
End Sub
Как видно из примера подпрограмма проявляет себя как небольшая программа, внутри которой возможно использование всех языковых средств языка: структурных и простых операторов, объявлений переменных и вызов других подпрограмм. Вызов процедуры из другой части программы осуществляется с помощью ключевого слова CALL за которым следует имя процедуры и в скобках список фактических параметров:
Call MyFirstProc (0)
Ключевое слово CALL может быть пропущено, но тогда список фактических параметров должен быть указан без скобок:
MyFirstProc 0
Любая процедура может быть объявлена и без формальных параметров, тогда она не может получать информацию извне, как только с помощью специальных переменных объявленных на уровне модуля или глобальных переменных.
В следующем примере показан способ передачи информации в подпрограммы с использованием переменной, объявленной на уровне модуля. Такая переменная разделяется всеми подпрограммами данного модуля и ее значение может быть доступно любой процедуре или функции в любой момент времени.
Private x As Integer
Sub ParamFreeProc()
x = x + 10
End Sub
Sub CallingRoutine()
x = 10
ParamFreeProc
Debug.Print x
End Sub
Однако такой способ передачи информации сводит на нет преимущества и основную идею процедурной парадигмы программирования – сокрытие внутренней информации от других алгоритмических процессов.
Одним из свойств параметров является способ их передачи в подпрограмму. В VB возможно два типа прохождения параметра: по ссылке, что используется по умолчанию ипо значению. Тип прохождения параметра задается перед идентификатором формального параметра с помощью ключевых слов BYREF (по ссылке) или BYVAL(по значению).
При передаче параметра по ссылке его измененное значение внутри подпрограммы может быть доступно из вызывающей подпрограммы например:
Public Sub MyFirstProc(ByRef AParam as Integer)
AParam = AParam * 100
End Sub
Public Sub MySecondProc
Dim Param as Integer
Param = 10
MyFirstProc Param
Debug.Print Param ' значение Param равно 1000
End Sub
Это связано с тем, что при прохождении параметра по ссылке в вызываемую процедуру передается не значение переменной, а ее адрес, и значение по этому адресу становится доступным для изменения. Ячейка памяти по этому адресу становиться доступной как в вызываемой, так и вызывающей процедурах.
Напротив, при передаче по значению в вызывающую процедуру передается не адрес, а значение, которое копируется по новому адресу внутри процедуры. Таким образом, содержимое передаваемого параметра по значению локализуется в вызываемой подпрограмме. Например:
Public Sub MyFirstProc(ByVal AParam as Integer)
AParam = AParam * 100
End Sub
Public Sub MySecondProc
Dim Param as Integer
Param = 10
MyFirstProc Param
Debug.Print Param ‘ значение Param равно 10
End Sub
С подпрограммами также связано такое важное понятие в программировании как область видимостиивремя жизни(life time) переменной. Если переменная объявлена в теле подпрограммы с помощью ключевого слова DIM, ее значение теряется при окончании работы подпрограммы. При этом говорят, что областью видимости переменной является подпрограмма, а временем ее жизни – время исполнения подпрограммы. При объявлении внутренней переменной с помощью ключевого словаSTATICее значение сохраняется между вызовами подпрограммы. Например:
Public Sub MyStaticProc()
Static X As Integer
Param = X + 10
Debug.Print X
End Sub
Public Sub MyOrdinaryProc()
Dim X As Integer
Param = X + 10
Debug.Print X
End Sub
Повторный вызов первой процедуры приводит к тому, что статическая переменная Xс каждым вызовом увеличивает свое значение на 10. Тогда как многократный вызов второй подпрограммы не изменяет значения ее локальной переменной. Таким образом, всякая переменная объявленная в подпрограмме имеет область видимости ограниченную этой подпрограммой. Однако время жизни статической переменой не ограничено промежутком времени в котором исполняются операторы подпрограммы, и существует до тех пор пока работает программа (адрес переменной не потерян), даже несмотря на то, что видима статическая переменная также только в области подпрограммы. Если перед ключевым словом SUB указано ключевое слово STATIC, тогда все без исключения локальные переменные процедуры становиться статическими независимо от того, как они объявлены.
В противоположность внутренним локальным переменным подпрограмм все переменные объявленные вне их области видимости, т.е. на уровне модуля имеют время жизни ограниченное только временем исполнения программы. Переменная объявленная на уровне модуля с использования ключевого слова DIMстановиться закрытой переменной, также как если бы она была объявлена с помощью ключевого слова PRIVATE
′Закрытые переменные модуля
Private x As Integer
Dim a As Integer
Для того чтобы объявить переменную доступную в других модулях проекта используется ключевое слово PUBLIC
′ Открытая переменная
Public s As Integer
В ходе своей работы процедура может досрочно завершить свое исполнение и передать управление в точку вызова. Для этого в теле процедуры может быть указан специальный оператор завершения – EXIT SUB. Например:
Sub ExitFromProc(ByRef a As Integer)
If a > 50 Then
Exit Sub
End If
a = a + 1
End Sub
Все сказанное выше для процедур справедливо и для другого вида подпрограммам – функций. Однако, в отличие от процедур функция имеет возможность возвращать слева от себя значение скалярного или структурного типа. Объявляется функция аналогичным образом процедуре, однако в объявлении функции может быть указан, хотя это и необязательно, тип возвращаемого функцией значения после ключевого слова AS, которое следует за списком параметров функции.
[Public | Private ] [Static] Function <namefunc> [(arglist)] [As type]
[<statements>] [Exit Function] [<statements>]
End Function
В области видимости любой функции, в отличие от процедуры, неявно определена переменная одноименная идентификатору функции и имеющая тот же тип, что и возвращаемое функцией значение. Приведем пример функции, которая реализует отбрасывание определенного количества значащих зарядов числа с плавающей точкой. Результат выполнения функции передается вовне с помощью неявной переменной совпадающей с именем функции.
Function RoundN(x As Double, n As Byte) As Double
Dim Factor As Long
Factor = 10 ^ n
RoundN = Fix(x * Factor) / Factor
End Function
Применение функций не ограничивается их использованием для реализации простейших численных алгоритмов. С помощью функций построены библиотеки подпрограмм для обработки строк, для работы с датами и др. Функции являются наиболее гибким и мощным инструментом при реализации концепции процедурного программирования и положены в основу базовых идей объектно-ориентированного программирования.
Библиотека времени исполнения языка VisualBasicпредоставляет в распоряжение разработчика программ широчайший набор функций и процедур, которые решают наиболее часто возникающие перед разработчиком задачи, связанные с выполнением математических операций, манипулирования строчными данными и датами. Коротко рассмотрим три эти наиважнейшие группы функций.
К группе математических функций относятся следующие (табл. 5)
Таблица 5. Базовые математические функции библиотеки времени исполнения VB
Обозначение |
Описание |
Abs (<number>) |
Возвращает абсолютное значение числа. В качестве фактического параметра может быть указано любой выражение возвращающее числовое значение. Если параметр принимает значение NULL, то результатом функции является также значение NULL. |
Atn(<number>)
|
Возвращает число с плавающей точкой типа DOUBLE равное арктангенсу аргумента number. Функция возвращает угол в радианах в диапазоне от –π/2 до + π/2. |
Cos(<number>), Sin(<number>), Tan(<number>) |
Возвращают значение типа DOUBLE, соответствующее значению тригонометрических функций косинуса, синуса и тангенса. |
Sqr(<number>) |
Возвращает значение квадратного корня их аргумента. |
Exp(<number>) |
Возвращает значение экспоненциальной функции. |
Log(<number>) |
Возвращает значение логарифмической функции. |
Rnd(<number>) |
Возвращает случайное число с плавающей точкой в диапазоне от 0 до 1. |
Рассмотрим более подробно группу строчных функций и примеры их использования. К наиболее важным функциям в этой группе относятся функции извлечения части строки. К таким функциям принадлежат три функции Mid,Leftи Right.
Функция Midизвлекает некоторую часть строки <string> заданной длины <length>, начиная с некоторого символа в определенной позиции <start>:
Mid (<string>, <start> As Long [, <length> As Long]) As Variant
Функция принимает вариантное значение в качестве первого аргумента и возвращает также вариантный тип. Например:
Dim MyString, FirstWord, LastWord
MyString = "Mid Function Demo" ' Определяем строку
FirstWord = Mid(MyString, 1, 3) ' Возвращает "Mid".
LastWord = Mid(MyString, 14, 4) ' Возвращает "Demo".
Функция Leftподобно функции Mid возвращает подстроку из строки <string>, но только определенное количество символов слева, число которых указано в качестве второго аргумента <length>:
Left (<string>, <length> As Long) As Variant
Как и Mid функция Leftвозвращает вариантный тип данных. Приведем пример использования этой функции:
Dim AnyString, MyStr
AnyString = "Hello World" ' Определяем строку
MyStr = Left(AnyString, 7) ' Возвращает "Hello W".
Еще одной похожей функцией является функция Right, возвращающая заданное число символов, начиная с конца строки
Right (<string>, <length> as Long) as Variant
Для определения числа символов в строке в VB имеется функция Len:
Len (<string> | <variant>) as Long
Например:
MyString = "Hello World" ' инициализация строки
MyLen = Len(MyString) ' возвращает 11
К строчным функциям относится также подгруппа функций конвертирования строчных данных: Hex, UCase,LCase,LTrim,RTrimи Trim.
Функция Hex возвращает строчное представление шестнадцатеричного значения целого числа.
Hex (<number> As Long) As Variant
Например:
Dim MyHex
MyHex = Hex(459) ' Возвращает 1CB
Функции UCase и LCase возвращают содержимое исходной строки преобразованное в верхний или в нижний регистр символов соответственно:
UCase (<string> As Variant) As Variant
LCase (<string> As Variant) As Variant
Например:
Dim AnyCase, LowerCase, UpperCase
AnyCase = "Hello World 1234" ' Преобразуемая строка
UpperCase = UCase(LowerCase) ' Возвращает "HELLO WORLD 1234".
Lowercase = Lcase(UpperCase) ' Возвращает "hello world 1234".
На основе встроенных в библиотеку времени исполнения функций работы со строками могут быть реализованы сколь угодно сложные пользовательские функции обработки строк. Рассмотрим в качестве примера законченную пользовательскую функцию, которая выполняет подсчет числа слов входящих в строку. Функция использует несколько встроенных строчных функций для реализации своей функциональности.
Function CountWords(s) As Integer
Dim WC As Integer, i As Integer, OnASpace As Integer
WC = 0 ' внутренний счетчик
OnASpace = True ' указание того, что встали на пробел
' сканируем все символы строки
For i = 1 To Len(s)
' если встретили пробел
If Mid(s, i, 1) = " " Then
' выбрасываем флаг
OnASpace = True
Else
' если нет, определяем был ли предыдущим пробел
If OnASpace Then
' сброс флага
OnASpace = False
' идет очередное слово
WC = WC + 1
End If
End If
Next i
CountWords = WC
End Function
Группа функций манипулирования датами включает в себя такие функции которые позволяют формировать даты и время в программе, извлекать составные части даты и времени и выполнять простые вычисления над ними.
Функция Now возвращает в виде значения вариантного типа текущую дату и время соответствующую системной дате и времени компьютера.
Dim Today As Date
Today = Now
Переменные типа «дата» хранятся в виде 64-битного числа с плавающей точкой, которое представляет даты в диапазоне от 1 января 100 года до 31 декабря 9999 года. Литерал типа «дата» представляется любой последовательностью символов правильного формата заключенного между символами «#». Формат определяется установками в операционной системе. Например: #09/01/1992# . Поскольку, даты вVBхраниться в виде чисел, это дает дополнительные преимущества, позволяя при необходимости обрабатывать их как числовые значения в выражениях. Например, для получения следующей даты необходимо прибавить к дате единицу:
Dim Tomorrow As Date
Tomorrow = Date() + 1
Для выделения составляющих дат – года, месяца, дня – имеются функции Year, MonthиDayсоответственно. Например:
Dim MyBirthDay As Date
Dim MyDay, MyMonth, MyYear
MyBirthDay = #05/09/1975#
MyDay = Day(MyBirthDay) ' 9
MyMonth = Month(MyBirthDay) ' 5
MyYear = Year(MyBirthDay) ' 1975
VBимеет также встроенную функциюDatePart, которая позволяет выбрать любую составляющую даты и времени, а также выполнить некоторые несложные вычисления
Dim MyBirthDay As Date
Dim MyDay, MyMonth, MyYear
MyBirthDay = #05/09/1975#
MyDay = DatePart("d", MyBirthDay)
MyMonth = DatePart ("m", MyBirthDay)
MyYear = DatePart("yyyy", MyBirthDay)
Функции DateAdd и DateDiff, которые позволяют выполнять сложение и вычитание интервалов дат и времени. Функция DateAddпозволяет добавлять к значению даты и времени любое количество интервалов произвольной длины:
DateAdd(<Interval> As String, <Number> As Double, <Date> As Date) As Date
<Interval> – представляет собой строчную константу, задающую интервал времени, <Number> – задает количество добавляемых интервалов, как положительных, так и отрицательных, <Date> – определяет дату, к которой добавляется указанный интервал. Например, прибавить год к текущей дате можно следующим образом
DateAdd ("yyyy", 1, Date())
или прибавить два часа
DateAdd ("h", 2, Now())
Если требуется определить интервал между двумя датами в днях, месяцах, годах или других интервалах можно воспользоваться функцией DateDiff. Например, для вычисления точного значения возраста:
Dim MyBirthDay As Date
Dim MyAge As Single
MyBirthDay = #5/9/1975#
MyAge = DateDiff("d", MyBirthDay, Now) / 365
В заключение рассмотрения основ процедурного программирования следует отметить, что в VB отсутствует возможность объявления одной подпрограммы внутри другой, т.е. вложенных подпрограмм.