Описание
Находят в объектах 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