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

Е.А. Бессонов Access. Объекты доступа к данным

.pdf
Скачиваний:
58
Добавлен:
19.08.2013
Размер:
259.46 Кб
Скачать

10

OpenRecordSet и после этого становится доступным только для чтения. NoMatch. Если это свойство имеет значение True, то это означает, что операция Find или Seek не смогла найти запись, удовлетворяющую заданному критерию.

RecordCount. Для табличных наборов возвращает общее число записей. Для статических и динамических наборов записей RecordCount возвращает число записей, к которым осуществлялось обращение. Чтобы получить полное число записей, нужно сначала вызвать метод MoveLast для перемещения указателя текущей записи в конец набора, а затем ис-

пользовать RecordCount.

Sort. Устанавливает или возвращает порядок сортировки записей. Для сортировки нужно использовать строку, представляющую предложение Order BY языка SQL без ключевых слов Order By. При этом названия полей следует заключить в квадратные скобки. Порядок сортировки можно определить на основе одного или нескольких полей. Для того чтобы после установки порядка сортировки сортировка осуществилась, нужно открыть новый объект RecordSet на основе того объекта, для которого она установлена.

Type. Тип объекта RecordSet (Db_Open_Table, Db_Open_Dynaset, Db_Open_Snapshot). Это свойство инициализируется при вызове метода OpenRecordSet и используется только для чтения.

Пример 1

Function СписокПредметов (frm As Form) Dim rst As RecordSet

Set rst = frm.RecordSetClone rst.MoveFirst

Do

Debug.Print rst(0); “ “; rst(1) rst.MoveNext

Loop Until rst.Eof End Function

Функции СписокПредметов передается аргумент frm, являющийся ссылкой на открытую форму (тип Form). Здесь мы видим, что в одной процедуре могут использоваться как объекты Access (формы, отчеты, элементы управления), так и Jet (RecordSet). Объектной переменной rst присваивается значение свойства формы RecordsetClone. Это свойство является ссылкой на базовый набор записей формы. Таким образом,

11

можно получить доступ к объекту RecordSet, минуя обращение к сеансу и базе данных.

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

Цикл Do…Loop выполняется, пока не встретится конец набора, когда свойство набора Eof примет значение True.

Втеле цикла выполняются 2 инструкции. Инструкция Debug.Print выводит в окно отладки строку, состоящую из трех частей. Для разделения частей используется точка с запятой. Выражение вида rst(n) определяет поле набора по его порядковому номеру. При этом нужно помнить, что нумерация в семействах начинается с нуля. Таким образом, в строку окна отладки выдается первое и второе поле базового набора записей формы, переданной в качестве аргумента. Поля разделены пробелом. Вторая инструкция тела цикла Do вызывает метод MoveNext объекта RecordSet, перемещающий указатель на следующую запись. Цикл Do выводит в окно отладки все записи формы frm.

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

?СписокПредметов (Forms![Экзаменаторы])

После нажатия Enter функция СписокПредметов запускается и выдает результат в виде “Номер экзаменатора, Название предмета”.

0Информатика

1Математика

2

Если в заголовок формы Экзаменаторы поместить кнопку, а свойству кнопки “Нажатие кнопки” присвоить выражение “=СписокПредметов([Form])”, то при каждом нажатии этой кнопки будут выдаваться номера экзаменаторов и названия предметов.

Пример 2

Public Sub SQLRecords () Dim rst As RecordSet Dim db As Database

Dim strSQL As String Set db = CurrentDB()

StrSQL=“SELECT * FROM Преподаватели WHERE [Звание] = ‘До-

цент’”

Set rst = db.OpenRecordSet (strSQL)

12

Do Until rst.Eof Debug.Print rst!ФИО rst.MoveNext

Loop End Sub

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

“DBEngine.WorkSpaces(0).Datsbases(0)”. Переменной rst типа RecordSet

присваивается ссылка на объект типа RecordSet. Этот объект формируется на базе запроса strSQL с помощью метода OpenRecordset. Мы здесь не рассматриваем запросы на языке SQL. Предполагается, что читатель знаком с ними. Из содержания строки strSQL видно, что из таблицы Преподаватели извлекаются все поля и записи, в которых преподаватель имеет ученое звание Доцент.

Цикл Do…Loop выдает в окно отладки фамилии всех экзаменато- ров-доцентов. Некоторые фамилии могут встретиться несколько раз, поскольку после слова SELECT не поставлено слово DISTINCT.

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

Пример 3

Function SQLSortFilter()

Dim db As Database, rst As RecordSet, strSQL As String Set db As CurrentDB()

strSQL = “SELECT * FROM Фамилии WHERE Отдел = 3 Order By Фамилия”

Set rst =db.OpenRecordSet(strSQL) Do Until rst.Eof

Debug.Print rst!Фамилия rst.MoveNext

Loop

End Function

Здесь также используется запрос на языке SQL для формирования объекта RecordSet. При этом сам запрос, а не переменная, указывающая на него, размещается на месте аргумента метода OpenRecordset. В запросе используются условие отбора записей (Отдел = 3) и сортировка записей по полю Фамилия в возрастающем порядке (Order By Фами-

13

лия). Пусть, например, таблица Фамилии имеет вид:

Код

Отдел

Фамилия

1

2

Петухов

2

3

Уточкин

3

3

Гусаков

Вокне отладки появится сообщение:

?SQLSortFilter()

Гусаков

Уточкин

Пример 4

Function DAOSort()

Dim rst As RecordSet, rstSort As RecordSet, db As Database Set db = DBEngine.WorkSpaces(0).Databases(0)

Set rst = db.OpenRecordset (“Фамилии”,Db_Open_Dynaset) rst.Sort = “Фамилия”

Set rstSort = rst.OpenRecordSet() Debug.print “Неотсортированный список:” Do until rst.Eof

Debug.Print rst!Фамилия rst.MoveNext

Loop

Debug.Print “Сортировка по фамилии:” Do Until rstSort.Eof

Debug.Print rstSort!Фамилия RstSort.MoveNext

Loop

End Function

Запуск процедуры можно организовать с помощью кнопки на форме, имеющей свойство “Нажатие кнопки”, равное выражению

“=DaoSort()”.

Набор данных rst в данном примере образуется на основе объекта Database. Метод OpenRecordSet в данном случае имеет 2 аргумента. Первый аргумент указывает на таблицу Фамилии, данные которой образуют набор Recordset. Второй аргумент – константа Db_Open_Dynaset

– определяет набор как динамический.

Свойству набора Sort присваивается имя поля Фамилия, по которому производится сортировка в возрастающем порядке. Для осуществ-

14

ления сортировки создается второй набор strSort типа RecordSet на основе первого набора с учетом значения свойства Sort.

Если таблица Фамилии имеет всего один столбец, то можно, например, получить в окне отладки:

? DAOSort()

Неотсортированный список: Овечкин Козлов Баранов

Сортировка по фамилии: Баранов Козлов Овечкин

Пример 5

Sub Замена()

Dim db As Database, rst As RecordSet

Set db = DBEngine.WorkSpaces(0).Databases(0)

Set rst = db.OpenRecordset (“Расписание экзаменов”, Db_Open_Table) rst.Index = “Предмет”

rst.MoveFirst Do Until rst.Eof

If rst![Название предмета] = ”Информатика” Then rst.Edit

rst![Название предмета] = “Информационные технологии” rst.Update

End If rst.MoveNext

Loop rst.Close End Sub

В данном примере используется набор данных rst табличного типа (при создании объекта RecordSet использована константа Db_Open_Table). Это позволяет использовать для упорядоченного просмотра таблицы “Расписание экзаменов” свойство Index. Этому свойству присваивается имя существующего индекса “Предмет”. Заметим, что если нет подходящего готового индекса, его можно создать мето-

дом CreateIndex.

15

В цикле Do…Loop осуществляется редактирование записей. После создания переменной, связанной с набором записей типа

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

1)переместиться на нужную запись;

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

3)внести необходимые изменения в запись;

4)применить метод Update для сохранения изменений в текущей записи.

Если не применить метод Update, новые данные будут потеряны. Если не применить метод Edit перед попыткой изменить значение текущей записи, то произойдет ошибка стадии выполнения.

Врезультате выполнения процедуры Замена в таблице “Расписание экзаменов” название предмета “Информатика” будет заменено на “Информационные технологии”.

Пример 6

Function КтоНачальник () As Integer

Dim frm As Form, rst As RecordSet, S As String Set frm = Screen.ActiveForm

Set rst = frm.RecordSetClone rst.BookMark = frm.BookMark S = frm.BookMark

If frm.Подчиняется > 0 Then

rst.FindFirst “[Сотрудник] =” & rst![Подчиняется] frm.BookMark = rst.BookMark

Else

MsgBox frm.[Фамилия] & “ не имеет начальника” frm.BookMark = S

End If rst.Close End Function

Переменной frm присваивается ссылка на активную форму, а rst – на набор записей типа RecordSet, являющийся базовым набором этой формы. Форма имеет закладку, связанную с текущей записью формы.

16

Именно эту запись можно видеть в режиме формы. Закладка является текстовой строкой и запоминается в переменной S.

Поля Сотрудник и Подчиняется содержат номера соответствующих сотрудников (Сотрудник – номер самого сотрудника, а Подчиняется – номер его начальника). Если у сотрудника нет начальника, то поле Подчиняется содержит нуль.

Если Подчиняется > 0, то у сотрудника есть начальник. В этом случае применяется метод FindFirst (перейти к первой записи, удовлетворяющей условию в аргументе метода). В условии сравнивается значение элемента управления формы Сотрудник с значением поля Подчиняется базового набора записей. В результате отыскивается запись начальника данного сотрудника. На нее устанавливается указатель текущей записи набора RecordSet. Форма продолжает показывать прежнего сотрудника. Инструкция frm.BookMark = rst.BookMark присваивает закладке формы значение закладки базового набора. Теперь форма показывает запись не сотрудника, а его начальника.

Если у сотрудника поле Подчиняется пусто, условие в инструкции If не выполняется. В этом случае выдается информация вида “Белкин не имеет начальника”, восстанавливается сохраненная в строке S закладка, и форма продолжает показывать данные того же сотрудника.

Пусть, например, базовым набором формы является таблица Сотрудники вида

Фамилия

Сотрудник

Подчиняется

Лисицына

1

2

Белкин

2

0

Зайцева

3

2

Волков

4

3

Медведев

5

3

Из таблицы видно, что у Белкина нет начальника. Ему подчиняются Лисицына и Зайцева. Зайцевой подчиняются Волков и Медведев. Пусть текущей является запись Медведева. В заголовке формы расположена кнопка, запускающая функцию КтоНачальник. После нажатия этой кнопки текущей становится запись Зайцевой.

Пример 7

Private Sub Кнопка1_Click()

Dim rst As RecordSet, S As String

Set rst = Me.RecordSetClone

17

rst.BookMark = Me.BookMark S = Me.BookMark

If Not IsNull (rst!Подчиняется) Then

rst.Move (rst!Подчиняется – rst!Сотрудник) BookMark = rst.BookMark

Else

MsgBox [Фамилия] & “ без начальника”

BookMark = S Exit Sub

End If rst.Close End Sub

Процедура Кнопка1_Click расположена в модуле активной формы. Для обращения к форме использовано слово Me. Слово Me означает “Форма, в модуле которой расположена данная процедура”. Процедура запускается при нажатии (событие Click) кнопки Кнопка1. Процедура выполняет ту же задачу, что и предыдущая, то есть осуществляет переход к записи начальника. Из предыдущего примера видно, что номера сотрудников идут строго по порядку. Это избавляет от необходимости производить поиск записи методом Find, а сразу перейти к нужной записи с помощью метода Move.

Рассмотрим тот же пример. Запись Волкова имеет номер 4, а нужно перейти к записи номер 3. В MS Access записи не имеют номеров и перейти к записи по ее номеру нельзя. Для перемещения по записям в наборе RecordSet можно использовать методы группы Move для перехода к первой записи (MoveFirst), к последней (MoveLast), к предыдущей

(MovePrevious), к следующей (MoveNext). Метод Move перемещает указатель вперед или назад по отношению к закладке. В рассматриваемом примере происходит перемещение на разность (Подчиняется – Сотрудник) записей. Если текущей была запись Волкова, то нужно переместиться на 3 – 4 = -1 записей, т.е. к предыдущей записи.

Пример 8

Private Sub Form_AfterUpdate()

Dim i As Integer

For i = 0 To Me.Count – 1

If Me(i).Tag = “1” Then

Me(i).DefaultValue = “””” & Me(i).Value & “”””

18

End If Next

End Sub

В процедуре используется форма обращения Me к форме, в модуле которой расположена данная процедура обработки события. Цикл For перебирает все элементы управления формы, пронумерованные от нуля до Me.Count - 1. У каждого элемента управления проверяется его свойство Tag (дополнительные сведения). Если в дополнительные сведения записана единица, то свойству DefaultValue (значение по умолчанию) присваивается значение Value этого элемента (Me(i)). Значением свойства DefaultValue должен быть текст. Правая часть оператора присваивания должна быть заключена в кавычки. Для представления текста в виде кавычек нужно повторить кавычки 4 раза (пара кавычек в кавычках), так как в текстовой строке для представления кавычек используют пару кавычек.

Если для поля в таблице или для элемента управления формы в режиме конструктора устанавливается свойство “Значение по умолчанию”, MS Access при выводе новой записи в форме автоматически вставляет значение этого свойства в данное поле или в данный элемент. Присваивание свойству “Значение по умолчанию” в режиме конструктора полезно в том случае, если нужно использовать некоторое значение во всех новых записях или применить выражение, включаемое во все новые записи. Так, если это свойство содержит выражение =Date(), то в данном элементе управления всегда будет выводиться текущая дата. Чтобы указать, что мы имеем дело не с выражением или именем поля, обычный текст заключается в кавычки.

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

Пример 9

Sub Должность_AfterUpdate()

Dim rst As Recordset

19

Dim Критерий As String, k As Integer

Критерий = “Должность = “”” & Должность & “””” Set rst = Me.RecordsetClone

rst.FindLast Критерий If Not rst.NoMatch Then

For k = 0 To Me.Count – 1 If Me(k).Tag = “1” Then

Me(k).Value = rst (Me(k).Name) End If

Next End If End Sub

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

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

Метод FindLast находит последнюю запись, в которой та же должность, что и только что введенная. Если запись с такой же должностью найдена, цикл For обеспечивает просмотр всех элементов управления формы. Если свойство Tag содержит единицу, выполняется присваивание свойству Value этого элемента результата вычисления выражения rst(frm(k).Name). В этом выражении используется элемент строки базового набора, найденной методом FindLast. Значение этого поля присваивается соответствующему элементу новой записи.

Пусть, например, базовая таблица имеет вид

Пре-

Фамилия

Степень

Звание

Должность

пода-

ватель

 

 

 

 

 

 

1

Блохин

 

 

Ассистент

2

Тараканов

Д.т.н

Доцент

Профессор

3

Комаров

К.т.н

Доцент

Доцент

4

Бабочкин

Д.т.н

Профессор

Профессор

5

Шмелев

К.т.н

 

Ст.преподаватель

6

 

К.т.н

Доцент

Доцент