Описание
Находят в объектах Recordset типа динамических и
статических наборов записей первую, последнюю, следующую или предыдущую запись,
удовлетворяющую заданным условиям, и делают эту запись текущей записью (только в
рабочей области ядра Microsoft Jet).
наборЗаписей.{FindFirst | FindLast | FindNext | FindPrevious} условия
Параметры
наборЗаписей
Объектная переменная, представляющая
существующий объект Recordset типа динамического или статического набора
записей.
условия
Выражение или переменная типа String,
используемая для поиска записи. Этот аргумент аналогичен предложению
WHERE в инструкции SQL (без зарезервированного слова
WHERE).
Замечания
Если необходимо работать со всеми записями набора, а не только с
записями, удовлетворяющими заданным условиям поиска, следует использовать методы
группы Move, обеспечивающие переход с записи на запись. Для поиска записи
в объекте Recordset табличного типа следует использовать метод
Seek.
Если запись, удовлетворяющая заданным условиям, не обнаружена,
то состояние указателя текущей записи становится неопределенным, и свойству
NoMatch присваивается значение True. Если наборЗаписей содержит
несколько записей, удовлетворяющих условиям отбора, то в методе FindFirst
будет найдена первая из этих записей, в методе FindNext следующая и
т.д.
Начальная позиция и направление поиска для каждого из методов группы
Find представлены в следующей таблице.
FindFirst Начало набора записей Конец набора записей FindLast Конец набора записей Начало набора записей FindNext Текущая запись Конец набора записей FindPrevious Текущая запись Начало набора записей
При вызове метода FindLast ядро базы данных Microsoft Jet
сначала полностью заполняет объект Recordset, а уже потом выполняет
поиск.
Результат применения методов группы Find отличается от
результата применения методов группы Move, в которых просто делается
текущей первая, последняя, следующая или предыдущая запись без применения
условий поиска. После вызова метода группы Find можно применить метод
группы Move.
Всегда необходимо следить с помощью свойства
NoMatch за тем, была ли успешной операция Find. Если запись
обнаружена, свойство NoMatch получает значение False. При
неудачном поиске свойство NoMatch принимает значение True, а
текущая запись становится неопределенной. В этом случае пользователь должен явно
установить указатель текущей записи на допустимую запись.
Применение методов
группы Find к наборам записей, доступ к которым через подключение
ODBC ядра Microsoft Jet, может оказаться неэффективным. Обычно для
поиска конкретной записи удобнее изменить аргумент условия, особенно при работе
с большими наборами записей.
В рабочей области ODBCDirect нельзя
использовать методы группы Find и метод Seek с объектами
Recordset любых типов, поскольку вызов Find или Seek через
сетевое подключение ODBC не является эффективным. Вместо этого следует
создать запрос (используя аргумент источник в методе OpenRecordset) с
соответствующим предложением WHERE, которое ограничивает возвращаемые
записи теми, которые удовлетворяют условиям, указанным в методе Find или
Seek.
При подключении ядра Microsoft Jet к базам данных
ODBC и использовании больших динамических объектов Recordset,
пользователь может обнаружить, что выполнение методов Find, а также
использование свойств Sort или Filter является достаточно
медленным. Для повышения быстродействия пользуйтесь запросами SQL со
специализированными предложениями ORDER BY или WHERE, запросами с
параметрами или объектами QueryDef, которые возвращают конкретные
индексированные записи.
При поиске в полях, содержащих даты, следует
использовать американский формат даты (месяц-день-год) даже в случае работы с
локализованной версией ядра базы данных Microsoft Jet; в противном случае
искомая запись может быть не найдена. Перевести дату в нужный формат позволяет
функция Visual Basic Format. Например:
rstEmployees.FindFirst "ДатаНайма > #" & Format(mydate, 'm-d-yy' ) & "#"
Если значение аргумента условия образуется путем строкового слияния с нецелым
числом, а в системной настройке задано использование национального символа
десятичного разделителя, такого как запятая (например, strSQL = "ЦЕНА > "
& lngPrice, где lngPrice = 125,50), то при попытке вызова метода
возникает ошибка. Появление ошибки объясняется тем, что при слиянии число
преобразуется в строковое значение с использованием стандартного символа
десятичного разделителя, а язык SQL ядра Microsoft Jet
поддерживает только американский символ десятичного разделителя (десятичную
точку).
Для обеспечения максимального быстродействия аргумент условия должен
быть задан либо в виде "поле = значение", где поле является индексированным
полем в базовой таблице, либо в виде "поле LIKE префикс" где поле является
индексированным полем в базовой таблице, а префикс представляет начальную часть
искомой строки (например, "ART*").
В общем случае, при прочих равных условиях
метод Seek выполняется быстрее, чем методы Find. Если табличные
объекты Recordset достаточны для решения задач пользователя, следует
применять этот метод.
Пример
Следующая программа использует методы FindFirst,
FindLast, FindNext и FindPrevious для перевода указателя
записи в объекте Recordset на базе указанной строки поиска и команды. Для
выполнения этой процедуры требуется функция FindAny.
Sub FindFirstX()
Dim dbsNorthwind As Database
Dim rstCustomers As Recordset
Dim strCountry As String
Dim varBookmark As Variant
Dim strMessage As String
Dim intCommand As Integer
Set dbsNorthwind = OpenDatabase("Борей.mdb")
Set rstCustomers = dbsNorthwind.OpenRecordset( "SELECT Название, Город, Страна " & "FROM Клиенты ORDER BY Название", dbOpenSnapshot)
Do While True
' Принимает данные от пользователя и собирает строку поиска.
strCountry = Trim(InputBox("Введите название страны."))
If strCountry = "" Then Exit Do
strCountry = "Страна = '" & strCountry & "'"
With rstCustomers
' Заполняет набор записей.
.MoveLast
' Находит первую запись, удовлетворяющую строке поиска.
' Выходит из цикла, если такой строки нет.
.FindFirst strCountry
If .NoMatch Then
MsgBox "Не найдены записи для " & strCountry & "."
Exit Do
End If
Do While True
' Сохраняет закладку текущей записи.
varBookmark = .Bookmark
' Принимает способ поиска, выбранный пользователем.
strMessage = "Компания: " & !Название & vbCr & "Место: " & !Город & ", " & _
!Страна & vbCr & vbCr & _
strCountry & vbCr & vbCr & _
"[1 - FindFirst, 2 - FindLast, " & _
vbCr & "3 - FindNext, " & "4 - FindPrevious]"
intCommand = Val(Left(InputBox(strMessage), 1))
If intCommand < 1 Or intCommand > 4 Then Exit Do
' Применяет выбранный метод Find. При неудачном
' поиске возвращает последнюю текущую запись.
If FindAny(intCommand, rstCustomers, strCountry) = False Then
.Bookmark = varBookmark
MsgBox "Запись не найдена Возврат " & "на текущую запись."
End If
Loop
End With
Exit Do
Loop
rstCustomers.Close
dbsNorthwind.Close
End Sub
Function FindAny(intChoice As Integer, rstTemp As Recordset, strFind As String) As Boolean
' Использует способ поиска, выбранный пользователем.
Select Case intChoice
Case 1
rstTemp.FindFirst strFind
Case 2
rstTemp.FindLast strFind
Case 3
rstTemp.FindNext strFind
Case 4
rstTemp.FindPrevious strFind
End Select
' Задает возвращаемое значение по значению свойства NoMatch.
FindAny = IIf(rstTemp.NoMatch, False, True)
End Function