Типы данных определяемые пользователем
Создание и использование
Содержание
- UDT – создание
UDT – объявление переменных
UDT – присвоение и получение значений
UDT – содержащий массив
UDT – аргумент процедуры
UDT – содержащий объект
UDT – составной
UDT – копирование
UDT – создание
Кроме базовых типов данных: Integer, Long, String и т.д., Visual Basic поддерживает типы данных, определяемые пользователем – User Defined Types (далее UDT). Комбинируя переменные различных типов, можно создать UDT (известный, в языке программирования Cи, как структура). UDT используется, для создания переменной, содержащей несколько взаимосвязанных частей информации.
Для создания UDT используется ключевое слово Type:
- Код: Выделить всё
'Синтаксис VB
[Private | Public] Type TypeName
Element1 [([Size])] As DataType
[Element2 [([Size])] As DataType]
End Type
Определение общего (Public) UDT, возможно только в секции (General) (Declarations) модуля. В этом случае, тип будет доступен во всех процедурах всех форм, модулей и модулей классов. Для определения UDT в форме или модуле класса, следует использовать ключевое слово Private, поскольку объявление общего типа в данной ситуации не допускается. При этом, область видимости такого типа, будет ограничена контейнером, где он объявлен.
- Код: Выделить всё
Private Type MyDataType
или
- Код: Выделить всё
Public Type MyDataType
Например, можно создать UDT, содержащий информацию о компьютере:
- Код: Выделить всё
' Декларация в стандартном модуле
Private Type SystemInfo
CPU As Variant
Memory As Long
VideoColors As Integer
Cost As Currency
PurchaseDate As Variant
End Type
UDT – объявление переменных
Определив UDT, вы можете использовать его для объявления переменных этого типа. Эти переменные могут быть локальными, глобальными или переменными контейнера:
- Код: Выделить всё
Dim MySystem As SystemInfo
Private YourSystem As SystemInfo
Таблица 1. Контейнеры, где можно объявить UDT и его переменную.
Примечание! UDT, объявленный без ключевого слова, по умолчанию считается объявленным, как Public. Если требуется UDT уровня модуля или модуля класса, его следует объявлять, используя ключевое слово Private.
UDT – присвоение и получение значений
Доступ к элементам переменной UDT осуществляется, по аналогии с доступом к свойствам, путем указания точки после имени переменной.
- Код: Выделить всё
MySystem.CPU = "486"
If MySystem.PurchaseDate > #1/1/92# Then
При этом переменные одинакового типа можно присваивать не поэлементно, а напрямую:
- Код: Выделить всё
YourSystem = MySystem
UDT – содержащий массив
UDT, может содержать обычный (фиксированного размера) массив:
- Код: Выделить всё
Type SystemInfo
CPU As Variant
Memory As Long
DiskDrives(25) As String ' Фиксированный массив
VideoColors As Integer
Cost As Currency
PurchaseDate As Variant
End Type
А также, может содержать динамический массив.
- Код: Выделить всё
Type SystemInfo
CPU As Variant
Memory As Long
DiskDrives() As String ' Динамический массив
VideoColors As Integer
Cost As Currency
PurchaseDate As Variant
End Type
Доступ к значениям элементов массива, UDT осуществляется, по аналогии с доступом к свойству объекта.
- Код: Выделить всё
Dim MySystem As SystemInfo
ReDim MySystem.DiskDrives(3)
MySystem.DiskDrives(0) = "1.44 MB"
Также, можно объявить массив UDT:
- Код: Выделить всё
Dim AllSystems(100) As SystemInfo
Для доступа к элементам этого типа, следуем тем же правилам.
- Код: Выделить всё
AllSystems(5).CPU = "386SX"
AllSystems(5).DiskDrives(2) = "100M SCSI"
UDT – аргумент процедуры
UDT можно использовать, как один из аргументов процедуры.
- Код: Выделить всё
Sub FillSystem (SomeSystem As SystemInfo)
SomeSystem.CPU = lstCPU.Text
SomeSystem.Memory = txtMemory.Text
SomeSystem.Cost = txtCost.Text
SomeSystem.PurchaseDate = Now
End Sub
Примечание! При использовании UDT, в качестве аргумента процедуры в модуле формы, процедура должна быть объявлена, как Private.
UDT, можно использовать в качестве возвращаемого значения функции, а пользовательскую переменную в качестве одно из аргументов процедуры. UDT всегда передаются по ссылке (ByRef), так что процедура может изменить аргумент и вернуть его в вызываемую функцию.
Примечание! Поскольку UDT всегда передается по ссылке, все данные, будут переданы и получены без проблем. Для UDT, содержащих большие массивы данных, это может привести к снижению производительности, особенно в архитектуре клиент-серверных приложений, где процедура может быть запущена на удаленной машине. В такой ситуации, лучше, принимать и передавать только необходимые данные полей UDT.
UDT – содержащий объект
UDT, может содержать объект.
- Код: Выделить всё
Private Type AccountPack
frmInput as Form
dbPayRollAccount as Database
End Type
Примечание! Поскольку тип Variant может хранить различные типы данных, массив Variant может быть использован во многих ситуациях, где можно использовать UDT. Массив Variant, на самом деле более гибкий, чем UDT, потому что можно изменить тип данных, хранящихся в каждом его элементе в любое время, и можно сделать массив динамическим, и изменять размер по мере необходимости. Однако, массив Variant, всегда использует больше памяти, чем эквивалентные UDT.
UDT – составной
UDT, может быть составным. В этом случае важна последовательность определения UDT. Сначала нужно определить основной UDT, который будет использоваться далее в составных UDT. Если не соблюдать это правило, то после запуска программы появится сообщение об ошибке. Ниже приводится пример использования составных UDT:
- Код: Выделить всё
Type DriveInfo
Type As String
Size As Long
End Type
Type SystemInfo
CPU As Variant
Memory As Long
DiskDrives(26) As DriveInfo
Cost As Currency
PurchaseDate As Variant
End Type
Dim AllSystems(100) As SystemInfo
AllSystems(1).DiskDrives(0).Type = "Floppy"
UDT, рекомендуется использовать при обработке данных неизменной структуры.
UDT – копирование
Рассмотрим оператор Visual Basic – LSet
- Код: Выделить всё
'Синтаксис VB
LSet StringVariable = StringExpression
LSet – выравнивает строку по левой стороне, при присваивании ей значения, меньшего по размеру, чем исходная строка. Вместо строк могут использоваться UDT.
Вспомним базовые типы данных Visual Basic
Таблица 2. Базовые типы данных Visual Basic
Определимся со значениями некоторых типов данных.
Boolean: может принимать – True или False (в Visual Basic – False, всегда принимает нулевое значение; True – любое значение отличное от нуля)
Decimal: не используется.
Object: ссылка на объект (указатель)
Variant: универсальный тип, значением которого могут быть данные любого из перечисленных выше типов, объекты, значения NULL, Empty и значения ошибок ERROR.
Рассмотрим следующий пример:
- Код: Выделить всё
'Объявление UDT
Private Type TypeExempleOne
Element_1 As Integer
Element_2 As Long
End Type
Private Type TypeExempleTwo
Element_1 As Integer
Element_2 As Long
End Type
Private Sub CopyUDT()
'Объявление переменных UDT
Dim teo As TypeExempleOne
Dim tet As TypeExempleTwo
'Присваивание значений
teo.Element_1 = 11
teo.Element_2 = 1111111
tet.Element_1 = 22
tet.Element_2 = 222222
'Выводим на печать присвоенные значения
Debug.Print "Значения до копирования"
Debug.Print "teo.Element_1 = " & teo.Element_1, "teo.Element_2 = " & teo.Element_2
Debug.Print "tet.Element_1 = " & tet.Element_1, "tet.Element_2 = " & tet.Element_2
'Копируем один UDT в другой
LSet tet = teo
'Выводим на печать значения после копирования
Debug.Print "Значения после копирования"
Debug.Print "teo.Element_1 = " & teo.Element_1, "teo.Element_2 = " & teo.Element_2
Debug.Print "tet.Element_1 = " & tet.Element_1, "tet.Element_2 = " & tet.Element_2
End Sub
В окне Immediate мы увидим следующие значения:
Значения до копирования
teo.Element_1 = 11 teo.Element_2 = 1111111
tet.Element_1 = 22 tet.Element_2 = 222222
Значения после копирования
teo.Element_1 = 11 teo.Element_2 = 1111111
tet.Element_1 = 11 tet.Element_2 = 1111111
При копировании UDT надо придерживаться простого правила: логические (а не фактические) поля должны иметь тот же размер и должны быть расположены в том же порядке, что и соответствующие поля в копируемой структуре.
Немного изменим пример:
- Код: Выделить всё
'Объявление пользовательских типов
Private Type TypeExempleOne
Element_1 As Integer
Element_2 As Long
End Type
Private Type TypeExempleTwo
Element_1 As Boolean
Element_2 As Long
End Type
Private Sub CopyUDT()
'Объявление переменных пользовательского типа
Dim teo As TypeExempleOne
Dim tet As TypeExempleTwo
'Присваивание значений
teo.Element_1 = 11
teo.Element_2 = 1111111
tet.Element_1 = False
tet.Element_2 = 222222
'Выводим на печать присвоенные значения
Debug.Print "Значения до копирования"
Debug.Print "teo.Element_1 = " & teo.Element_1, "teo.Element_2 = " & teo.Element_2
Debug.Print "tet.Element_1 = " & tet.Element_1, "tet.Element_2 = " & tet.Element_2
'Копируем один тип данных в другой
LSet tet = teo
'Выводим на печать значения после копирования
Debug.Print "Значения после копирования"
Debug.Print "teo.Element_1 = " & teo.Element_1, "teo.Element_2 = " & teo.Element_2
Debug.Print "tet.Element_1 = " & tet.Element_1, "tet.Element_2 = " & tet.Element_2
End Sub
В окне Immediate мы увидим следующие значения:
Значения до копирования
teo.Element_1 = 11 teo.Element_2 = 1111111
tet.Element_1 = False tet.Element_2 = 222222
Значения после копирования
teo.Element_1 = 11 teo.Element_2 = 1111111
tet.Element_1 = True tet.Element_2 = 1111111
В первом примере, мы копировали полностью идентичные UDT, в изменённом – скопировали в Boolean переменную, значение типа Integer.
Как видно из таблицы 2, тип Boolean занимает в памяти 2 байта. Тип данных Integer – 2 байта. Тип данных Long занимает в памяти 4 байта. Значит, общий размер каждого UDT, составляет 6 байт, мы не нарушили правило при копировании.
Соответственно, зная размеры занимаемой памяти, базовых типов Visual Basic, можно легко определиться с копированием UDT.
Например: Long(4 байта) = двухэлементный массив Integer(4 байт)
С уважением Diamock.
P.S. К сожалению, не знаю тега таблица, поэтому вставил рисунки.
Жду конструктивные комментарии и критику.