Light-electric.com

IT Журнал
12 просмотров
Рейтинг статьи
1 звезда2 звезды3 звезды4 звезды5 звезд
Загрузка...

Findfirst vba access

Findfirst vba access

Описание
Находят в объектах Recordset типа динамических и статических наборов записей первую, последнюю, следующую или предыдущую запись, удовлетворяющую заданным условиям, и делают эту запись текущей записью (только в рабочей области ядра Microsoft Jet).

Параметры
наборЗаписей
Объектная переменная, представляющая существующий объект Recordset типа динамического или статического набора записей.
условия
Выражение или переменная типа String, используемая для поиска записи. Этот аргумент аналогичен предложению WHERE в инструкции SQL (без зарезервированного слова WHERE).

Замечания
Если необходимо работать со всеми записями набора, а не только с записями, удовлетворяющими заданным условиям поиска, следует использовать методы группы Move, обеспечивающие переход с записи на запись. Для поиска записи в объекте Recordset табличного типа следует использовать метод Seek.
Если запись, удовлетворяющая заданным условиям, не обнаружена, то состояние указателя текущей записи становится неопределенным, и свойству NoMatch присваивается значение True. Если наборЗаписей содержит несколько записей, удовлетворяющих условиям отбора, то в методе FindFirst будет найдена первая из этих записей, в методе FindNext следующая и т.д.
Начальная позиция и направление поиска для каждого из методов группы Find представлены в следующей таблице.

При вызове метода 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. Например:

Если значение аргумента условия образуется путем строкового слияния с нецелым числом, а в системной настройке задано использование национального символа десятичного разделителя, такого как запятая (например, strSQL = «ЦЕНА > » & lngPrice, где lngPrice = 125,50), то при попытке вызова метода возникает ошибка. Появление ошибки объясняется тем, что при слиянии число преобразуется в строковое значение с использованием стандартного символа десятичного разделителя, а язык SQL ядра Microsoft Jet поддерживает только американский символ десятичного разделителя (десятичную точку).
Для обеспечения максимального быстродействия аргумент условия должен быть задан либо в виде «поле = значение», где поле является индексированным полем в базовой таблице, либо в виде «поле LIKE префикс» где поле является индексированным полем в базовой таблице, а префикс представляет начальную часть искомой строки (например, «ART*»).
В общем случае, при прочих равных условиях метод Seek выполняется быстрее, чем методы Find. Если табличные объекты Recordset достаточны для решения задач пользователя, следует применять этот метод.

Пример
Следующая программа использует методы FindFirst, FindLast, FindNext и FindPrevious для перевода указателя записи в объекте Recordset на базе указанной строки поиска и команды. Для выполнения этой процедуры требуется функция FindAny.

Microsoft Access 2010 tutorial:recordset findfirst

Recordset findfirst

VI.5. Finding a record in a table by using recordset method

You use find method to locate the record of the Recordset object. For finding an existing record, there are four methods you can use such as:

These four find methods is used in dbOpenDynaset or dbOpenSnapshot type of the Recordset object.

VI.5.1. Recordset.FindFirst

Recordset.FindFirst is used to locate the first record of the Recordset object that satisfies the specific criteria . For the direction of the search, it finds the record from the beginning to the end of the Recordset.

Syntax:

RecordsetObject.FindFirst(Criteria)

Criteria: It is like WHERE clause in the SQL statement, but in this syntax the word WHERE is not used. Criteria (must) has a data type as string.

Note: This method always use with NoMatch property to determine whether the process of finding has succeeded. If the search is found, the value of NoMatch property is False. In contrast, the value of NoMatch property is True. However, you can use BOF property instead of Nomatch property in finding the data.

Читать еще:  Access inner join

If the Recordset contains more than one record that satisfies the criteria, the first occurrence is returned.

For example, you have the frmModifyData form as figure:

This form allows you to find the existing record through CategoryID only. If you want to find any record (e.g. you would like to find Cate004. Does it exist in the table or not?), you have to type CategoryID(not case-sensitive) in the Search text box and click the Search command button. The found record will display in the two text boxes and be selected in the list box. See the figure:

The VBA code below explicates the example. You can use either BOF or NoMatch property as in demonstrative VBA code below:

Option Compare Database
Dim Db As DAO.Database
Dim Rs As DAO.Recordset
Dim SqlText As String

Private Sub Form_Load()

‘ Display the first record on form and drop all records to listbox with selection
Set Db = CurrentDb

SqlText = » Select * From TblCategory»

Set Rs = Db.OpenRecordset(SqlText, dbOpenDynaset)

Call Display ‘ Call display sub procedure

Selectlist (Rs.AbsolutePosition) ‘ Call selectlist sub procedure

Call PopListbox ‘ Call PopListbox sub procedure

Private Sub cmdSearch_Click()

If txtSearch.Value <> » » Then

If Not Rs.BOF Then

Rs.FindFirst «CategoryID='» & txtSearch.Value & «‘»

If Trim(txtCategoryID.Value) <> txtSearch.Value Then

MsgBox «The Record not found!»

Else : MsgBox «Please enter what you want to find.»

If txtSearch.Value <> «» Then

Rs.FindFirst «CategoryID='» & txtSearch & «‘»

If Rs.NoMatch = True Then

MsgBox «The record not found!»

Else : MsgBox «Please enter what you want to find»

Выполнение SQL запросов к текущей базе данных в среде VBA (Access)

В Microsoft Office Access поддерживается выполнение SQL запросов к текущей базе данных из программного кода на VBA. Рассмотрим, как это можно использовать при разработке приложений баз данных.

Так как запрос выполняется к той же самой базе данный в которой выполняется модуль VBA, для выполнения SQL запроса нет необходимости работать со стандартными в подобных случаях интерфейсами ADO, ODBC и т.д. Всё можно сделать при помощи объектной модели Access.

Как известно SQL запросы можно условно разделить на две большие группы:

  • Запросы, не возвращающие данных (INSERT, UPDATE, DELETE и т.д.);
  • Запросы возвращающие данные (запросы на выборку (SELECT)).
Запросы, не возвращающие данных

Для выполнения запросов к текущей базе данных служит метод Execute объекта CurrentDb. Этот метод принимает в качестве параметра строку с SQL запросом, который необходимо выполнить.

Это простейший запрос. Но, как быть с запросами, которые манипулируют теми или иными данными?

Такие запросы тоже можно выполнить. Для этого нужно просто сформировать соответствующую строку.

Так, например, может быть реализовано добавление записей в таблицу:

А, так их обновление:

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

Запросы на выборку

Метод Execute объекта CurrentDb не поддерживает выполнение запросов на выборку. Поэтому для них нужен другой подход.

Чтобы работать с выборкой данных необходимо воспользоваться объектом RecordSet, который можно создать при помощи метода OpenRecordSet объекта CurrentDb. Этот метод также принимает в качестве параметра строку с SQL запросом.

После создания RecordSet мы можем перебрать все записи, как это показано ниже.

Помимо простого перебора доступны несколько видов поиска. Но в основном используются два.

Первый вид поиска реализован в виде методов FindFirst, FindLast, FindNext и FindPrevious объекта RecordSet.

Первые два устанавливают курсор на соответственно первую и последнюю записи, соответствующие условию поиска. Условие поиска передаётся в качестве параметра в виде строки. Само условие задаётся по аналогии с предложением WHERE в обычном SQL запросе.

Методы FindNext и FindPrevious устанавливают курсор на следующую и предыдущую записи в соответствии с условием поиска, если такие записи существуют. Условие поиска для этих методов задаётся также, как и для FindFirst и FindLast.

Обратите внимание, что эти четыре метода именно устанавливают указатель на нужную запись, а не производят фильтрацию выборки. Таким образом количество записей выбранных SQL запросом остаётся неизменным.

В следующем примере перебор записей начнётся с записи, у которой id равен 234, так как курсор был перемещён к ней до начала обхода набора записей в цикле.

How to work with recordset (Dao) in MS Access

Recordsets are objects that represent collections (sets) of records. Recordsets have many methods and properties to make working with the records in the collection easy. This page summarizes how to create and use DAO recordsets.

Open a recordset

There are several ways to create or get a recordset:

  • Create a new Recordset from a table or query in your database
  • Use the Recordset property of an Access object, such as a bound Form
  • Clone an existing recordset
  • Create a new Recordset by applying a Filter on an existing recordset

In the following sections these different approaches are shown. A small screencast will be included to show where to click to effortlessly get the code inserted.

Create a recordset from a table or query in the current database

The code below opens a recordset taken from a table in the current database

Click this to see how the code is created with just a few menu selections

Читать еще:  Ms access vba

In the screencast you see two actions taking place:

  1. Insert the OpenRecordset method from the DAO Database Object
  2. Insert the Name of a Table

Note: Code VBA automatically understands DAO OpenRecordset uses CurrentDb as the database.

Note: When you use OpenRecordset on a query or attached table Access defaults the Type property to dbOpenDynaset. When you OpenRecordset on a local table, it uses dbOpenTable by default. The Table type has different methods (e.g. Seek instead of FindFirst), but it cannot be used with attached tables. Consequently if you later, as good practice, split your database the tables become attached tables and the code is likely to fail. For this reason it is safer to just generally stick to dbOpenDynaset.

Add new record to DAO Recordset

To add a new record a recordset has to be be available. The adding of a record requires:

  1. AddNew : Start inserting a record
  2. Set the values of the fields of the record being created
  3. Update : Finalize the adding

Notes

  1. If a fieldname contains a space you must put it between square brackets.
  2. If you add a record to a recordset of type dynaset, the new record will appears at the end of the Recordset, regardless how the Recordset is sorted. To force the new record to appear in its properly sorted position, you can use the Requery method.

Read values from record

To read the field values from a record you first have to make it the current. Subsequently the value of a field can either be obtained using the .Fields method or shorter equivalents

Edit a record in a DAO Recordset

To edit a record in a recordset it first has to be made the current record. After that, changing the values of fields of a record requires:

  1. Edit : Indicate the current record is to be edited
  2. Set the values of the fields of the record being created
  3. Update : Finalize the adding

recordsetfindandedit

Check out this to see how the code is created with just a few menu selections

Move through a DAO Recordset — make record current

Moving through a recordset changes what is the ‘current’ record.

Find a record

The most direct way to move to a specific record is using the FindFirst method.

For best performance, the criteria should be in either the form «field = value» where field is an indexed field in the underlying base table, or «field LIKE prefix» where field is an indexed field in the underlying base table and prefix is a prefix search string (for example, «ART*» ).

After having found the record you can read or change the record’s field values as explained under Edit a record in a DAO Recordset.

Processing all records

Use the Move methods to move from record to record without applying a condition. When you open a Recordset, the first record is current. Using any of the Move methods (MoveFirst, MoveLast, MoveNext, or MovePrevious) causes an error if the recordset has no records, so you should test this condition before using a Move method. If, as usually is the case, you use the MoveNext in a loop as below this test is done with .EOF .

Delete a record

If you want to delete a record you first have to move to it (see above) making it the current. After that simply

When you use the Delete method, the Microsoft Access database engine immediately deletes the current record without any warning or prompting. Deleting a record does not automatically cause the next record to become the current record; to move to the next record you must use the MoveNext method.

CODE VBA — AGORA Software BV Copyright 1997-2019

VBA Traps: Working with Recordsets

This article highlights ten common traps with DAO recordsets in VBA code.

Most of the traps yield no syntax error; they are bugs lying dormant in your code until particular conditions are met. Your program then fails, or returns inaccurate results.

1. DAO versus ADO

The DAO and ADO libraries both have a Recordset object, but with different methods, properties, and options.

DAO is the native Access library (what Access itself uses), whereas ADO is a more generic library (now superseded by the vastly different ADO.NET library.)

Different versions of Access default to different libraries. See Solving Problems with Library References for details.

This article assumes DAO recordsets.

Solution:

To ensure your code works reliably:

  1. Set your references to use just the library you want.
  2. If you must use both, list your main one first.
  3. Disambiguate by specifying which library’s recordset you want. Use:
    Dim rs As DAO.Recordset
    not:
    Dim rs As Recordset

2. Recordset types

There are different types of DAO recordset, with different methods.

When you OpenRecordset() on a query or attached table, Access defaults to a Dynaset type (dbOpenDynaset). When you OpenRecordset() on a local table, it defaults to a Table type (dbOpenTable.)

The Table type has different methods (e.g. Seek instead of FindFirst), but it cannot be used with attached tables. So if you later split your database so the tables are attached, the code fails when you use a method that no longer applies.

Читать еще:  Справочник vba access

Solution:

Always specify the type you want. Dynaset guarantees your code will work for all queries and tables, local and attached. Example:

3. Move with no records

Using any of the Move methods (MoveFirst, MoveLast, MoveNext, or MovePrevious) causes an error if the recordset has no records.

Solution:

Test before using any of the Move methods. Either of these approaches works:

4. RecordCount without MoveLast

For recordsets based on queries, SQL statements, and attached tables, the RecordCount property returns the number of records accessed so far. When you first OpenRecordset(), Access grabs the first record, and keeps processing your code while the others load. So, if you test RecordCount immediately after you OpenRecordset, you typically get 0 (if there are no records), or 1 (if there are any, regardless of how many will load.) This does not apply to recordsets of type dbOpenTable type (the default for local tables.)

Solution:

If you need to know the RecordCount, use the MoveLast method first. This forces Access to wait while all records load, so the RecordCount reflects the entire recordset.

Don’t MoveLast unless you really need to: this will be slow with a large recordset or a recordset drawn across a network. RecordCount will always be at least 1 if records exist, so there is no need to MoveLast if you only want to know if you have records to work with.

5. MoveNext without testing EOF

A MoveNext may take you to the end of the recordset (EOF) or a MovePrevious to the beginning of the recordset (BOF). Failure to test for these conditions means your code works for most cases, but generates an error one day when the last/first record is accessed.

The problem is prevalent when you have another exit condition in mind for your loop, so you are not thinking of EOF. Test for EOF (or BOF if moving backwards) before checking the real exit condition for your loop.

Solution:

Use this construct for looping through Access recordsets:

6. Loop without MoveNext

When looping through records, it is easy to create an endless loop by omitting the line rst.MoveNext. Your code then becomes stuck in an endless loop.

Solution:

VBA is more forgiving than most other languages: just press Ctrl+Break to break out of the loop.

Even in a quick’n’dirty procedure, a progress indicator lets you know if a loop is stuck. The simplest reports every 100th record in the loop like this:

7. FindFirst/Seek without testing NoMatch

If you use Seek or one of the Find methods (FindFirst, FindLast, FindNext, FindPrevious), and do not test NoMatch, your code will appear to work until you strike a case where the find failed.

Solution:

Always test for NoMatch after using Seek or a Find method. Example:

8. AddNew without moving to LastModified

When inserting a new record into a recordset, the new record does not automatically become the current record.

Solution:

To access the new record, move to the bookmark LastModified:

9. Failing to close a recordset

It is poor programming to open anything without explicitly closing it. This problem is particularly acute in Access 97. Short of pressing Ctrl+Alt+Del, you may find that Access will not quit if recordsets or other objects are not closed and dereferenced.

Solution:

Always close recordsets and set objects to Nothing in the error recovery of your procedure. Use this construct:

10. Nested recordsets

Access 2007 introduced the possibility that a field in a recordset may itself be a recordset. This applies to complex data types — multi-value fields and attachments — in an ACCDB, not MDB.

Any code that examines the Fields of a recordset or applies criteria is affected. Test the field’s Type, and introduce another loop to walk the fields within the recordset that is a field in your main recordset. For a list of the field types, see Field type reference.

Many professional developers avoid the complex data types, believing they introduce more problems than they solve. The hidden structure makes it harder to manage them, harder to apply criteria, harder to pass arguments, harder to determine the delimiters to use for a field, and harder to upsize since other databases like SQL Server don’t use these complex types. Eschewing the complex data types is a perfectly valid choice if you only deal with databases you created, but if you support end users or write generic utilities to work with any Access tables, you must learn to handle them.

Solutions

Specifically test for and handle the complex data types if your code must work with databases in Access 2007 or later. Particularly, if you:

  • Loop through the fields of a recordset, examining each.
  • Apply criteria to a field without knowing its data type.

The Find-as-you-type utility contains a practical example of testing for and excluding the complex data types in the function FindAsUTypeLoad(), while ensuring the code still works in earlier versions of Access.

Ссылка на основную публикацию
Adblock
detector