Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Lab16

.doc
Скачиваний:
13
Добавлен:
02.06.2015
Размер:
59.39 Кб
Скачать

Лабораторная работа № 16

Работа с пользовательскими типами данных и файлами произвольного доступа в Microsoft Visual Basic for Applications

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

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

Public Type FamilyData

Name As String * 30

Surname As String * 30

End Type

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

Dim Fam As FamilyData

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

Декларацию типов данных выполняют в модулях.

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

Открытие файла выполняется с указанием длины записи:

Open "Fam1.dat" For Random As Num Len = Len(Fam)

Здесь в качестве аргумента функции Len указывается переменная типа FamilyData, продекларированная так, как указано выше.

Перед чтением файла следует определить количество записей в нем:

RecCount = LOF(Num) / Len(Fam)

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

Чтение записи файла выполняется при помощи команды Get:

Get #Num, i, Fam

Здесь i – номер записи. В результате выполнения этой операции запись будет прочитана в переменную Fam, определенную выше.

Запись переменной указанного типа в файл выполняется следующей командой:

Put #Num, i, Fam

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

Каждый класс хранится в специальном модуле – модуле класса. Создание модуля класса выполняется при помощи команды “ВставкаМодуль класса” (“InsertClass Module”).

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

Рассмотрим пример создания класса Vector, моделирующего двумерный вектор. У объектов класса «вектор» будут определены три свойства: координата абсциссы, координата ординаты и длина вектора (это свойство является свойством только для чтения). Кроме того, для объектов класса «вектор» будут определены два метода, первый из которых возвращает вектор, являющийся результатом покомпонентного произведения вектора на число, а второй — результат скалярного произведения двух векторов.

Текст модуля класса Vector:

' X - координата абсциссы

' У - координата ординаты

Dim X, Y As Double

'

Public Property Get Abscissa() As Double

' Возвращает значение свойства Абсцисса

Abscissa = X

End Property

Public Property Get Ordinate() As Double

' Возвращает значение свойства Ордината

Ordinate = Y

End Property

'

Public Property Let Abscissa(ByVal NewAbscissa As Double)

' Устанавливает значение свойства Абсцисса

If Not IsNumeric(NewAbscissa) Then

MsgBox "Абсцисса не является числом", vblnformation, "VBA"

Exit Property

End If

X = NewAbscissa

End Property

Public Property Let Ordinate(ByVal NewOrdinate As Double)

' Устанавливает значение свойства Ордината

If Not IsNumeric(NewOrdinate) Then

MsgBox "Ордината не является числом", vblnformation, "VBA"

Exit Property

End If

Y = NewOrdinate

End Property

Public Property Get Length() As Double

' Возвращает длину вектора. Это свойство только для чтения

Length = Sqr(X ^ 2 + Y ^ 2)

End Property

Public Sub AddVector(ByVal AVector As Вектор)

' Покоординатное сложение двух векторов

X = X + AVector.Abscissa

Y = Y + AVector.Ordinate

End Sub

Public Sub MultiplyByNum(ByVal Num As Double)

' Покоординатное умножение вектора на число

If Not IsNumeric(Num) Then

MsgBox "Число, на которое умножается вектор," & Chr(13) _

& "на самом деле не число", vblnformation, "VBA"

Exit Sub

End If

X = Num * X

Y = Num * У

End Sub

Public Function ScalarMult(ByVal AVector As Вектор)

' Скалярное произведение векторов

ScalarMult = X * AVector.Abscissa + Y * AVector.Ordinate

End Function

Private Sub Class_Initialize()

' Инициализация класса

' Vector (1, 0)

X = 1

Y = 0

End Sub

Функции Property Get предназначены для получения значений свойств объекта класса. При этом свойство может как храниться в переменной (X и Y в данном примере), а может вычисляться непосредственно в момент получения (свойство Length). Полный синтаксис:

[Public | Private] [Static] Property Get имя [(списокАргументов)] [As тип]

[инструкции]

[имя = выражение]

[Exit Property]

[инструкции]

[имя = выражение]

End Property

Если вместо объявления Public использовать Private, то свойство станет «видимым» только для процедур модуля класса. Директива Static стимулирует сохранение локальных переменных данной процедуры между ее запусками. Команда Exit Property вызывает завершение процедуры.

Функции Property Let имеют обратное назначение, т.е. предназначены для присваивания значения свойству объекта класса. Если значение свойства может вычисляться, но не может устанавливаться, то метод Property Let для такого свойства не определяется. Полный синтаксис:

[Public | Private] [Static] Property Let имя [(списокАргументов)]

[инструкции]

[Exit Property]

[инструкции]

End Property

В случае, если свойство определяется не как объект простейшего типа (Double, Single, String и т.п.), а как объект класса, то вместо Property Let используется Property Set, имеющий аналогичный синтаксис.

Метод Class_Initialize используется для инициализации при создании нового экземпляра класса. При необходимости может быть определен метод Class_Terminate для завершения работы с объектом.

Использование класса «вектор» из приведенного примера проиллюстрировано в следующем фрагменте:

Sub VectorDemo()

Dim a, s As Double

' Объявление двух векторов

Dim MyVector, AnotherVector As Vector

' Создание вектора

Set МойВектор = New Вектор

' Установка координат вектора

With МойВектор

.Abscissa = 1

.Ordinate = 1

End With

'

' Определение длины вектора

а = MyVector.Length

MsgBox CStr(a)

'

' Умножение вектора на 2

MyVector.MultiplyByNum Num:=2

'

' Определение координат преобразованного вектора

MsgBox CStr(MyVector.Abscissa)

MsgBox CStr(MyVector.Ordinate)

'

' Создание еще одного вектора

Set AnotherVector = New Vector

With AnotherVector

.Abscissa = 2

.Ordinate = 3

End With

'

' Сложение векторов

MyVector.AddVector AVector:=AnotherVector

'

' Определение координат преобразованного вектора

MsgBox CStr(MyVector.Abscissa)

MsgBox CStr(MyVector.Ordinate)

'

' Определение скалярного произведения

s = MyVector.ScalarMult(AVector:=AnotherVector)

MsgBox CStr(s)

End Sub

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

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]