Введение
Всё больше программ использует для хранения данных базы данных. Один из
инструментов для работы с базами данных - библиотека DAO (Data Access Objects).
О ней и пойдёт речь в этой статье.
Для начала нужно подключить эту библиотеку. Для этого в меню
Project|References отметьте пункт "Microsoft DAO
3.6 Objects Library". В составе Visual Basic 6.0 поставляется библиотека
версии 3.6. Если у Вас более ранняя версия - отметьте её, особых различий нет.
Примечание: В этой статье будет рассмотрена работа с
базами MS Access (*.mdb). Бывают и другие типы баз данных, например FoxPro.
Выборка данных
Как осуществить выборку данных? Сначала объявляем переменные.
Dim db As DAO.Database 'Объявляем базу данных
Dim rs As DAO.Recordset 'Объявляем рекордсет
Dim sSQL As String 'Переменная, где будет размещён SQL запрос
Открываем базу данных. Для этого вызываем метод OpenDatabase, и в качестве
параметра передаём полный путь и имя файла базы данных. Обратите внимание, что
db - это объект и поэтому пишем ключевое слово Set.
Set db = DAO.OpenDatabase ("C:\db.mdb")
Формируем строку SQL запроса. Допустим, нам нужно получить все поля
таблицы Orders.
sSQL = "SELECT * FROM Orders;"
Теперь открываем рекордсет. Для этого вызываем метод OpenRecordset объекта
db с первым параметром - SQL запросом. У этого объекта есть ещё 3
необязательных параметра.
Параметр type определяет тип открытия рекордсета. Может принимать значения
одной из этих констант:
Константа |
Значение |
Описание |
dbOpenTable |
1 |
Редактируемый объект. Может быстро находить и возвращать записи при
использовании индексируемых таблиц. |
dbOpenDynaset |
2 |
Обновляемый. Эффективный, поскольку представляет набор ссылок на
данные в основном запросе (а не на реальные данные). Может возвращать
записи из нескольких таблиц благодаря использованию объединения, даже
когда эти таблицы связываются из нескольких баз данных. Такие записи во
многих случаях обновляемы. |
dbOpenSnapshot |
4 |
Могут обрабатываться быстрее, чем объекты Dynaset и Table, в
особенности для небольших наборов записей. Может возвращать записи из
нескольких таблиц благодаря использованию объединения. Такие записей во
многих случаях обновляемы. |
dbOpenForwardOnly |
8 |
Работает быстрее, чем объект Snapshot. Может возвращать записи из
нескольких таблиц благодаря использованию объединению. |
dbOpenDynamic |
16 |
Обновляемый. Может возвращать записи из нескольких таблиц благодаря
использованию объединения. |
Значение по умолчанию для параметра type - dbOpenTable.
Параметр options определяет некоторые характеристики открываемого
рекордсета. Может принимать значение, состоящее из комбинации 11 констант.
Параметр LockEdit (в DAO 3.5 этот параметр называется lockedits)
определяет тип блокировки рекордсета. Может принимать значение одной из 5
констант:
Константа |
Значение |
Описание |
dbReadOnly |
4 |
Только для чтения. |
dbPessimistic |
2 |
Запись блокируется только редактируемая запись. |
dbOptimistic |
3 |
Запись блокируется только при сохранении данных на диск (пока не
закончил работу метод Update). |
dbOptimisticValue |
1 |
Для многопользовательского режима. Перед update (запись на диск)
производится проверка, была ли изменена запись. Если да, то сгенерируется
ошибка, и update не будет произведен. В отличном случае update будет
произведен и на время update запись заблокируется. |
dbOptimisticBatch |
5 |
Пакетная блокировка. |
Set rs = db.OpenRecordset (sSQL)
Рекордсет открыт. Информация, выбранная из базы данных, находится в
объекте rs. Теперь нам нужно достать оттуда данные. Для передвижения по
записям в объекте типа RecordSet используется 5 методов:
Move |
Используется для перемещения к произвольной записи. В качестве
параметра передаётся номер записи. |
MoveFirst |
Используется для перемещения к первой записи. |
MoveLast |
Используется для перемещения к последней записи. |
MoveNext |
Используется для перемещения к следующей записи. |
MovePrevious |
Используется для перемещения к предыдущей записи. |
Также пригодятся свойства BOF и EOF.
BOF возвращает True, если текущая запись находится перед первой записью в
объекте типа Recordset.
EOF возвращает True, если текущая запись находится после последней записи
в объекте типа Recordset.
Текущая запись находится в классе Fields.
With rs
.MoveFirst 'Перемещаемся к первой записи
Do While Not .EOF 'Выполнять пока есть записи
Debug.Print .Fields (0) 'Достаем значение текущей записи для поля номер
0
Debug.Print .Fields (1) 'Достаем значение текущей записи для поля номер
1
Debug.Print .Fields (2) 'Достаем значение текущей записи для поля номер
2
'…
.MoveNext 'Перемещаемся к следующей записи
Loop
End With
Вместо Debug.Print естественно можно поставить и оператор присваивания (=)
a = .Fields (0)
Закрываем рекордсет и базу данных
rs.Close
db.Close
В конце процедуры для того, чтобы освободить память пишем
Set rs = Nothing
Set db = Nothing
Добавление и изменение записей
Для добавления и изменения записей используется похожая технология.
При добавлении записи открываем рекордсет.
Dim db As DAO.Database 'Объявляем базу данных
Dim rs As DAO.Recordset 'Объявляем рекордсет
Dim sSQL As String 'Переменная, где будет размещён SQL запрос
Set db = DAO.OpenDatabase ("C:\db.mdb")
sSQL = "SELECT * FROM Orders;"
Set rs = db.OpenRecordset (sSQL)
Для добавления записи используется метод AddNew объекта типа Recordset.
rs.AddNew
Теперь запись добавлена, и мы заполняем все поля для данной записи.
rs.Fields (0) = "Значение 1"
rs.Fields (1) = "Значение 2"
'...
Обновляем рекордсет.
rs.Update
Закрываем рекордсет и базу данных и освобождаем память.
rs.Close
db.Close
Set rs = Nothing
Set db = Nothing
Код для изменения записи очень похож на предыдущий код. Для изменения
записи используется метод Edit. Также нужно изменить SQL запрос и сделать его
примерно таким:
SELECT * FROM Orders WHERE ID = 23;
Предполагается наличие поля ID, тип которого числовой и его значение
уникально для каждой записи. В данном случае мы будем изменять запись значение
поля ID которой равно 23.
Dim db As DAO.Database 'Объявляем базу данных
Dim rs As DAO.Recordset 'Объявляем рекордсет
Dim sSQL As String 'Переменная, где будет размещён SQL запрос
Set db = DAO.OpenDatabase ("C:\db.mdb") 'Открываем базу
sSQL = "SELECT * FROM Orders;" 'Формируем запрос
Set rs = db.OpenRecordset (sSQL) 'Открываем рекордсет
rs.Edit 'Редактируем запись
'Ставим новые значения
rs.Fields (0) = "Значение 1"
rs.Fields (1) = "Значение 2"
'…
rs.Update 'Обновляем рекордсет
'Закрываем рекордсет и базу данных
rs.Close
db.Close
'Освобождаем память
Set rs = Nothing
Set db = Nothing
Удаление записи
Удаление записи можно произвести двумя путями. Первый путь - исполнение
SQL запроса с командой DELETE. Идентифицировать запись будем по полю ID.
Предполагается, что значения поля ID уникальны для каждой записи. Удаляем
запись, ID которой равно 5.
Dim db As DAO.Database 'Объявляем базу данных
Dim sSQL As String 'Переменная, где будет размещён SQL запрос
Set db = DAO.OpenDatabase ("C:\db.mdb") 'Открываем базу
sSQL = "DELETE FROM Orders WHERE ID=5;" 'Формируем запрос
Рекордсет открывать не нужно, так как нам не надо получать данные из базы.
Для исполнения запроса мы используем метод Execute объекта типа Database. Он
имеет 2 параметра. Первый параметр Query - строка исполняемого запроса. Второй
необязательный параметр options - константа или комбинация констант,
отражающая характеристики исполняемого запроса.
db.Execute sSQL
'Закрываем рекордсет и базу данных
rs.Close
db.Close
'Освобождаем память
Set rs = Nothing
Set db = Nothing
Второй способ удаления записи заключается в использовании метода Delete
объекта типа Recordset. Этот метод удаляет текущую запись. Он не имеет
параметров.
rs.Delete
Количество записей и номер текущей записи
Для определения количества записей в рекордсете используется свойство
RecordCount объекта типа Recordset. Но есть небольшая неувязочка... Если
рекордсет типа Dynaset, Snapshot или ForwardOnly, то свойство RecordCount
покажет число записей, только при достижении последней записи. В этом случае
нужно сразу переместиться к концу рекордсета.
rs.MoveLast
rs.MoveFirst
Номер текущей записи определяется с помощью свойства AbsolutePosition.
Отсчёт начинается с нуля. Т.е. если текущая запись - первая, то
AbsolutePosistion покажет 0. Если текущая запись находится до первой или после
последней, то свойство AbsolutePosition покажет -1.
Свойство PercentPosition возвращает процентное отношение номера текущей записи
от количества записей.
Debug.Print "Количество записей " & CStr (rs.RecordCount)
Debug.Print "Текущая запись " & CStr (rs.AbsolutePosition + 1)
Debug.Print Cstr (Round (rs.PercentPosition, 2)) & " %"
Пример работы с DAO можно взять здесь.