Обычно, если вам нужно создать например базу данных MDB с одной таблицей, то лучше всего создать простой класс, чем использовать контрол “Data”. Для базы данных сначала необходимо создать алгоритм разделения записей, мы возьмём самый малоиспользуемый символ chr(0). Также нам потребуется не только класс для работы с файлом, но и класс для хранения, редактирования, удаления записей.
Создайте стандартный проект и добавьте в него класс-модуль с именем “clsVault”, мы будем использовать его для управления записями базы данных. Этот класс мы виртуально разделим на две части: первая - это открытие и сохранение файла базы данных, вторая - для управления записями.
Когда мне пришлось впервые создавать собственный класс для базы данных, я подумал использовать класс «Collection» входящий в состав VBA, но его использование оказалось неприемлемо.
Для обработки базы данных мы будим использовать одномерный строковый массив, объявим его в классе вместе с другими переменными раздела «General Declarations»
Option Explicit
Private arrData() As String ‘Общий массив для хранения данных
Private lngIndex As Long, lngIdx As Long ‘Две переменные для схожих целей
Давайте рассмотрим текст открытия файла базы данных и его обработка с последующим выводом в массив
Public Sub Load(ByVal strFileName As String)
Dim strFileData As String ‘Временная переменная для хранения всех данных из открываемого файла
Open strFileName For Binary Access Read As #1 ‘Откроем файл для чтения
strFileData = Space(LOF(1)) ‘Определим размер считываемых данных
Get #1, , strFileData ‘Считаем данные
Close ‘Закроем файл
arrData = Split(strFileData, Chr(0)) ‘Строковая функция Split разбивает неразмеченный
‘массив на куски строки разделённые указанным символом, в данном случае это нуль-символ chr(0)
End Sub
Теперь рассмотрим процедуру сохранения базы данных в файл
Public Sub Save(ByVal strFileName As String)
Open strFileName For Output Access Write As #1 ‘Откроем файл для записи
Print #1, Join(arrData, Chr(0)); ‘до недавнего времени я не знал о столь полезной функции Join, которая
‘объединяет все переменные массива в одну строку вставляя между ними указанный символ,
‘в данном случас это нуль-символ
chr(0)
Close ‘Закроем файл
End Sub
Всё, с сохранением и открытием мы разобрались, теперь осталось самое главное - работа с записями базы данных. Если вы читаете эту статью для применения и пытаетесь это понять, то скажу сразу, самое сложное это удаление записей, т.к. в Бейсике я не смог найти функции или процедуры выполняющей эту задачу.
Сперва рассмотрим функцию определения - есть ли в массиве записи
Public Function IsArray() As Boolean
On Error GoTo Handler ‘При ошибке перейдём на её обработку
If UBound(arrData) > -1 Then IsArray = True ‘Если в массиве есть хоть одна(ноль - это одна) запись,
‘для того, чтобы массив начинался не с нуля, а с единицы, в разделе объявлений надо указать
‘Option Base 1 но это будет не удобно.
Exit Function ‘выйдем из функции
Handler: ‘Обработка ошибок
If Err.Number = 9 Then IsArray = False ‘В данном случае может возникнуть только одна ошибка
‘«Нижний индекс вне
диапазона», т.е. массив ещё не измерен и в нём нет записей.
‘Эту функцию пришлось мне придумать самому, т.к. в Бейсике я ничего подобного
‘найти не смог, а функция vba.IsArray в любом случае возвращает истину т.к.
‘наша переменная является неизмеренным массивом.
End Function
Теперь рассмотрим процедуру очистки массива
Public Sub Clear()
On Error Resume Next
Erase arrData ‘Очищаем массив
End Sub
Теперь нам необходимо написать свойство для установки и чтения индекса, назовём его указателем, в данной программе указатель будет указывать на запись, указателем является переменная, объявленная нами в самом начале «lngIndex»
Public Property Get Index() As Long
On Error Resume Next
If IsArray = False Then Exit Property ‘Если наш массив ещё не измерен, выйдем из получения свойства
Index = lngIndex ‘Присвоим свойству значение
End Property
Public Property Let Index(ByVal lngNewIndex As Long)
On Error Resume Next
If IsArray = False Then Exit Property ‘Если наш массив ещё не измерен, выйдем из установки свойства
lngIndex = lngNewIndex ‘Присвоим переменной значение
End Property
Ну вот и дошли до добавления записей, посмотрим!
Public Sub Add()
If IsArray = True Then ‘Если массив измерен
ReDim Preserve arrData(UBound(arrData) + 1)
‘Переизмерим массив на одно значение больше,
‘чем общее количество записей
Else ‘Если же массив ещё не имерен, то
ReDim arrData(0) ‘Измерим его - создадим одну запись
End If
End Sub
С добавлением всё ясно, а вот теперь рассмотрим процедуру удаления записей
Public Sub Remove()
If IsArray = False Then Exit Sub ‘Если в массиве нет записей, то ничего делать не будем
If UBound(arrData) = 0 Then ‘Если в массиве только одна запись
Clear ‘Очистим массив
Else ‘Если больше
Dim arrTemp() As String ‘Создадим временный строковый массив
ReDim arrTemp(UBound(arrData) - 1) ‘Т.к. мы за один раз удаляем только одну запись, то и
‘измерим массив на одну запись меньше чем в общем массиве
For lngIdx = LBound(arrData) To Index - 1
‘Сначала мы создадим цикл с присвоением всех
‘значений до удаляемой записи
arrTemp(lngIdx) = arrData(lngIdx)
‘Присвоим значение
Next
For lngIdx = Index + 1 To UBound(arrData)
‘А теперь цикл начинается со следующей
‘записи после удаляемой
arrTemp(lngIdx - 1) = arrData(lngIdx)
‘Присвоим значение
Next
Clear ‘Очистим общий массив
ReDim arrData(UBound(arrTemp)) ‘Размерим его
For lngIdx = LBound(arrTemp) To UBound(arrTemp)
‘Создадим цикл
arrData(lngIdx) = arrTemp(lngIdx)
‘Присвоим значение
Next
End If
End Sub
Я бы назвал эту процедуру универсальной, да и весь класс тоже, на его создание у меня ушло около трёх часов;-).
Ну теперь напишем получение и изменение текста в записях
Public Property Get Text() As String
If IsArray = False Then Exit Property
Text = arrData(lngIndex) ‘Отправим значение ячейки
End Property
Public Property Let Text(ByVal strNewText As String)
If IsArray = False Then Exit Property
arrData(lngIndex) = strNewText ‘Установим значение ячейки
End Property
Ну и напоследок немаловажная функция для получения общего количества записей
Public Property Get Count() As Long
If IsArray = True Then
Count = UBound(arrData)
Else
Count = -1
End If
End Property
Раз вы дочитали до сюда, значит это уже неплохо! В данном классе вас должен волновать только индекс записи - объясню: если в базе данных например три записи, а вам необходимо поменять значение у второй, то сначала вам надо поставить указатель на вторую запись.
Для проверки класса:
Option Explicit
Private Vault As New clsVault
И в Form_Load например:
Vault.Add
Vault.Index = 0
Vault.Text = “Привет Мир!”
Для удаления записи также на неё сначала необходимо поставить указатель.
Вот и всё!