<<<назад | Часть1 | Часть2 | Часть3 | Часть4 | Часть5 | вперёд>>>

 

Глава 3. Программирование на VISUAL BASIC 6

3.1. АЛФАВИТ

Visual Basic является языком программирования. Как любой другой язык, например, русский, английский или язык программирования Pascal, он имеет свой алфавит, используемый для написания операторов или предложений Visual Basic. Алфавит Visual Basic включает:

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

3.2. ДАННЫЕ

3.2.1. Классификация данных

Данные характеризуются типом и организацией. Тип данных обобщает следующие понятия:

Размещение. Данные и программа в момент выполнения размещаются в оперативной памяти (ОП) ЭВМ, которая состоит из пронумерованных ячеек, каждая из которых вмещает 1 байт данных (1 байт состоит из 8 битов, каждый из которых может содержать элемент двоичных данных - 0 или 1). Номер определенной ячейки называется адресом. Одного байта для хранения данного как правило недостаточно и данное занимает непрерывную последовательность байтов (2, 4, 8 байтов).

Способ представления. Последовательность битов в байтах данного кодирует всю необходимую информацию, определяющую данное. Правила кодирования и их реализация в разных ЭВМ определяют способ представления данного. Так, для числовых данных существует способ представления с фиксированной точкой и с плавающей точкой.

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

В Visual Basic 4 определены следующие типы данных:

В табл. 3.1 приводятся характеристики этих типов данных:

Таблица 3.1

Тип данных

Описание

Диапазон значении

Занимаемая память

Byte

Двоичные данные

От 0 до 255

1 байт

Boolean

Логический

True или False

2 байта

Integer

Целые числа

От -32768 до 32767

2 байта

Long

Целые числа (длинные)

От -2 147 483 648 до +2 147 483 647

4 байта

String (variable-length)

Символьный (переменной длины)

От О до 2000000000 символов

10 байт + длина строки

String (fixed-length

Символьный (фиксированной длины)

От 0 до 2000000000 символов

1 байт на 1 символ

Currency

Число с фиксированной десятичной точкой

От -22337203685477,58 до 922337203685477,58

8 байтов

Date

Дата

От January 1, 100 до December 31, 9999

8 байтов

Object

Объект

 

 

4 байта

Single

Вещественные числа

От± 1.4* Ю-45 до + 3.4*104-38

4 байта

Double

Вещественные числа

От+ 4.94* Ю-324 до+ 1.79* Ю-“308

8 байтов

Variant

Произвольный тип

Любой из перечисленных выше

Зависит от значения

Data (Дата) - определяет дату (месяц, день, год).

Object (Объект) - ссылка на объект (OLE).

String (Строка) - последовательность ASCII-символов.

Саггепсу (Валюта) предназначен для финансовых расчетов и имеет фиксированную точность до четвертого знака после запятой (округляется).

Variant (Варьируемый) способен принимать любые значения (состоят из двух частей: собственно значения и кода, указывающего исходный тип данного).

Под организацией данных понимается независимость отдельных данных (хранятся в отдельных непоследовательных ячейках памяти) или их связанность (хранятся в связанной последовательности ячеек памяти).

Связанными данными в Visual Basic 4 являются массивы (совокупность связанных данных одного типа) и записи (совокупность связанных данных разных типов).

3.2.2. Константы

Константа - данное, значение которого однозначно определяется написанием и не может быть изменено.

Пример:

3.1415926 6.02ЕЗ (значение 60200) 123 “Visual Basic “ “Иванов “

Для хранения постоянных величин Visual Basic позволяет объявить константы, т.е. выделить участки памяти, содержимое которых не меняется (при попытке модификации выдается сообщение об ошибке). Объявление констант осуществляется оператором

[Public | Private] Const имя [As type] = выражение Имя констант принято записывать прописными буквами (правила записи имен см. ниже).

Значения ключевых слов следующие:

Public - константу можно использовать в любых процедурах и функциях;

Private - константу можно использовать только внутри модуля (см. ниже), в котором она определена.

Пример:

Const /V= 3.1415926

Const MY_NAME = “Юра “

Тип константы можно не объявлять (устанавливается на основе значения — Const CODE = 35 автоматически получит тип integer). Однако константа PI в примере может быть любого из трех типов: single, double или currency. По умолчанию принимается тип, занимающий наименьший объём памяти. Поэтому лучше явно указывать тип специальными символами в операторах объявления констант. Используемые символы показаны в таблице:

Символ объявления типа

Тип данных

%

integer

&

long

1

single

#

double

@

currency

$

string

 

Пример:

Const ONE& = / (резервирует 4 байта)

Const ONE# = 1 (резервирует 8 байтов, хранится в виде числа двойной точности с плавающей точкой).

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

vbOKCancel = 1 — аргумент функции MsgBox для вывода в диалоговом окне командных кнопок ОК и Cancel;

vbYesNoCancel = 3 — аргумент функции MsgBox для вывода в диалоговом окне командных кнопок Yes, No, Cancel;

vbOk = 1 — значение, которое возвращает MsgBox, если пользователь щелкнул по кнопке ОК в диалоговом окне;

Полную информацию о встроенных константах можно найти в Object Browser.

Кроме того, в комплекте Visual Basic имеется файл CONSTANT.TXT, содержащий десятки часто используемых констант. Необходимые константы могут быть скопированы в программу. 3.2.3. Имена

Имена используются для обозначения объектов в программе (константа является объектом программы). Правила образования имен:

Примеры:

Правильные имена Неправильные имена StartTime CM*PER*INCH

А2 23В

color File (ключевое слово) • VariableName BMW_360

Хорошим тоном при программировании на любом языке является осмысленный выбор имен для объектов программы (присваивать объектам имена, соответствующие контексту и несущие описательную нагрузку). В качестве примера можно привести имя процедуры обработки события, связанного с щелчком мыши по командной кнопке, запускающей программу btnStart_CUck: первая часть имени состоит из сокращения слова кнопка (button — btn) и слова Start, вторая часть определяет событие — Click.

3.2.4. Оператор объявления

Оператор объявления резервирует в памяти место для хранения данных определенного типа и организации и присваивает ему имя, по которому производится обращение к данным.

Оператор имеет вид:

{Dim | Global} имя [({описатель})} [As [New] тип} [, имя [([описатель])] [As [New]w“n] ] . . .

Dim, Global, As, New — ключевые слова (Global используется для объявления глобальных данных (см. ниже). New используется для создания нового объекта на основе существующих объектов, например формы);

имя — имя объекта (имя переменной, массива);

тип - тип данных;

описатель — определяет организацию данных (например, массива, см. ниже).

Пример:

Dim Name, YourName As String, N As Integer, Money As Currency,

SiirName As String* 15

(переменная SurName определена как символьная фиксированной длины в 15 символов).

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

Visual Basic допускает использование имен без объявления их типа (в этом случае автоматически определяется тип, требующий для размещения минимальной памяти), однако целесообразно и является признаком хорошего тона явно объявлять типы используемых данных.

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

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

Если оператор объявления какой-либо переменной находится внутри процедуры обработки события, то доступ к этой переменной (возможность ее использования) возможен только в рамках данной процедуры. Такая переменная называется локальной (local).

Для того чтобы одна и та же переменная могла использоваться в разных процедурах одной формы, оператор объявления переменных должен быть помещен в раздел общих объявлений (general), доступ к которому открывается щелчком мыши по элементу “general” раскрывающегося списка окна Object формы. Объявленная таким образом переменная имеет статус действующей на уровне модуля (modul-level variable) и может использоваться (доступна) в любой процедуре данной формы. Для того чтобы одна и та же переменная могла использоваться в процедурах разных форм одной программы она должна быть объявлена как глобальная переменная (global variable). Используется ключевое слово Global вместо Dim.

Пример:

Global Name, YourName As String, N As Integer, Money As Currency,

SurName As String* 75

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

В Форме 1 переменная Р объявлена в разделе общих объявлений (general) формы и может быть использована как в Процедуре X, так и в Процедуре Z. Изменение значения переменной в одной из процедур влечет за собой изменение и в другой процедуре.

Объявленные переменные И в Процедуре Х и G в Процедуре Z Формы 1 определены только внутри этих процедур, аналогично переменной G в Процедуре_У Формы 2. Эти переменные определены только в рамках своих процедур. Более того, для одноименных переменных G в Процедуре Z и в Процедуре Y выделяются разные ячейки памяти и изменение значения переменной

G в одной из процедур не влечет изменения значения в другой процедуре.

Переменные А и В определены как глобальные для всей программы и доступны во всех процедурах Формы 1 и Формы 2. Изменение значения переменных в одной из процедур одной из форм влечет изменение значений в других процедурах и формах.

Рассмотренные области действия переменных справедливы и для других объявляемых данных (констант, пользовательских типов данных, массивов и др.).

Как было сказано выше, описания глобальных данных помещаются .в модуль кода. Определения формы и все связанные с ней программы хранятся в отдельном файле с расширением .FRM. Программы, состоящие из нескольких форм и соответственно из нескольких таких файлов, размещаются в файлах модулей кода с расширением. Такие файлы создаются при выборе в меню Insert (Вставить) команды Module (Создать модуль) или при щелчке мыши на одноименной кнопке панели инструментов.

3.2.5. Пользовательские типы данных (записи)

Данные различных типов можно сгруппировать по какому-либо признаку в удобную для использования одну структуру. В ряде языков программирования такие структуры называются записями (records).

Оператор объявления пользовательского типа данных (записи) помещается в модуль и имеет вид:

Type имя записи имя элемента записи [(описатель)} As тип

[имя элемента записи [(описатель)} As тип}

End Type

  Оператор создает указанную структуру данных, но не выделяет под неё память. Память выделяется рассмотренным оператором описания, в котором в качестве типа указывается имя записи (имя пользовательского типа данных).

Пример:

Dim Student_l, Student_2 As Student Описаны два имени (Student_l, Student_2 ), для каждого из которых определены заданные в структуре компоненты (Familia, Name, Voyast, Birthdate, Length, Wegith) и для хранения значений которых выделяется память соответственно заданному типу (длине и способу представления).

Для обращения к конкретному свойству (элементу структуры) определенного объекта используется составная запись

имя переменной.элемент структуры

Например, Student'_]. Birthdate определяет дату рождения студента Student_7.

3.2.6. Массивы

Массив - упорядоченный набор однотипных данных, обозначенный одним именем. Массив может строится из однотипных переменных, однородных пользовательских типов данных (одинаковых записей), однотипных элементов пользовательских типов данных.

Массив объявляется уже рассмотренным оператором

{Dim | Global [ Static) имя [({описатель})} [As [New] тип} [, имя [([описатель])} [As [NewJ/гаил] ] . . . где описатель имеет следующий синтаксис:

[нижняя граница То ]верхняя граница[,[нижняя граница То] верхняя граница] . .

нижняя граница определяет минимальное значение индекса массива (целого типа);

верхняя граница определяет максимальное значение индекса массива (целого типа);

То — ключевое слово.

Количество повторений[нижняя граница То [верхняя граница определяет размерность массива (количество индексов, используемое для определения элементов массива). Максимальное число индексов равно 60.

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

Пример различного способа объявления одного и того же массива:

Объявляется двухмерный массив (два индекса). Нижняя граница обоих индексов равна 0 (принимается по умолчанию). Верхняя граница первого индекса равна 8, второго — 3. Массив состоит из 36 элементов (9*4=36) одинакового типа (вещественный) и каждый элемент занимает 8 байтов.

Границы значений индексов: от —32768 до 32767.

Примеры:

Dim A(—4 То 10} As Integer

Dim B(—99 То —5, —3 То 0) As String

Элементы массива занимают связанную последовательную область в памяти машины. Массив А в примере занимает в памяти машины последовательность из 15 ячеек памяти, каждая из которых имеет длину 2 байта (тип Integer имеет длину 2 байта).

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

В Visual Basic многомерные массивы упорядочиваются в памяти машины так, что быстрее всего меняется левый индекс. Например, двумерный массив (в прикладных математических программах матрицы представляются двумерным массивом) А (2,3), состоящий из 12 элементов, располагается в памяти машины следующим образом: А(0,0), А(1,0), А(2,0), А(0,1), А(1,1), А(2,1), А(0,2), А(1,2), А(2,2), А(0,3), А(1,3), А(2,3) (если данный

массив представляет матрицу, то в памяти машины она упорядочивается по столбцам).

Для рассмотренного пользовательского типа данных (записи) Student можно также объявить массив оператором Dim MasStudent (25) As Student

Объявляется одномерный массив MasStudent, состоящий из 26 элементов, каждый из которых является одной записью:

Type Student

Familia As String * 20 Name As String * 10 Voyast As Integer Birthdate As Double Length As Integer Wegith As Integer End Type

рассмотренной выше. Записи располагаются последовательно в памяти машины и занимают каждая 44 байта. 20 байт занимает Familia (один символ занимает 1 байт), 10 байт - Name, 2 байта -Voyast (целый тип занимает 2 байта), 8 байт - Birthdate (вещественный двойной точности занимает 8 байт) и по 2 байта -Length и Wegith (целый тип).

Элемент пользовательского типа данных (записи) может являться массивом. Например, можно объявить массив записей для хранения результатов экзаменов студентов группы. Туре Rezultat

Familia As String * 20 NameExam (4) As String * /5 RewltExam (4) As Integer End Type Dim Sesia(25) As Reyiltat

Объявлен пользовательский тип данных Rewltat, элементами которого являются Familia фиксированной длины 20 символов (фамилия студента не может состоять более чем из 20 символов), массив NameExam (4) из пяти элементов (число экзаменов в сессии не более 5) для хранения названия экзаменов (название каждого экзамена не может состоять более чем из 15 символов), массив RewltExam (4) из пяти элементов для хранения оценок по каждому экзамену (целого типа). Длина записи Rewltat 105 байтов.

На базе пользовательского типа данных Requital объявлен массив Se<iia(25), каждый элемент которого содержит информацию об экзаменах и оценках для одного студента (не более 26 студентов в группе). Один элемент массива занимает 105 байтов памяти, а весь массив 2730 байт.

В Visual Basic имеется возможность переопределять количество элементов массива в момент выполнения программы, т.е. динамически определять размер массива. Это позволяет эффективно использовать дефицитную оперативную память при создании программ. Для этого используется оператор ReDim (не объявление, а команда, выполняемая при работе программы) в программе

ReDini [Preserve] имя [([описатель})} [, имя [([описатель})}}

Preserve сохраняет данные существующего массива при выполнении оператора (для многомерных массивов можно применять только для правого индекса).

При использовании оператора ReDim в операторе объявления массива не задается размер (объявляется динамический размер (dynamic array)).

В примере объявленный динамическим массив Massl( ) при выполнении программы первый раз определяется состоящим из 10 элементов (Massl(lO)). Далее — состоящим из 25 элементов (Massl(25)). При переопределении нельзя изменять тип.

Элементы объявленного массива могут использоваться в операторах программы в виде

имя массива (значение индекса [значение индекса} ...)

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

Если массив объявлен оператором

Dim A(10,20) As Double,

то для обращения к его элементам в операторах программы можно использовать

А(0,0) A(5,J+!) A(1,K) А(2.5, 9.8) (обращение к элементу А(2,10).

. К элементам массива рассмотренных выше пользовательских типов данных обращение записывается:

MasStitdent(J).Name (обращение к имени j-ro студента массива MasStudent, как к элементу записи Student)

Sesia(Ciirrent).NameExam(2) (обращение к названию экзамена для текущего (current) индекса студента массива Sesia как к третьему элементу массива NameExam, являющегося элементом записи Reviltat}.

Пример.

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

В данном примере три оператора перестановки элементов, операторы изменения значения индекса и проверки условия выполняются несколько раз при разных значениях I (изменяемый параметр). Реализован так называемый “ручной” цикл, т.е. присутствуют операторы задания начального значения параметра, изменения значения параметра, проверки условия невыхода параметра за заданную границу, которые и организуют цикл вычислений.

В заключение следует отметить, что однотипные элементы управления также могут организовываться в виде массивов, что позволяет делать программы более универсальными и компактными. Если при разработке формы двум одинаковым элементам управления присваиваются одинаковые имена, то открывается специальное окно для подтверждения создания массива управляющих элементов. При подтверждении (ответ “Да”), элементы управления организуются в массив и у процедур обработки событий для этих элементов управления появляется параметр — индекс элемента управления. Изменяя значение индекса, одну и ту же процедуру обработки события можно использовать для разных элементов.

В списке свойств элементов управления имеется свойство Index, значение которого определяет индекс данного элемента в массиве. Индексы присваиваются автоматически последовательно при создании на форме нового одинакового элемента управления (первому элементу — 0, второму — 1 и т. д.) Эта последовательность может быть изменена разработчиком формы, но только на этапе создания формы.

3.3. ВЫРАЖЕНИЯ

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

операнд [знак операции операнд} [знак операции операнд] ... где в зависимости от типа выражения используются соответствующие операнды и знаки операций.

3.3.1. Арифметическое выражение

Используются следующие знаки операций:

+ - сложение (2.36+12.5);

* - умножение (3*2);

“ - возведение в степень (1(^2, результат 100, 10*-2, результат 0.01, 25^.5 или 25”(1/2), результат 5);

/ - деление с плавающей точкой (3/2, результат 1.5);

\ - целочисленное деление (3/2, результат 1);

Mod - вычисление Остатка (7Mod4, результат 3). Приоритет выполнения операции (в порядке убывания приоритета): возведение в степень, умножение и деление с плавающей точкой, целочисленное деление, вычисление остатка, сложение и вычитание. Вычисления в выражении производятся слева направо. Скобки изменяют приоритет.

Пример:

14/5*2 = 5.6 - операции одного приоритета выполняются слева направо;

14\5*2 = 1 - умножение имеет более высокий приоритет и при целочисленном делении дробная часть отбрасывается;

27^1/3 = 9 — возведение в степень обладает наивысшим приоритетом;

27-(1/3) = 3 - скобки изменяют последовательность операций.

Операнды выражения:

3.3.2. Логическое выражение

Логические выражения используются в математической логике и их также называют Булевыми выражениями, по имени математика Дж. Буля.

Используются следующие знаки логических операций:

Логические операции объединяют логические величины, которые могут принимать два значения: True (Истина) или False (Ложь). Результат логической операции также принимает одно из двух значений: True (Истина) или False (Ложь).

Результа1 ложческои операции определяется следующей таблицей:

Значения

pciv.im.it ипер.шии

Оперли.1 (А)

Oiicp.iiLi (В)

Nol A

Not В

A And li

A Oi В

A Xoi В

A Eч^ В

A Imp В

Т] нс

True

False

False

Tine

True

False

True

True

False

True

Tmc

False

False

True

True

False

F.ilse

Tme

Pulse

F.ilse

Ti не

False

Tine

True

False

False

False

False

Тше

Tme

False

False

False

Tine

True

Приоритет выполнения операций (в порядке убывания приоритета): Not, And, Or, Xor, Eqv, Imp.

Пример:

True And Not False Or False

Вычисляется Not False, результат — True; далее вычисляется And. результат — True; последним вычисляется Or, результат — True.

Операндами логического выражения являются:

. • выражения отношения;

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

> — больше;

< — меньше;

>= — больше или равно;

<= - меньше или равно;

= — равно;

<> — не равно.

Выражение принимает значение либо True, либо False. Примеры:

3 + 1 > 3 (результат True);

SiirName = “Ивсмов “ (если переменная SiirName имеет значение “ Иванов”, то результат True, в противном случае False);

“А” > “В” (результат False, побитово сравниваются значения кодов символов, код символа “Я” больше кода символа 'A”).

Двойные неравенства для правильного их вычисления необходимо записывать с использованием знаков логических операций. Когда арифметические данные преобразуются к логическому типу, то 0 преобразуется в False, а другие значения преобразуются в True. При преобразовании логического типа к арифметическому, False преобразуется к 0, a True к —1.

Рассмотрим неравенство 23 < А < 543. Хотя синтаксически Visual Basic допускает такую запись, результат в любом случае будет True независимо от значения переменной А. Выражение вычисляется слева направо: 23 < А даст либо True. либо False, т.е. либо —/, либо 0. —/ или 0 всегда меньше 543 и результат будет True. Для того чтобы вычисление было корректным, это двойное неравенство следует записать состоящим из двух операндов и знака логической операции.

Правильная запись двойного неравенства: 23 < A And A< 543 (если использовать Or вместо And, то вычисление также будет некорректно).

Составим логическое выражение для набора условий:

Вначале вычисляется выражение в скобках ( И <= Y And ^<= q) — True, далее слева направо вычисляются Л+ 2 >= Y And д + В > С — False, далее

д*Х + B*Y = D And ( // <= Y And Y <= Q) - False, последней операция Or. которая лает результат — False.

3.3.3. Символьное выражение

В Visual Basic определена одна операция с символьными данными - конкатенация (сцепление), позволяющая объединять несколько строк в одну. Знак операции — “+” или “&”.

Операндами символьного выражения могут быть:

Пример:

NameS = “Иван”

SurName$ = “Иванов”

. Narne$ + SurNameS дает результат “ИванИванов” Следует обратить внимание (см. Пример), что необходимые пробелы нужно расставлять самостоятельно. Visual Basic их не вставляет.

3.4. СТАНДАРТНЫЕ ФУНКЦИИ

В Visual Basic имеется широкий набор встроенных (стандартных) функций, облегчающий написание программ. Имеются математические функции, для обработки строк, для работы с временем и датами, для финансовых расчетов.

Встроенные функции различаются тем, что некоторые воз-вращрют вычисленное значение, другие не возвращают. Обращения к функциям, которые возвращают вычисленное значение, является операндом выражения (в рассмотренном выше выражении

A(I,J+1) * (Cos(B+3.5) + 2 * К 3) + (Р - 3.25) операнд Cos(B+3.5) является обращением к встроенной функции вычисления косинуса угла).

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

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

Для обращения к некоторым встроенным функциям нужно задавать значение аргумента (например, Sin(X+2), где Х+2 выражение, определяющее значение аргумента). Для других встроенных функций аргумент задавать не нужно (например. Now). Примерами математических функций являются:

• • String — создает строку символов;

3.5. ОПЕРАТОРЫ

. Программа на Visual Basic состоит из процедур (любая программа состоит хотя бы из одной процедуры). Процедуры состоят из операторов.

Оператором (Statement) является синтаксически полное описание конкретной команды (аналог предложения на русском или другом языке), которая выражает одно действие или определение.

Одному оператору соответствует одна строка программы. Однако можно использовать разделительный знак двоеточие (:), чтобы поместить больше чем один оператор в строке программы.

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

Строки программы могут, быть обозначены метками (Linelabel) или номерами (Linenumber).

Метка (Label) обозначает следующую строку программы. Метка может включать не более 40 символов (первый обязательно буква) и заканчивается двоеточием(:), не может быть ключевым словом. Метка может начинаться в любой позиции строки, если ей не предшествует никакой символ.

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

Routine: ' метка Num = Num / 2 ' оператор, помеченный меткой Routine:

123 ' Номер строки

Msgbox “Half of your number is “ & Num ' оператор с номером 123 Программу легче читать и отлаживать, если операторы программы снабжены комментариями. Комментарии начинаются с апострофа ('), за которым можно размещать любые замечания в тексте программы. Если комментарии располагается на нескольких строках, то каждую строку нужно начинать с апострофа.

3.5.1. Оператор перехода

Оператор перехода имеет вид GoTo { метка | номер строки}

и вызывает переход к выполнению оператора, с указанной меткой или номером строки. ,

Пример:

GoTo 123 'после этого оператора будет выполняться оператор Msgbox ...

Num = Num / 2

123 ' Номер строки

Msgbox “Половина введенного числа равна “ & Num

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

Другой оператор перехода позволяет перейти к выполнению выделенной группы операторов (так называемая внутренняя процедура). Синтаксис его использования следующий:

GoSub { метка \ номер строки }

{метка : \ номер строки } Return

этот оператор вызывает переход к выполнению группы операторов, начало коюрои указано меткой или номером строки. Последний оператор группы является оператор Return (Return и GoSub — ключевые слова).

Пример:

Sub Form_Click ()

Dim Num ' Объявление переменной.

Num = Input Во\(“ Введите число.”)

GoSub Routine ' Переход к группе операторов (к

' внутренней процедуре).

GoTo Nextparl ' Обход группы операторов (внутренней

'процедуры). Routine: ' Начало группы операторов (внутренней

'процедуры). Num = Num / 2

Return ' Конец группы операторов (выход из внутренней ' процедуры). Nextparl: ' Продолжение программы. Msgbox “Половина введенного числа равна “ & Num End Sub

3.5.2. Оператор присваивания

Оператор присваивания (assignment statement) имеет следующий вид:

[Let] {переменная | элемент массива} = выражение

Переменной или элементу массива в левой части оператора присваивается значение вычисленного выражения в левой части.

Примеры:

С = A(f,J+l) * (Cos(B+3.5) + 2 * К л 3) + (Р - 3.25)

StartTime = Now

1=1+1

Massiv_J(3,4)л 2 - 4*А*С + D

Student_1.Birthdate =DateSerial(1975,6,11) - используется встроенная функция DateSerial для преобразования трех последовательных чисел (год, месяц, число) в дату.

Р = Х+ 2 >=KAnd A + В > С Or А*Х + B*Y=D And (H<=Y And Y<=Q)

Sesia( Current). Name Exam( 2)= “Физика “

При использовании оператора присваивания следует соблюдать следующие правила:

Если в левой части оператора используется переменная или элемент массива символьного типа (String), то выражение в правой части должно быть тоже символьное; Если в левой и правой частях оператора используются арифметические данные (Integer. Long, Single, Double, Currency^ но разных типов, то тип правой части” преобразуется к типу левой части. Результатом присвоения значения вещественной константы 2.5 переменной целого типа (I = 2.5) будет 2 (т.е. в ячейке памяти отведенной для переменной I будет храниться значение 2).

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

Опция Let в операторе используется для присвоения значения одного данного пользовательского типа другому, при условии что типы элементов обоих пользовательских данных совпадают.

3.5.3. Условный оператор

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

If логическое выражение Then then-последователпость [Else else -последовательность} или

If логическое выражение Then

[блок операторов — 1} [Elself логическое выражение Then

[блок операторов — 2] ] [Else

[блок операторов — п] ] End If где If, Then, Elself, Else, End If ключевые слова.

Во второй синтаксической конструкции If и End If являются как бы открывающей и закрывающей скобкой группы операторов, образующих структурный логический оператор.

Then-последователность и else-последовательность имеют вид

{операторы \ [GoTo] номер строки \ GoTo метка } операторы последовательность расположенных на одной строке операторов, разделенных двоеточием.

Пример:

If А > 10 Then A = А + I : В = В + А : С = С + В: GoTo

Vsiavka

If Name = “Иван” Then GoTo 555

If Name = “Иван “ Then 555 (эквивалентно предыдущему оператору)

блок операторов 1, блок операторов 2, ... блок операторов п _ последовательность выполняемых операторов.

Первая синтаксическая конструкция условного оператора обеспечивает альтернативное выполнение then-последователности или else-последовательности в зависимости от значения логического выражения (принимает значение True или False ) If True Then 'эти операторы Else 'эти операторы

выполняются не выполняются 'следующий оператор . If False Then 'эти операторы Else 'эти операторы

не выполняются выполняются ' следующий оператор

Вторая синтаксическая конструкция условного оператора обеспечивает альтернативное выполнение блоков операторов (блок операторов — 1, блок операторов — 2,... блок операторов — п) в зависимости от значений логических выражений (принимает значение True или False ) If True Then

'эти операторы блока выполняются Else эти операторы блока не выполняются End If 'следующий оператор If False Then

'эти операторы блока не выполняются Else 'эти операторы блока

выполняются End If • 'следующий оператор Ключевое слово Elself позволяет объединить функции Else и следующего вложенного If. Примеры показывают эквивалентность, с точки зрения реализуемого алгоритма, двух фрагментов программ

Во втором примере отсутствует повторное вложение If — End If.

Пример программы.

Программа должна определять количество десятичных цифр в вводимом числе от 0 до 1000. Запуск программы осуществляется щелчком мыши по форме (операторы программы помещаются в процедуру обработки события Foim_Click):

Private Sub Form_Click()

Dim X, Y 'объявление переменных . X = InputBox(“Введите число больше 0 и меньше 1000.”)

If X < 10 Then

Y = 1 • 1 цифра. Elself X < 100 Thpn

Y = 2 ' 2 цифры. Else

Y = 3 ' 3 цифры. End If

If Y > 1 Then Unit = “ цифры.” Else Unit = “ цифру.”

MsgBox “Введенное число имеет “ & Y & Unit End Sub

После запуска программы появляется пустая форма Щелчок мыши на форме вызывает появление окна ввода, в котором можно набрать вводимое число и ввести его щелчком мыши по кнопке или клавишей “Enter” . После ввода появляется окно с результатом.

3.5.4. Управляющая структура Select Case

Структура Select Case применяется, когда одна величина участвует в нескольких логических сравнениях и определяет, какой блок операторов будет выполняться Алгоритм такого множественного сравнения можно запрограммировать и с использованием логического структурного оператора, но применение структура Select Case эффективнее

Наиболее часто структура Select Case применяется в тех случаях, когда сравниваемая величина является целым числом (например, для выбора блоков операторов программы в зависимости от выбранной альтернативы диалога) *

Select Case, Case, Case Else, End Select ключевые слова

(Select Case и End Select соответственно оператор начала и конца структуры);

проверяемое выражение — арифметическое или символьное выражение;

список выражении I, список выражении 2...- может иметь одну из следующих форм:

выражение

выражение То выражение

Is знак отношения выражение

Пример:

Select Case Value

Case /, 3

Блок операторов 1

Case 5 То 10

Блок операторов 2

Case 12 Is >= 15

Блок операторов 3

Case Else

Блок операторов 4

End Select

В данном примере проверяемым выражением является значение Value. Если значение Value 1 или 3 (Case /, 3), выполняется Блок операторов I. Если значение Value от 5 до 10 (Case 5 То 10), выполняется Блок операторов 2. Если значение Value равно 12 или больше 15 (Case 12 Is >= 15), выполняется Блок операторов 3. Если значение Value не равно ни одному из указанных значений

^и не принадлежит ни одному из указанных диапазонов, выполняется Блок операторов 4.

Пример программы.

Программа должна определять, является ли вводимый символ большой или малой буквой латинского алфавита или четной или нечетной десятичной цифрой. Проверка символа осуществляется по значению ASClI-кода вводимого символа. Значение ASClI-кода вводимого символа является проверяемым выражением структуры Select Case. В зависимости от значения кода выдается то или иное сообщение (соответствующие блоки Case-операторов. Запуск программы осуществляется щелчком мыши по форме (операторы программы помещаются в процедуру обработки события Form_Click). Для ввода символа и вывода сообщения используются встроенные функции InpupBox и MseBox.

В программе используются всгроенные функции Len (определяет длину строки), Cdbl (преобразует тип исходного выражения в тип Double), Is Numeric (проверяет, является ли символ числом), Asc (преобразует символ и ASCll-код), Спг (преобразует ASCII-код в строку).

После запуска программы появляется пустая форма. Щелчок мыши на форме вызывает появление окна ввода, в котором можно набрать вводимый символ и ввести его щелчком мыши по кнопке или клавишей “Enter". После ввода появляется окно, выводящее характеристику введенного символа

Ввод других символов будет вызывать вывод соответствующих сообщений.

3.5.5. Циклы

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

Для реализации такого рода программ в Visual Basic специальные средства — операторы цикла.

3.5.5.1. Оператор цикла For-Next

Синтаксис оператора следующий:

For параметр цикла = начшьное значение То конечное значение [Step

шаг}

{блок операторов}

[Exit For] [блок операторов^ Next {параметр цик-га {,параметр цик-ш ][, ...]]

где For, To, Exit For, Step, Next ключевые слова. Пара For-Next определяют начало и конец оператора цикла. Операторы между ними (б->ок операторов) повторяются столько раз, сколько определено. задаваемыми начальным значением, конечным значением и

шагом.

Exit For может находится в любом месте между For - Next и используется для прекращения выполнения цикла (управление передается на оператор, который следует сразу за Next) и применяется, например, в логическом операторе, который проверяет альтернативное условие прерывания цикла (например, ошибку).

Параметр цчюш - арифметическая переменная, не может быть элементом массива или элементом пользовательского типа

данных.

Начальное значение, конечное значение и шаг определяют значения, которые принимает параметр цикла при работе программы - на первом шаге параметр цикла принимает начальное значение, после выполнения операторов, входящих в цикл (блок операторов), параметр цикла изменяется на величину шага (выполняется оператор Next), опять выполняются операторы, входящие в цикл, параметр цикла изменяется на величину шага и т. д., пока параметр цикла не примет последовательно все свои

значения.

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

. Операторы, входящие в цикла будут выполняться если:

шаг цикла >= 0 и конечное значение >= начальное значение шаг цикла < 0 и конечное значение <= начальное значение. Пример.

Рассматривается фрагмент программы для нахождения максимального значения элементов одномерного массива из 15 элементов.

Dim В (1 То J5), МахВ As Single 'оператор объявления массива и переменной

МахВ = В(1) 'присвоение начального значения МахВ For /= /To 15 'начало цикла

If B(I) > МахВ Then МахВ = В(1) 'этот оператор выполнится 15 раз

Next / 'конец цикла MsgBox Str(MaxB) 'для вывода результата используется

'встроенная функция MsgBox, в которой 'используется встроенная функция Str 'для преобразования числового значения в строку

При использовании оператора цикла необходимо соблюдать правила:

1. Следует избегать изменения значения параметра цикла в каких-либо операторах внутри цикла.

Оба фрагмента программ эквивалентны, т.е. два цикла могут заканчиваться одним оператором Next.

При выполнении цикла в цикле внутренний цикл выполняется для каждого значения параметра внешнего цикла (в фрагментах программ оператор C(I,J) = A(I) * B(J) выполнится 12 раз со следующей последовательностью индексов: С(1,1), С(1,2), С(1,3), С(1,4), С(2,1), С(2,2), С(2,3), С(2,4), С(3,1), С(3,2), С(3,3),

С(3,4)).

Внутренний (“вложенный”) цикл должен целиком содержаться во внешнем цикле:

Число вложенных циклов не ограничено.

Пример.

Рассматривается фрагмент программы для формирования вектора А(4). элементами которою являются суммы столбцов матрицы В (5,4).

Dim А(1 То 4), В(1 То 5, / То 4) As Single’onepaTop объявления массивов

For J = I To 4

A(J) = 0 'присвоение начального значения

'элемента вектора For / = / То 5

A(J) = A(J) + B(/,J) 'вычисление суммы в цикле Next / Next J

Пример программы.

Определен массив записей для хранения результатов экзаменов

Dim Sesia (5) As Resiiitaf на основе пользовательского типа данных Type Reyiltat

Familia As Sti ing * 20 Name Exam (1 To 3) As Stung * /5 ReyiltExam (/ To J) As Integer End Type

Программа должна вводить исходные данные и определять среднюю оценку студента, фамилия которого задается

Поместим описание пользовательской структуры данных в раздел Geneial модуля Module! и создадим форму .

Форма и программы процедур обработки событии обеспечивают следующую логику работы При загрузке формы меткам (Label I, Label2, Label3) присваиваются названия экзаменов и активизируется командная кнопка “Ввод”, командная кнопка “Вычисление” не активна Последовательное пятикратное щелканье мыши по кнопке “Ввод” после заполнения информацией текстовых окон обеспечивает ввод необходимых исходных данных После чего командная кнопка “Ввод” деактивизируется, а командная кнопка “Вычисление” активизируется После ввода в текстовое окно под ней фамилии и щелчка мыши по кнопке “Вычисление” производится вычисление средней оценки студента и результат выводится в текстовое окно

3.5.5.2. Оператор цикла Do-Loop

Синтаксис оператора следующий

Do [{While | Until} логическое выражение]

[блок операторов}

[Exit Do]

[блок операторов ]

Loop

или

Do

[блок операторов }

[Exit Do]

[блок операторов ]

Loop [{While | Until} логическое выражение ] где Do, While, Until, Exit Do, Loop ключевые слова. Пара Do-Loop определяют начало и конец оператора цикла;

While определяет выполнение операторов, входящих в цикл, пока стоящее следом логическое выражение принимает значение “True”;

Until определяет выполнение операторов, входящих в цикл, до тех пор пока стоящее следом логическое выражение не примет значения “True”; Exit Do используется для прекращения выполнения цикла (управление передается на оператор, который следует сразу за Loop) и применяется, например, и логическом операторе, который проверяет альтернативное условие прерывания цикла (например, ошибку).

Запись условия “{While | Until} логическое выражение” в начале или в конце цикла определяет, где это условие (задается логическим выражением) будет проверяться.

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

Пример последовательного чтения информации из файла, когда необходима проверка, что файл не закончился, анализируя наличие записи конца файла с использованием встроенной функции EOF ( номер файла):

Операторы чтения файла будут выполняться только в случае значения функции EOF — False (текущая запись не является концом файла).

Запись условия в конце цикла означает, что цикл выполнится хотя бы один раз (при этом первом проходе обычно формируется условие, которое затем будет проверяться).

Пример.

Do I Do Password = InputBox (“Введите пароль”) Password = InputBox (“Введите пароль”) Loop While Password О “Секрет” ] Loop Until Password = “Секрет”

В данном примере условие стоит в конце и ввод пароля (обращение к встроенной функции InputBox) выполняется хотя бы один раз (формируется проверяемое в конце условие). В первом случае используется While, определяющее повторение цикла пока “Секрет” не совпадает с введенным значением. Во втором случае используется Until, определяющее повторение цикла до момента совпадения “Секрет” с введенным значением.

Пример программы.

Программа производит вычисление ряда с задаваемой точностью вычисления. М-и элемент ряда вычисляется по формуле

(-irN/(N!*(2*N+l))

Программа реализуется в четырех вариантах с использованием оператора цикла Do-Loop. Варианты определяют место записи условий While и Until. Каждый вариант помещается в процедуру обработки события щелчка мыши по соответствующей командной кнопке (кнопки “Вариант!”, “Вариант2”, “ВариантЗ”, “Вариант4”) на форме.

Текст процедур примера:

Private Sub Commandl_Click () Dim Eps, Sum, Sumi As Double Dim N, NFactorial As Integer Eps = Val(InputBox(“Введите точность вычисления”).) Sum = 0: N = 1: NFactorial = 1 Do While Abs((-1)”N/(NFactorial*(2 * N + 1))) > Eps

Sum = Sum + (-1) л N /(NFactorial * (2 * N + 1)) • N = N + 1

NFactorial = NFactorial * N Loop

MsgBox “Сумма paBHa”+Str$(Sum)+”,N равно” + Str$(N) End Sub

Private Sub Command2_Click() Dim Eps, Sum, Sumi As Double Dim N, NFactorial As Integer

Eps = Val(InputBox(“Введите точность вычисления”)) Sum = 0: N =- 1: NFactorial = 1

Do Until Abs ( (-1)”N/(NFactorial*(2 * N + 1))) < Eps Sum = Sum + (-1) A N / (NFactorial * (2 * N + 1)) N = N + 1

NFactorial = NFactorial * N Loop

MsgBox “Сумма равна”+31г$(Sum)+”, N равно”+ Str$(N) End Sub

Private Sub Command3_Ciick() Dim Eps, Sum, Sumi As Double

Dim N, NFactorial As Integer

Eps = Val(InputBox(“Введите точность вычисления”))

Sum =0: N = 1: NFactorial - 1

Do Sum ^ Sum + (-1; N / (NFactorial * (2 * N + 1))’

N = N + 1

NFactorial = NFactorial * N

Loop Wnile Abs ( (-1)’”N/(NFactorial* (2 * N + !)))> Eps

MsgBox “Сумма paBHa”+Str$(Sum)+ “, N равно” + Str$(N) End Sub

Private Sub Command4_Ciick () Dim Eps, Sum, Sumi As Double Dim N, NFactorial As Integer Eps = Val(InputBox(“Введите точность вычисления”)) Sum = 0: N = 1: NFactoriai = 1 Do

Sum = Sum + (-1) л N / (NFactorial (2 * N + 1))

N = N + 1

NFactorial = NFactoriai * N Loop Until Abs((-1)”N/(NFactorial*(2*N + !)))< Eps MsgBox “Сумма paBHa”+Str$(Sum).”, N равно” + Str$(N) End Sub

Циклы Do-Loop позволяют также строить циклы со счетчиком, аналогично циклам For-Next.

Пример.

Counter = 1 \ Counter = 1

Do While Counter <= 100 Do While Counter > 100

В(Counter) = ......... В(Counter) = ........

Counter = Counter + 1 Counter = Counter + 1

Loop Loop

Эти два фрагмента программы эквивалентны следующему фрагменту с использованием цикла For — Next.

For Counter = 1 То 100

В(Counter ) = ...........

Next Counter

Для организации ввода исходных значений элементов массивов удобно использовать операторы цикла при работе For-Next и Do-Loop. Примеры процедур обработки события щелчка мыши по форме, которые обеспечивают последовательный ввод элементов массива в специальном окне InpiitBox и их вывод в специальном окне MsgBox:

Sub Form_Click ()

Dim I As Integer

Static A(1 To 5)

I = 1

Do While I <= 5

A (‘I^=Val (InputBox ( “Введите элемент массива” ( Str(-T) ) )

MsgBox “Значение элемента массива” •+ Str(A(I))

1=1+1

Loop

End Sub

Sub Form_Click ()

Dim I As Integer

Static A(1 To 5) 1=1 Do Until I > 5

A (I)=Val(InputBox(“Введите элемент массива” + Str(-I) ) )

MsgBox “Значение элемента массива” + Str(A(‘I))

1=1+1

Loop

End Sub

Альтернативным способом ввода нескольких значении элементов массива может быть использование текстового окна и его свойств SelLength, SelStart, SelText (см описание текстового окна) В определенных позициях текстового окна можно задавать значения различных элементов массива и с использованием указанных функции эти поля выделять (аналогично тому, как осуществлялся ввод данных в текстовой строке ввода в операционнои системе DOS и др ) Создадим форму и разместим на ней текстовое окно, определив максимальное число символов 80 (свойство MaxLength = 80)

Исторический экскурс' когда-то недавно на перфокарте можно было “набить” 80 символов и строка фортран-программы состояла из 80 позиции Каждый элемент массива будем располагать последовательно в четырех позициях строки (число символов вводимого числа, включая десятичную точку, не превышает 4) Пробелы между числами отсутствуют

Имя текстового окна Input_Txt Остальные параметры определяются по умолчанию Определим процедуру обработки события нажатия клавиши KeyPiess

Sub Inpui:_Txt_KeyPress (KeyAscii As Integer) Static A(1 To 5) As Single If KeyAscii = 13 Then For I = 1 To 5 Input-_txt. SalStart-f’I 1) *4 'последовательно

'определяется начальная позиция вводимого числа lnput_txt.SelLength= 4 'определяется количество ' вводимых символов

A(I) = Val(Input_txt.SelText) 'выделяются 'необходимые символы и преобразуются

'в числовое значение (функция Val) Print A(I}; 'печать введенных значении на форме Next I End If

Процедура обеспечивает ввод значении пяти элементов массива при нажатии клавиши “Enter” (ASC1I-код клавиши равен 13). Стоящая “,” после оператора Punt A(I) обеспечивает печать следующего элемента массива на той же строке сразу после предыдущего.

Альтернативно можно использовать “,” (выводимые значения располагаются на одной строке в фиксированных зонах формы) При отсутствии указанных символов выводимые значения располагаются на отдельных строках

В качестве примера приводится программа нахождения суммы элементов матрицы 3*4 (три строки и четыре столбца), хотя бы один индекс которых кратен трем.

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

Текст процедуры:

Private Sub Form_Click ()

Static A(1 То 3, 1 То 4), Sum As Single For J = 1 To 4 Input_txtl.SelStart = (J - 1) * 4 'последовательно

“определяется начальная позиция вводимого числа Input_txtl.SelLength = 4 'определяется количество

'вводимых символов А(1, J) = Val(Input_txtl.SelText) 'выделяются

'необходимые символы и

'преобразуются в числовое значение (функция Val) Next J

Print А(1, 1), А(1, 2), А(1, 3), А(1, 4) For J = 1 То 4 Input_txt2.SelStart = (J - 1) * 4 'последовательно

'определяется начальная позиция вводимого числа Input_txt2.SelLength = 4 'определяется количество

'вводимых символов А(2, J) = Val(Input_txt2.SelText) 'выделяются

'необходимые символы и преобразуются в числовое

'значение (функция Val) Next J

Print А(2, 1), А(2, 2), А(2, 3), А(2, 4) For J = 1 То 4 Input_txt3.SelStart = (J - 1) * 4 'последовательно

'определяется начальная позиция вводимого числа Input txt3.SelLength = 4 'определяется количество

'вводимых символов А(3, J) = Val(Input_txt3.SelText) 'выделяются

'необходимые символы и преобразуются

'в числовое значение (функция Val) Next J

Print А(3, 1), А(3, 2), А(3, 3), А(3, 4) Sum = О

For I = 1 То 3 алгоритм For J = 1 То 4 суммирования IfI/3=I\30rJ/3=J\3 Then элементов Sum = Sum + A(I, J) матрицы, один

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

При одновременном использовании в процедурах и функциях операторов цикла и условных операторов должно выполняться так называемое правило вложенности.

Если среди операторов, выполняющихся в цикле (циклы For-Next и Do-Loop), имеется условный оператор (If-Endlf), то условный

оператор должен целиком содержаться внутри цикла (между операторами For-Next или Do-Loop). Если в Then — блоке или Else ~ блоке условного оператора It’-Endlf имеются выполняющиеся в цикле операторы (циклы For-Next и Do-Loop), то эти циклы Должны целиком содержаться в этих блоках.

3.6. ПРОЦЕДУРЫ И ФУНКЦИИ

Любая программа на Visual Basic является процедурой или функцией.

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

Выполнение профаммы начинается в основной (первой) функции или процедуре, iij которой вызываются другие процедуры или функции (Процедура А). После вызова выполняется вызванная процедура (Процедура А), которой передается управление выполнением программы. В свою очередь в вызванной процедуре могут быть обращения к другим процедурам или функциям (Функция Б) и т.д. (Visual Basic отслеживает до нескольких сот уровней вызовов).

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

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

Локальные данные определены только в момент выполнения процедуры или функции и память для них выделяется только на момент выполнения.

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

Глобальные данные сохраняются пока выполняется программа и они доступны для всех входящих в программу процедур и функции. При запуске программы Visual Basic отводит для глобальных данных необходимую память.

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

Программный код процедур и функций, не являющихся процедурами обработки событии, помещается в раздел general списка Object формы (щелчок мыши по кнопке Wiew Code окна Project и далее щелчок мыши по элементу раскрывающегося списка general). Кроме того, в раскрывающемся меню Insert Главного меню имеется пункт Procedure . выбор которого раскрывает специальное окно для выбора процедуры или функции п задания имени.

Для заданной процедуры или функции появляется шаблон (заготовка) в окне кода (первая п последняя строки программы), в который можно ввести текст программы.

3.6.1. Процедуры

Синтаксически процедура определяется [Private | Public] [Static] Sub имя процедуры [(список аргумен-

[операторы объявления] [операторы} [Exit Sub] [операторы} End Sub

где Private, Public, Static, Sub, Exit Sub, End Sub - ключевые слова. Sub определяет обязательный первый оператор процедуры. End Sub - обязательный последний оператор процедуры;

имя процедуры образуется в соответствии с общими правилами образования имен, но не может иметь описателей типа (имя процедуры не принимает значения);

список аргументов имеет следующий синтаксис:

[Optional] [ By Val | ByRef] [ParainArray] имя [( )] [As тип] где Optional, ByVal, ByRef, ParaniArray и As ключевые слова;

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

Тип может быть Byte, Boolean, Integer, Long, Currency, Single, Double, Date, String (только переменной длины). Variant, пользовательский тип или Control и Form. As тип необходимо применять для каждого аргумента.

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

Процедура не может быть определена внутри какой-либо процедуры или функции.

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

Sub SubDemo (RLen, Rwid) ' 'заголовок процедуры

‘SubDemo с двумя аргументами-

‘R1en-длина и Rwid-ширина

Dim Area 'объявление локальной переменной Area = RLen * Rwid ' расчет площади MsgBox “Площадь равна” & Area “печать результата End-Sub

Пример процедуры на основе рассмотренного выше фрагмента программы формирования вектора из сумм элементов столбцов матрицы:

Sub SubMatrVektor (A() As Single, B() As Single, .

MaxI As Integer, MaxJ As Integer)’ Dim J, I As Integer For J = 1 To MaxJ 'верхняя граница индекса J

'определяется передаваемым 'аргументом процедуры Л(J) = 0 'присвоение начального значения

'элемента вектора For I = 1 То MaxI 'верхняя граница индекса

'I определяется

Передаваемым аргументом процедуры А(J) = А(J) + B(I,J) 'вычисление суммы в цикле Next I Next J End Sub

Изменяя значения аргументов данную процедуру можно использовать для работы с матрицами произвольного размера.

Рассмотрим, что означают другие используемые ключевые слова в определении процедуры.

Exit Sub вызывает прекращение выполнения процедуры и пыход из нее в вызывающую программу.

Static определяет, что локальные данные (переменные, массивы), определенные внутри процедуры (переменная Area в примере), сохраняются в промежутках между вызовами данной процедуры. Определение Static не распространяется на данные, которые объявлены вне данной процедуры, но используются в ней (т.е. эти данные будут изменяться независимо от определения Static). Нельзя использовать при рекурсивном вызове процедуры.

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

Public определяет, что процедура может быть вызвана из любого модуля приложения.

Поскольку имя процедуры определяется (глобально распознается) в рамках всех процедур всех модулей одной программы, имя процедуры не должно совпадать с другими глобально распознаваемыми именами программы. Такими глобально распознаваемыми именами являются имена других процедур Visual Basic или процедур динамически подключаемых библиотек (dynamic-link library [DLL|) и данных, объявленных как Global (см. выше).

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

Optional определяет, что аргумент не является обязательным. При его использовании все последующие аргументы в списке аргументов также являются необязательными и для них также необходимо использовать данное ключевое слово. Аргументы, объявленные Optional, должны иметь тип Variant. He может использоваться для аргумента, для которого задан параметр ParamArray.

ByVal определяет, что аргумент передается в процедуру по значению (см. ниже).

ByRef определяет, что аргумент перелается в процедуру по ссылке (см. ниже).

ParamArray относится к последнему аргументу в списке аргументов и определяет, что конечный (заключительный) аргумент является необязательным массивом. Не может использоваться совместно с параметрами ByVal, ByRef, Optional.

Пример.

Sub ReturnTwice(ReturnValue, Optional A) If IsMissing(A) Then 'функция IsMissing ()

“проверяет передачу аргумента А в процедуру ReturnValue =Null 'если аргумент не передается,

'вычисляемое значение присваивается О Else ReturnValue = A * 2 'если аргумент передается,

'вычисляется значение от аргумента End If End Sub

Синтаксис оператора обращения к процедуре следующий:

имя процедуры[список значении} или

Call имя процедуры[{список значении)}

где Call — ключевое слово;

список значений список значений аргументов (соответствует списку аргументов в операторе Sub no количеству, порядку следования и типу, кроме случая когда используется параметр Optional).

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

Аргумент Значение

Переменная | Константа, переменная,

I элемент массива, выражение.

Массив Массив

форма Форма

Элемент управления ; Элемент управления

I

Следующие примеры показывают правильное согласование между списками аргументов и значении:

Пример 1.

Sub Sum (A As Integer, B As Integer, С As Integer)

'список аргументов состоит из переменных С = А + В • End Sub Sub Form Click ()

Static X(3) As Integer X(1) = 1 X(2) =2

Call Sum(X(l), X(1) + X(2), X(3)) 'список

' -значений включает элементы массива и выражение

Print Х(1), Х(2), Х(3) End Sub

Пример 2.

Sub Sum (A As Integer, В As Integer, С As Integer)

'список аргументов состоит из переменных С—А + В End Sub Sub Forrri_Click ()

Dim X, Z As Integer

X = 5

Call Sum(X, 4, Z) 'список значений включает

' переменные и константу Print X, Z End Sub

Пример 3.

Sub Sum (A ( ) As Integer)

'список аргументов включает массив

А(3) = А(1) + А(2) End Sub

Sub Form_Click () Static X(3) As Integer

X(1) - 1

X(2) =2

Sum X ( ,)'список значений включает массив

Print Х(1), Х(2), Х(3) End Sub

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

Для рассмотренного примера списка аргументов с использованием параметра Optional, обращения могут иметь следующий вид:

Call ReturnTwice(ReturnValue, )

'значение ReturnValue равно О

Call ReturnTwice(ReturnValue, 2)

‘ значение ReturnValue равно 4

Пример программы.

Поместим рассмотренную выше процедуру формирования вектора из сумм элементов столбцов матрицы в раздел general формы:

Option Explicit

Sub SubMatrVektor (A() As Single, B() As Single, MaxI As Integer, Max.J As Integer) Dim J, I As Integer For J == 1 To MaxJ A(J) -- 0 For I = 1 To MaxI

A(J) = A(J) + B(I, J) Next I Next J End Sub

Private Sub Form_Ciick()

Static X(1 To 2, 1 To 3) As Single, Y(1 To 3) As Single

X(1, 1) = 1

X(1, 2) = 2

Х(1, 3) = 3

X(2, i) = 4

Х(2, 2} = 5

Х(2, 3) = 6

SubMatrVektor Y(), X(), 2, 3

Print Y(li, Y(2), Y(3) End Sub

Результат выводится на форму.

3.6.2. Функции

Синтаксически функция определяется

[Public | Private] [Static] Function имя функции [(список аргументов)} [As тип]

[операторы объявления]

[операторы}

[имя функции = выражение]

[Exit Function] [операторы] [имя функции = выражение] End Function

где Public, Static, Private, Function , Exit Function , End Function —

ключевые слова. Function определяет обязательный первый оператор функции. End Function — обязательный последний оператор функции:

имя функции образуется в соответствии с общими правилами образования имен и может иметь описатель типа (As тип в конце первой строки относится к имени функции). Имя функции принимает значение и хотя бы один оператор

имя функции = выражение

может присутствовать внутри функции и выполняться при выходе из нее. Если никакое значение не присвоено имени функции, то имя функции принимает значение по умолчанию: числовая функция принимает значение 0, функция, объявленная как String, принимает значение пустой строки нулевой длины (“”), функция, объявленная как Variant принимает значение Empty (значение, которое принимает имя функции, называют возвращаемым значением функции — возвращаемое значение).

Список аргументов имеет следующий синтаксис:

[Optional] [ByVal|ByRef][ParamArray] имя[( )][As тип] [.[Optional] [By Val | ByRef][ParamArray] имя[( )] [As тип] ] ... где Optional, ByVal, ByRef, ParamArray и As ключевые слова;

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

Тип может быть Byte, Boolean, Integer, Long, Currency, Single, Double, Date, String (только переменной длины). Variant, пользовательский тип или Control и Form. As тип необходимо применять для каждого аргумента.

Список аргументов определяет связь по данным между вызывающей (функция, из которой происходит вызов) и вызываемой (функция, которая вызывается) процедурами или функциями. Локальные данные, определенные внутри функции (кроме тех, что определены в списке general для форм), не могут использоваться в других процедурах и.'функциях (например, переменные с одинаковыми именами, но объявленные в разных функциях, хранятся в разных ячейках памяти и изменение переменной в одной из функций не ведет к изменению одноименной переменной и другой функции).

Exit Function вызывает прекращение выполнения функции ц выход из нее в вызывающую программу.

Функция не может быть определена внутри какой-либо процедуры или функции.

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

Function FunDemo (RLen, Rwid) As Single

'заголовок функции FunDemo с “двумя аргументами- Rlen-длина и Rwid-ширина

“тип имени функции определен как Single Dim Area ' объявление локальной

'переменной Area = RLen * Rwid ' расчет площади MsgBox “Площадь равна” & Area ' печать

'результата. FunDemo = Area 'имени функции

'присваивается вычисленное значение End Function

Пример функции для вычисления среднего значения элементов одномерного массива:

Function FunSumVecior (A( )} As Single,

MaxI As Integer) As Single

Dim SumVector As Single, I As Integer

Surn Vector = 0

For 1=1 To MaxI ' верхняя граница индекса 'I определяетсяпередаваемым аргументом процедуры

SumVector =SwnVector + A(I)

Next I

FunSuni Vector = SumVector/MaxI 'имени

'функции присваивается вычисленное значение End Function

Изменяя значения аргументов данную функцию можно использовать для работы с вектором произвольного размера.

Используемые ключевые слова аналогичны рассмотренным выше для процедур.

Приведем примеры заголовков функций с использованием параметров ParamArray и Optional:

Function (‘.ilcSur-i (ByVa;: FirstArg As Integer, par^Array OtnerArqri;;^

Function MyFunc.My^tr As String, Optional MyArgI, Opt--^1’”1”-‘1 MyArg2 )

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

имя функци11([список значений})

список значении - список значений аргументов (соответствует списку аргументов в операторе Function по количеству, порядку следования и типу. если не используется параметр Optional). Кроме того должно выполняться следующее соответствие между списками аргументов и значениями:

Пример 1.

Function Sum (A As Integer, B As Integer) As I n t e g e r

‘список аргументов состоит из переменных • С - А + В Sum = С Knd Function Sub Form_Click ; ) italic X(3) As Integer X<1) - 1 X(2) - 2 X(3) = Sum(X(l), X(1) - X(2))’список значений

‘ включает 'элементы мас,”'ЛЕ^а и выражение Print Х(1) , Х(2), Х(3) End Sub

Пример 2. .

Function Sum (A As Integer/ В As Integer) ftg Integer

'список -аргументов состоит из переменных С = А + В Sum = С End Function Sub Forrn_Click () Dim X, Z As Integer X = 5 Z = Sum (X, 4)' список значений включает

' переменную и константу Print X, Z End Sub

Function Sum (A ( ) As Integer) As Integer 'список аргументов включает массив

А(3) = А(1) + А(2)

SumА(3)

End Function

Sub Form_Click ()

Static X(3) As Integer

X(1) = 1

X(2) - 2

X.(3 ) = Sum (X() ,)'список значений 'включает массив

Print Х(1), Х(2) , Х(3)

End Sub

Для рассмотренных примеров заголовков функций с параметрами ParamArray и Optional обращения к функциям могут иметь следующий вид:

ReturnValue = CalcSum(4, 3 ,2 ,1) первый аргумент функции FirstArg принимает значение 4, остальные аргументы являются элементами массива и принимают значения OtherArgs(l) = 3, OtherArgs(2) = 2, последнее значение определяет размерность массива (1).

RetVal = MyFunc(“Hollo”, 2, “World”) - В этом обращении заданы все три значения аргумента.

. RetVal = MyFunc (“Test”, , 5) — в этом обращении не задано значение второго аргумента.

RetVal = MyFunc (МуАгд! :-- 7) - в этом обращении зада-но значение второго аргумента с использованием его имени.

Пример программы.

Поместим рассмотренную функцию для определения среднего значения элементов одномерного массива в раздел general (Формы и обращение к ней в процедуру обработки события щелчка мыши по форме . После запуска программы и щелчка мыши по форме распечатывается среднее значение суммы элементов массива Х.

3.6.3. Передача аргументов по ссылке и по значению

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

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

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

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

3.6.4. Использование в качестве аргументов процедур и функции форм и элементов управления

Список аргументов процедур и функций может включать имена форм и элементов управления (в качестве описателей типа для них применяются соответственно Form и Control ). Это позволяет создавать универсальные алгоритмы для работы с формами и управляющими элементами. Например, для привлечения внимания пользователя к одной из управляющих кнопок формы можно создать одну универсальную процедуру, изменяющую шрифт и цвет фона,

Для контроля соответствия передаваемых при обращении типов форм и элементов управления в Visual Basic есть специальный оператор

If TypeOf имя объекта Is тип объекта Then

где TypeOf и Is — ключевые слова, а последующий синтаксис и действие совпадают с рассмотренным выше условным оператором.

Чтобы проверить соответствие передаваемого в процедуру объекта, в ее текст можно включить оператор

Sub Attention (Btn As Control)

If TypeOf Btn Is OptionButton Then

Btn.Fontltaiic = True

Btn.BackColor = Red

End If End Sub

Пример программы.

Создадим процедуру для изменения свойств формы, аргументом которой является имя формы, и процедуры обработки событий Click для задания исходных свойств формы и KeyPress, в которой имеется обращение к процедуре Change

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

. Нажатие клавиши Enter приводит к изменению размера, положения формы и вывод заключительной части текста (обращение в процедуре обработки события KeyPress к процедуре Change) .

3.7 ФАЙЛОВЫЙ ВВОД-ВЫВОД

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

оперативной памяти и ее относительно высокая стоимость не позволяют применять ее для постоянного хранения больших объемов информации. Для этого используется внешняя память (магнитные ленты, жесткие и гибкие магнитные диски, лазерные диски), позволяющие хранить сотни мегабайт (1 Мбайт = 1048576 байт) и гигабайт (1 Гбаит = 1.073.741.824 байт) информации и стоимость которых относительно невелика.

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

Таким универсальным понятием является файл (набор данных), который используется для работы с внешними данными на любом носителе. Под файлом понимается совокупность данных. Файл состоит из записей. Запись состоит из логически связанных данных, которые передаются между оперативной и внешней памятью за одну операцию ввода-вывода (ввод — передача данных из внешней в оперативную память, вывод - передача данных из оперативной во внешнюю память).

Например, в качестве файла можно рассматривать и используемую ранее колоду перфокарт. Одна карта является одной записью (устройство ввода перфокарт считывает последовательно по одной карте и нельзя считать меньше, чем одну карту). Запись характеризуется длиной (рассмотренная перфокарта является записью фиксированной длины в SO байтов и на ней можно было разместить 80 символов). Записи бывают фиксированной или переменной длины.

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

В Visual Basic файлы подразделяются на:

3.7.1. Последовательные файлы

3.7.2. Файлы прямого доступа

Каждая запись последовательного файла представляет собой строку символов, в конце которой содержится символ <CR>, обозначающий переход к началу строки (carriage return, ASCII-код равен 13), и <LF>, обозначающий переход на другую строку (line feed, ASCII-код равен 10). Последовательное действие этих двух символов обеспечивает переход к новой записи. После последней записи записывается признак конца файла (end of file), который может проверяться встроенной функцией EOF (возвращает значение True. если обнаружен конец файла, и False, в противном случае).

Для получения доступа к файлу для операции ввода-вывода используется оператор открытия файла, синтаксис которого следующий

Open имя_файла For {Append Input | Output} As #номер_фаила fLen = размер буфера памяти}

где Open, For. Append. Input. Output, As — ключевые слова.

Input — файл открывается для ввода.

Output — файл открывается для вывода.

Append — устанавливает считывающе-записывающее устройство на конец файла и выводимая информация записывается в файл после существующих записей (при значении параметра Output выводимая информация записывается с начала файла, т.е. происходит перезапись файла, если в нем существовали записи).

Имя_файла имя файла (символьная константа или переменная) или путь. Имя файла в DOS и Windows 3.1 состоит из не более чем восьми буквенных (латинских) или цифровых символов (первый символ буква), за которым может следовать расширение, определяющее тип файла (VBPART3.DOC, Project. MAC). В Windows 95 допускаются длинные имена файлов до 255 символов, включая специальные символы (в русской версии для записи имени файла можно использовать русские буквы) Путь определяет местонахождение файла в иерархической системе каталогов (C:\CONF1G.SYS, C:\WINDOWS\VB).

Номер файла целочисленное выражение, значение которого должно лежать в диапазоне от 1 до 255 (присваиваемый файлу номер).

Len — определяет размер буфера операций ввода-вывода (по умолчанию 512 Кб).

Примеры:

Open “С:\CONFIC.SYS” For Input As tt5 'открывается

файл с именем CONFIG.SYS в директории С: для ввода

и ему присваивается номер 5

Doc$ = “a:\Utilits\NC.DOC”

присвоение значения константе

Open Doc$ For Input A.s ft 5

'открытие файла NC.DOC на диске А: в директории Utilits для ввода, файлу присваивается номер 2

Open “Resulc. t:-:t “ For Output As tt7

'открытие файла для вывода.

Если открывается для вывода несуществующий файл. то он создается при значениях параметров Append и Output. Если для ввода открывается несуществующий файл, то Visual Basic сообщает об ошибке. Если файл скрывается для вывода Visual Basic всегда создает новый файл, перезаписывая в него любой имеющийся на диске файл с тем же именем.

Существование файла перед открытием можно проверить с помощью встроенной функции Dir$ (возвращает строку с копией имени файла, если указанный файл существует, либо пустую строку в противном случае).

Пример.

If Dir$(“FilePrim.Txt”) <> “” Then

.Open “FilePrim.Txt” For Input As #12

End If

После завершения операций ввода — вывода файл должен быть закрыт. Для этого используется оператор

Close #номер_фачла где Close — ключевое слово;

номер_ файла соответствует номеру в операторе Open.

Для ввода информации из последовательного файла используется оператор

Line Input #номер_файла, имя_переменной где Line Input — ключевое слово;

номер_файла — номер файла, совпадающий с номером в операторе Open (вводится информация из открытого файла);

имя_переменной — имя переменной, которая принимает значение записи файла, типа String или Variant.

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

Встроенная функция EOF (аббревиатура английских слов End Of File - конец файла) позволяет проверять при чтении файла: достигнут конец файла или нет. Значением аргумента функции EOF является номер считываемого файла. Функция возвращает значение True, если достигнут конец файла, и False - в противном случае.

Пример.

Dim FileYura, Sr.rokaVvoda As String

'объявление символьных переменных

Open FileYura For Input As #5

'открытие файла FileYura для ввода Do While Not EOF(5)'цикл последовательного чтения

'записей файла пока не достигнут конец Line Input #5, StrokaVvoda'ввод считанной записи

'в переменную StrokaVvoda LineRead StrokaVvoda 'обращение к

'процедуре обработки строки LineRead 'аргументом которой является переменная StrokaVvoda Loop

Close #5 'закрытие файла

Для вывода информации в последовательный файл используется оператор

{Print* Write} ”номер_файла,[[{8рс(ч) |Tab(n)}]

[ выражение}[{,\;}}} где Print, Write — ключевые слова.

Print# — обеспечивает вывод в последовательный файл в формате дисплея (т.е. аналогично выводу на печать, например, на форме).

выражение - выражение, значение которого записывается в файл.

Если выражения разделяются “;”, то в файл они записываются без пробелов слитно.

Если выражения разделяются “,”, то в файл они записываются в фиксированные зоны длиной 14 символов (зонный формат).

Если в конце выражения не стоит “;” или “,”, то выведенная в файл строка дополняется символами <CR>, обозначающими переход к началу строки (carriage return, ASCII-код равен 13), и <LF>, обозначающими переход на другую строку (line feed, ASCII-код равен 10). Т.о. каждому значению соответствует одна запись или одна строка при выводе в формате дисплея.

Spc(n) и ТаЬ(п) определяют соответственно вставку п пробелов между выводимыми выражениями и табуляцию на п колонок перед списком выражений.

Для удаления с дискового пространства неиспользуемого файла используется оператор

Kill имя_файла где Kill — ключевое слово.

В заключение следует отметить, что данные любого типа (Boolean, Data, Integer, Single, Double, Currency) записываются в файл в символьной форме. При выводе данные преобразуются к символьной форме, при вводе происходит их преобразование к первоначальному типу, па что затрачиваются ресурсы компьютера. Кроме того. представление данных в символьной форме неэффективно. Например, число 421596 типа Single -занимает в памяти компьютера 4 банта, но при записи в последовательны” файл - 7 байт: 1 байт па каждый символ.

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

3.7.2. Файлы прямого доступа

Пример программы.

В первой части процедуры обработки события щелчка мыши по форме в файл TE5TFILE выводятся строки символов с использованием оператора Print# (вывод в формате дисплея). Во второй части процедуры записи этого файла читаются и выводятся в окно вывода в том виде, как они записаны в файле.

Текст процедуры:

Пример программы.

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

На форме располагаются:

Тексты процедур обработки событий:

Private Sub Coriurtandl_Click ()

Text3.SetFocus Open “Filel” For Output As #5

Text3.Text = “” End Sub

Private Sub Command2_Click() Dim Filedata, Filedatal As String Dim NPoz, NProbel As Integer Close #5

Open “Filel” For Input As tt5 Open “File2” For Out-put As #6 Do While Not EOF(5) Line Input #5, Filedata Filedatal = “” 1=1 Do While InStrfI, Filedata, “*”) > 0

NPoz = InStr(I, Filedata, “*”) Filedatal = Filedatal + Mid$(Filedata, 1, NPoz - I) NProbel = Val (Mid$ (Filedata, NPoz +1, 1);

Fiiedatal = Filedatal + String$(NProbel, “ I .= NPoz + 2 Loop

Filedatal = Filedatal + Mid$(Filedata, I) Write #6, Filedatal Loop

Close #5 Close ft6 End Sub

Private Sub Command3_Click() Dim Filedata As String Close #5

Text2.Text = “”

Open “Filel” For Input As ft5 Do While Not EOF(5)

Line Input #5, Filedata

Text2.Text = Text2.Text + Filedata :hr$ (13) + Chr$(10)

Loop End Sub

‘Private Sub Command4 Click() Dim Filedata As String Open “File2” For Input As #6 Do While Not EOF(6) Line Input tt6, Filedata

Textl.Text = Textl.Text + Filedata + Chr$(13) ^ Chr$(10)

Loop Close #6 End Sub

Private Sub Command5_Click()

Kill “Filel”

Kill “File2”

End End Sub

Private Sub Text3_KeyPress(keyAscii As Integer) Dim Filedata As String If keyAscii = 13 Then Filedata = Text3.Text

Write tt5, Filedata Text3.Text •= “”

Описание используемых стандартных (функции для обработки строк

Stiing$(niimbei, chaiactci) возвращает проку одинаковых символов (chaiaciei) заданной длины (niimbel)

Mid$(stung, start|. length|) возвращает строку с заданным количеством символов (length) из cirokh (stung), начиная с заданной позиции (start) el in start больше количесгва символов в строке - возвращаечся прока нулевой длины Если отсутствуег параметр length, то воз праща клея симво1ы от заданной позиции до конца строки Если slung равно Null - возвращается Null

lnSti(|stait. |stiingl. stiing2) возвращает первую позицию, с которой одна строка (stiing2) вхолиг в другую (stimgl), как подстрока Start — арифмешческое выражение, значение которого задае! начальную позицию поиска в slungi (если параметр stait не задан, ю поиск иде1 с первой позиции)

Возвращаемое значение' если stiingi имеет нулевую длину — О если string! равно Null - Null если stiing2 имеет нулевую длину — start если stiing2 равно Null — Null если string2 не найдено — О если start > длины stimgl — О

Для получения доступа к файлу для операции ввода-вывода используется оператор открыгия файла, синтаксис которого следующий

Open имя_фаша [For Random] [Access {Read] Write I Read

Write}]

[{Shared | Lock Read | Lock Read Write}] As [#] номер файла [Len =

длина записи}

где Foi Random, Access. Read, Wiite, Read Wiite, Shaied, Lock Read, Lock Wiite, Lock Read Wiite, Len - ключевые слова.

For Random определяет прямои доступ и принимается по умолчанию

Access определяет допустимые операции с файлом (Read — чтение фаипа (ввод). Write - вывод в файл. Read Write — допускается ввод и вывод)

Shared, Lock Read, Lock Write, Lock Read Write определяют допустимые операции над фаилом для друшх пользователей сеги (только для сетевых приложении)

имя_фа1иа имя файла (символьная константа или переменная) или путь

Номер файла - целочисленное выражение, значение которого должно лежать между 1 и 255 Другие операторы ввода-вывода используют номер открытого файла

Len определяет длину записи в байтах (по умолчанию длина записи устанавливается в 128 бант)

Длина записи определяется информацией, хранимой в файле, и задается целочисленным выражением и должна быть меньше 32767 байт (см ниже) Все записи одного файла прямого доступа имеют одинаковую длину (записи одного файла последовательного доступа Moiyr иметь разные длины)

Несушес1вующии файл создается при выполнении оператора Open Примеры:

Open “TESTFILE” For Random As#l Len=Len (Cl ien CWame) 'открывается файл “TESTFILE” прямого 'доступа с номером 1, длина записи

'определяется с помощью встроенной 'функции Len (определение длины строки)

Open “MYFILE.TXT” For Random As #5 Len = 256

Для файлов прямого доступа можно открыть файл с другим номером, не закрывая файл

Файл прямого доступа закрывается оператором

Close #номер файла где номер фалла - указанный при открытии номер

Для ввода и вывода в файлах прямого доступа используются соответственно операторы

Get #номер файла, [номер записи], имя_переменной

Put #номер файла, [номер записи], имя_переменной где Get, Put - ключевые слова (Get — ввод. Put — вывод).

номер записи - арифметическое выражение, значение которого должно лежать в диапазоне от 1 до 2247483647, и которое определяет номер читаемой записи при вводе и номер записи, в которую выводится переменная

Если номер записи отсутствует, то ввод — вывод начинается со следующей от текущеи записи (используемый номер в последнем из предыдущих операторов Get и Put) Обратите внимание, что запятые должны присутствовать при отсутствии номера записи (Get #4„FileBufTer)

Имя^переменной имя любой переменной, кроме имени массива (отдельный элемент массива может быть) и имени объекта, значение которой записывается в файл при выводе и значение которой считывается из файла при вводе

Примеры

Put #3, 4, Massiv(5)'выводится значение 5-го 'элемента массива Massiv в 4-ю запись J-го файла.

Get #fileNum, I, RecVar 'ич 1-й -записи файла с 'номером liieNun’ считывается 'значение переменной RecVar.

Пример программы.

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

Текст процедур обработки событии'

Private Sub Commandl_C-Lick ()

i^im PEREMLN Ач String * 15

Open “Prirrb^le” For Random As 5 Len - 15

For I - 1 ^r b PEREMEN = InputBox(“Введите запись” + Str(I))

Put #1-, T, PEPEMEN

Next r

Close ^ End Sub

Private Sub Commcind2 Click ()

Dim PEREMEN As String * 15

Open “Primflie” For Random As 5 Len = 15 К = InputBox(“Введите номер записи для вывода”)

Get #5, К, PEREMEN

MsgBox Str(K) +' “-ая запись” + “ “ + PEREMEN

Close #5

Kill “PrimFile” End Sub

Еще одним преимуществом файлов прямого доступа является возможность использования индексов записеи Если для реорганизации фаила последовательного доступа (добавление, удаление, перестановка записей) необходимо сначала его прочитать, затем реорганизовать данные, а потом переписать фаил на диск в соответствии с новой реорганизациеи, то используя индекс, можно реорганизовывать индекс без реорганизации самого фаила Это значительно увеличивает скорость обработки больших объемов информации

Чтобы создать индекс, вначале создается массив целых чисел, в котором каждый элемент содержит один (свой) номер записи фаила прямого доступа Этот массив используется для определения номера записи, к которой нужно обратиться Такая

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

Для массива индексов Index () оператор ввода для связанного с этим индексом файла имеет вид

Get ftFiieNiim. Imlex(l), RecVar

Первоначально каждый элемент массива Index () содержит свой собственный номер:

Index (1) = 1

Index (2) = 2 “.', Index (3) = 3

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

Index (I) = 1

Index (2) = 3

Index (3) = 2

Пример программы.

Добавим к предыдущей программе процедуру обработки события щелчка мыши по форме.

Private Sub Form_C]-ick ( )

Dim PEREMEN As String * 15, PEREMEN1 As String * 15 Static thelndex(l To 5) As Integer Open “PrimFile” For Random As 5 Len = 15 For I = 1 To 5 thelndex(l) = I Next I

11 = Val(InputBox(“Введите номер 1-й записи для

перестановки”))

Get #5, thelndex(ll), PEREMEN

12 = InputBox(“Введите номер 2-й записи для перестановки”)

Get #5, thelndex(12), PEREMEN1 Print Str(thelndex(ll)) + “-ая запись “ + PEREMEN Print Str(thelndex(12)) + “-ая запись “ + PEREMEN1 thelndex(ll) = 12 thelndex(12) = II Get #5, thelndex(ll), PEREMEN Get #5, thelndex(12), PEREMEN1 Print Str(Il) + “-ая запись “ + PEREMEN Print Str(I2) + “-ая запись “ + PEREMEN1 Close #5

Kill “PrimFile” End Sub

В процедуре вводится массив thelndex для задания индексов записей используемого файла. Первоначально значениям массива последовательно присваиваются значения от 1 до 5 (индекс записи совпадает с ее реальным номером’в файле). Далее вводятся значения двух номеров записей для их перестановки,

Private Sub Commandl_Click()

Nzapisi = 1

Nzapisil = 1

Open “TestFile” For Random Access Read Write As #10 Len = 70

Text 1.Enabled = True

Text2.Enabled = True

Text3.Enabled = True

Text4.Enabled = True

Text7.Enabled—True

Textl.SetFocus

Commandl.Enabled = False End Sub

Private Sub Command2_Click() Dim Peremen As Primer Textl.Text = “” Text2.Text = “” Text3.Text = “” Text4.Text = “” If Nzapisil < Nzapisi Then Get #10, Nzapisil, Peremen Textl.Text = Peremen.Familia Text2.Text = Peremen.Dolgnost Text3.Text = Peremen.Podrazdeienie Text4.Text = Peremen.Zarplata End If

Nzapisil = Nzapisil + 1 End Sub

Private Sub Command3_Click()

Textl.Text = “”

Text2.Text = “”

Text3.Text = “”

Text4.Text == “”

Text5.Enabled = True

Text6.Enabled = True

Text5.Text = “”

Text6.Text = “”

Text5.SetFocus End Sub

Private Sub Command4_Clicki’ Dim Peremen As Primer

Dim Zaprosi As String * 20, Zapros2 As String * 20, Sum As Single

Dim Pri As Integer, Pr2 As Integer, Kol As integer, Rez As Single

Pri = -1: Pr2 = -1: Nzapisil = 1: Kol = 0: Sum = 0

Zaprosi = Text5.Text: Zapros2 = Text6.Text Do While Nzapisil < Nzapisi Get #10, Nzapisil, Peremen If Peremen.Podrazdeienie - Zaprosi Then Pri = 1 End If

If Peremen.Doignost = Zapros2 Then Pr2 - 1 End If

If Peremen.Podrazdeienie = Zdprosi And Peremen.Doignost = Zapros2 Then

Kol -= Kol + 1: Sum = Sum + Val(Peremen.Zarplata): Rez = Sum / Kol End If

Nzapisil = Nzapisil + 1 Loop If Pri < 0 Then

• • MsgBox “Такого подразделения нет” Text5.Text = “”: GoTo Finish6 End If If Pr2 < 0 Then MsgBox “Такой должности нет”

Text6.Text = “”: GoTo Finish6 End If

Text7.Text = Str$(Rez) Command5.Enabled =- True Finish6:

End Sub

Private Sub Cun-iniand5_Ciick ()

Cl?Qse„#10

Kill “TeS-tFile”

End End Sub

.Private Sub Form_Load() ' Commandl.Enabled = True Command2.Enabled - False Command3.Enabled = False Command4.Enabled a False Хотя можно указать запись длиной 1 байт, компьютер на самом деле прочитает в буфер памяти один или более секторов. Когда программа читает данные из дискового файла, она читает их из буфера. Когда прочитывается весь буфер, компьютер читает в этот буфер следующие несколько секторов из файла. Аналогично данные записываются в дисковый файл: сначала они записываются в буфер памяти, а когда он заполняется, то записываются на диск.

Предположим, что размер дискового сектора 512 байтов, а длина записи файла 260 байтов. При такой длине записи большинство записей файла будут расположены в двух секторах (например, запись 2 использует байты с 261 по 512 первого сектора и с 1 по 8 байт второго сектора) и для чтения с диска такой записи потребуется прочесть два сектора. Использование вместо 260-байтных записей 256-байтных обеспечивает упаковку в один дисковый сектор двух полных записей и позволяет для ввода одной записи читать только один сектор.

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

Пример программы.

Записи файла прямого доступа содержат информацию о сотрудниках подразделения предприятия (структура записей файла:

фамилия, должность, подразделение, заработная плата).

Программа обеспечивает ввод исходной информации в файл и получение информации по запросу: средняя заработная плата для заданных должности и подразделения.

Текстовые окна “Фамилия”, “Должность”, “Подразделение”, “Зарплата” (имена соответственно Textl, Text2, Text3, Text4) используются для ввода исходной информации и просмотра записей файла. Текстовые окна “Должность”, “Подразделение” (имена соответственно Text5, Text6) для ввода запроса. Текстовое окно “Результат” (имя Text?) используется для

вывода результата и предупреждении о не заполнении необходимых текстовых окон. Коммандные кнопки “Начало/Ввод”, “Просмотр файла”, “Ввод запроса”, “Обработка запроса”. “Конец” (имена соответственно Command I, Command2, Command3, Command4, Command5) обеспечивают переход к функциональным алгоритмам. Оператор объявления пользовательского типа данных помещаются в модуль module l.bas.

Текст процедуры обработки событий:

Type Primer

Familia As String * 20

Dolgnost As String * 20

Podrazdelenie As String * 20

Zarpiata As String * 10 End Type

Dim Nzapisi, Nzapisil As Integer Dim Peremen As Primer Private Sub Coirimandl_Cllck ()

Nzapisi = 1

Nzapibil 1

Open “TestFile” For Random Access Read Write As #10 Len = 70

Textl.Enabled - True

Text2.Enabled -= True

Text3.Enabled—True

Text 4.Enablea = True

Text?.Enabled - True

Textl.SetFocus

Commandl.Enabled -= False End Sub

Private Sub Command2_Click ( ) Dim Peremen As Primer Textl.Text = “” Text2.Text - “” Text3.Text - “” Text4.Text = “” If Nzapisil <” Nzapisi Then Get #10, Nzapisil, Peremen Textl.Text = Peremen.Familia Text2.Text =- Peremen.Dolgnost Text3.Text = Peremen.Podrazdeleni Text4.Text = Peremen.Zarplata End If

Nzapisil = Nzapisil + 1 End Sub

Private Sub Command3__Click()

Textl.Text = “”

Text2.Text = “”

Text3.Text =• “”

Text4.Text = “”

Text5-Enabled = True

Text 6.Enabled = True

Text5.Text = “”

TextG.Text = “”

Text5.SetFocus End Sub

Private Sub Conmand4_Clic1 Dim Peremen As Primer

Dim Zaprosi As baring - ^.u, ^аргоь^ as String * 20, Sum As Sinqie

Dim Pri As Integer, Pr2 As Integer, Koi As Integer, Rez As Single

Pri - -1: Pr2 - -1: Nzapisil = 1: Kol = 0: Sum - О

Zciprosi - Text’).Text: Zapros2 = Text6.Text Do While N^dpibil “•’zapisi ‘^rit #1’, Nzdpisil, Peremen If Peremen. Pcmra^aeienie - Z^prosi Th>.’n t’rl -= 1 End If

If Peremen.Dolgnost = Zapros2 Then Pr2 - 1 End If

If Peremen. Podrazdelenie - Zciprosi And Peremen.Dotqnosr Zdpros2 Then

Kol k’)i + 1 : Sun suit + Val ( E’fc r emen . Zdrplata ) : Rez - iiiim / Koi End If

N?apisil - ^Zcioisil + 1 Loop II: Pri < (• T^hen

MsqBox “Tai- ого псдразд&ления нет” Tex^J.rext - “”: GoTo l-mishb End If If Pr2 < 0 Then MsgBox “Такой допкно ••ти нет”

r^xtt.rex”- - “”: u^Tu Finishfa End I*

Text /.It >;r Str$ ;Re.i) i”^mmdndb . Fn,jbi( ci =- ‘I rue F i n i a n о :

End Sub

briV.itt S л1 ‘ .:l”LcU!f.t^ CLlCK(,

^1оъе #1-;

Kill “Tebtr.i-“ Enci bnd Suo

Private Suo ruriii L’^ad () Comricinal .Enabit ‘•i True Coi’mdnd2 . Er.JDied r.aisp Command i. EnaO-l ed - i-alse Command4 . Eriab i-ed - ‘: ^lae Commands.Enabled = False Textl.Enabled =- False Text2.Enabled = False Text3.Enabled = False Text4.Enabled = False Text5.Enabled = False Text6.Enabled = False Text7.Enabled = False End Sub

Private Sub Textl_KeyPress(KeyAscii As Integer) If KeyAscii = 13 Then

If Textl.Text = “” Then

Label7.Caption = “Предупреждение” Text7.Text = “Введите фамилию” Textl.SetFocus GoTo Finish End If

If Label7.Caption = “Предупреждение” Then Label7.Caption = “Результат” Text7.Text = “” End If Text2.SetFocus End If Finish:

End Sub

Private Sub Text2 Keypress(KeyAscii As Integer) If KeyAscii ^ 13 Then

If Text2.Text = “” Then

Label7.Caption = “Предупреждение” Text7.Text = “Введите должность” Text2.SetFocus GoTo Finishi End If

If Label7.Caption = “Предупреждение” Then Label7.Caption = “Результат” Text7.Text = “” End If

Text3.SetFocus End If Finishi:

End Sub

Private Sub Text3 Keypress(KeyAscii As Integer) If KeyAscii ~= 13 Then

If Text3.Text = “” Then

Label7.Caption = “Предупреждение” Text7.Text - “Введите подразделение Text3.SetFocus GoTo Finish2 End If

If Label7.Caption = “Предупреждение” Then Ldbei7.Caption = “Результат” Text 7.Text = “” End If Text4.SetFocus End If Finish2:

End Sub

Private Sub Text4_KeyPress(KeyAscii As Integer) Dim Peremen As Primer

If KeyAscii =. 1 3 Then

It Text 4.Text = “” Then

Labei7.Caption = “Предупреждение” Text7.Text = “Введите зарплату” Text4.SetFocus GoTo Finish3 End If

If Labei7.Caption = “Предупреждение” Then Label7.Caption = “Результат” Text7.Text = “” End If Finish3:

Peremen.Familia = Textl.Text Peremen.Dolgnost = Text2.Text Peremen.Podrazdelenie = Text3.Text Peremen.Zarplata = Text4.Text Put #10, Nzapisi, Peremen Nzapisi = Nzapisi + 1 Command2.Enabled = True Command3.Enabled = True

 

<<<назад | Часть1 | Часть2 | Часть3 | Часть4 | Часть5 | вперёд>>>
 
Webmaster Cheeeck (c) 2001
Hosted by uCoz