Vba access recordset: Объект Recordset (DAO) | Microsoft Learn

Свойство Form.Recordset (Access) | Microsoft Learn






Twitter




LinkedIn




Facebook




Адрес электронной почты










  • Статья



Возвращает или задает объект ADO Recordset или DAO Recordset , представляющий источник записи для указанного объекта. Чтение и запись объекта.

Синтаксис

expression. Набора записей

выражение: переменная, представляющая объект Form.

Свойство Recordset возвращает объект Recordset , который предоставляет данные, просматриваемые в форме, отчете, элементе управления «Список» или элементе управления со списком. Например, если форма основана на запросе, ссылка на свойство Recordset эквивалентна клонирования объекта Recordset с помощью того же запроса. Однако, в отличие от использования свойства RecordsetClone , изменение текущей записи в наборе записей, возвращаемом свойством Recordset формы, также задает текущую запись формы.

Поведение чтения и записи свойства Recordset определяется типом набора записей (ADO или DAO) и типом данных (Access или SQL), содержащихся в наборе записей, определяемом свойством .

Тип набора записейНа основе данных SQLНа основе данных, хранящихся ядром СУБД Access
ADOЧтение и записьЧтение и запись
DAOНедоступноЧтение и запись

В следующем примере открывается форма, открывается набор записей, а затем форма привязывается к набору записей, задавая свойство Recordset формы к только что созданному объекту Recordset .

Global rstSuppliers As ADODB.Recordset 
Sub MakeRW()      
    DoCmd.OpenForm "Suppliers" 
    Set rstSuppliers = New ADODB.Recordset 
    rstSuppliers.CursorLocation = adUseClient 
    rstSuppliers.Open "Select * From Suppliers", _ 
         CurrentProject.Connection, adOpenKeyset, adLockOptimistic      
    Set Forms("Suppliers").Recordset = rstSuppliers 
End Sub

Используйте свойство Recordset , чтобы:

  • Используйте методы с объектом Recordset , которые не поддерживаются непосредственно в формах. Например, можно использовать свойство Recordset с методами ADO Find или DAO Find в настраиваемом диалоговом окне для поиска записи.

  • Обведите транзакцию (которую можно откатить) вокруг набора правок, влияющих на несколько форм.

    Изменение свойства Recordset формы также может изменить свойства RecordSource, RecordsetType и RecordLocks . Кроме того, некоторые связанные с данными свойства могут быть переопределены, например свойства FilterOn, OrderBy и OrderByOn.

    Вызов метода Requery для набора записей формы (например, ) может привести к тому, Forms(0).Recordset.Requeryчто форма станет неограниченной. Чтобы обновить данные в форме, привязанной к набору записей, задайте для свойства RecordSource формы значение : Forms(0).RecordSource = Forms(0). RecordSource.

  • Привязка нескольких форм к общему набору данных. Это позволяет синхронизировать несколько форм. Например:

      Set Me.Recordset = Forms!Form1.Recordset
    

Примечание.

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

Пример

В следующем примере свойство Recordset используется для создания новой копии объекта Recordset из текущей формы, а затем выводит имена полей в окне Отладка.

Sub Print_Field_Names() 
    Dim rst As DAO.Recordset, intI As Integer 
    Dim fld As Field 
 
    Set rst = Me.Recordset 
    For Each fld in rst.Fields 
        ' Print field names. 
        Debug.Print fld.Name 
    Next 
End Sub

В следующем примере свойство Recordset и объект Recordset используются для синхронизации набора записей с текущей записью формы. Если в поле со списком выбрано название компании, метод FindFirst используется для поиска записи для этой компании, что приводит к отображению найденной записи в форме.

Sub SupplierID_AfterUpdate() 
    Dim rst As DAO.Recordset 
    Dim strSearchName As String 
 
    Set rst = Me.Recordset 
    strSearchName = CStr(Me!SupplierID) 
    rst.FindFirst "SupplierID = " & strSearchName 
    If rst.NoMatch Then 
        MsgBox "Record not found" 
    End If 
    rst.Close 
End Sub

Следующий код помогает определить, какой тип набора записей возвращается свойством Recordset при различных условиях.

Sub CheckRSType() 
    Dim rs as Object 
 
    Set rs=Forms(0).Recordset 
    If TypeOf rs Is DAO.Recordset Then 
        MsgBox "DAO Recordset" 
    ElseIf TypeOf rs is ADODB.Recordset Then 
        MsgBox "ADO Recordset" 
    End If 
End Sub

Поддержка и обратная связь

Есть вопросы или отзывы, касающиеся Office VBA или этой статьи? Руководство по другим способам получения поддержки и отправки отзывов см. в статье Поддержка Office VBA и обратная связь.






Свойство Набор записей(Recordset) — Служба поддержки Майкрософт

Access для Microsoft 365 Access 2021 Access 2019 Access 2016 Access 2013 Access 2010 Access 2007 Еще. ..Меньше

Применение






Объект ComboBox

Объект Form

Объект ListBox

Объект Report

Возвращает или задает объект ADO Recordset или DAO Recordset, который представляет собой источник записей для указанной формы, отчета, списка или поля со списком. Значение данного свойства доступно для чтения и записи.


выражение.Recordset


выражение — обязательный аргумент. Выражение, которое возвращает один из объектов в списке «Применяется к».



Замечания


Свойство Recordset (Набор записей) возвращает объект набора записей, который является источником данных, просматриваемых в форме, отчете, списке или поле со списком. Если форма основана, например, на запросе, ссылка на свойство Recordset эквивалентна клонированию объекта Recordset с помощью того же запроса. Однако в отличие от использования свойства RecordsetClone (Копия набора записей), назначение в качестве текущей другой записи в наборе записей, возвращаемом свойством Recordset формы, также задает текущую запись этой формы.

Это свойство можно задать только с помощью кода Visual Basic для приложений (VBA).

Доступность для чтения и записи свойства Recordset определяется типом набора записей (ADO или DAO) и типом данных (Access или SQL), которые содержатся в нем.





Тип
набора записей


Данные SQL


Данные Access


ADO

Чтение и запись

Чтение и запись


DAO

Н/Д

Чтение и запись

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


Global rstSuppliers As ADODB.RecordsetSub MakeRW()DoCmd.OpenForm «Suppliers»Set rstSuppliers = New ADODB.RecordsetrstSuppliers.CursorLocation = adUseClientrstSuppliers.Open «Select * From Suppliers», _CurrentProject.Connection, adOpenKeyset, adLockOptimisticSet Forms(«Suppliers»).Recordset = rstSuppliersEnd Sub

Свойство Набор записей служит для следующих целей:

  • Связывание нескольких форм с общим набором данных. Это позволяет синхронизировать несколько форм. Например:


    Set Me.Recordset = Forms!Form1.Recordset

  • Использование методов, не имеющих непосредственной поддержки в формах, вместе с объектом Recordset. Например, свойство Recordset можно использовать вместе с методами ADO Find или DAO Find в пользовательском диалоговом окне для поиска записи.

  • Добавление в транзакцию (для которой можно выполнить откат) набора изменений, влияющих на несколько форм.

Изменение свойства Recordset также может привести к изменению свойств RecordSource (Источник записей), RecordsetType (Тип набора записей) и RecordLocks (Блокировка записей). Кроме того, некоторые связанные с данными свойства могут быть переопределены, например свойства Filter (Фильтр), FilterOn (Фильтр включен), OrderBy (Порядок сортировки) и OrderByOn (Сортировка включена).

Вызов метода Requery набора записей формы (например, Forms(0).Recordset.Requery) может привести к превращению формы в свободную. Чтобы обновить данные в форме, привязанной к набору записей, следует задать для свойства RecordSource (Источник записей) формы само это свойство (Forms(0).RecordSource = Forms(0).RecordSource).

Если форма привязана к набору записей, при использовании команды «Фильтр по форме» возникает ошибка.



Пример


В следующем примере свойство Recordset используется для создания копии объекта Recordset из текущей формы. Затем в окне отладки печатаются имена полей.


Sub Print_Field_Names()
Dim rst As DAO.Recordset, intI As Integer
Dim fld As Field
Set rst = Me.Recordset
For Each fld in rst.Fields
' Print field names.
Debug.Print fld.Name
Next
End Sub

В следующем примере свойство Recordset и объект Recordset используются для синхронизации набора записей с текущей записью формы. При выборе в поле со списком названия организации для поиска ее записи используется метод FindFirst, вызывающий отображение найденной записи в форме.


Sub SupplierID_AfterUpdate()
Dim rst As DAO.Recordset
Dim strSearchName As String
Set rst = Me.Recordset
strSearchName = CStr(Me!SupplierID)
rst.FindFirst "SupplierID = " & strSearchName
If rst.NoMatch Then
MsgBox "Record not found"
End If
rst.Close
End Sub

Следующий код помогает определить, какой тип набора записей возвращается свойством Recordset при разных условиях.


Sub CheckRSType()
Dim rs as Object
Set rs=Forms(0).Recordset
If TypeOf rs Is DAO.Recordset Then
MsgBox "DAO Recordset"
ElseIf TypeOf rs is ADODB.Recordset Then
MsgBox "ADO Recordset"
End If
End Sub



Как работать с набором записей (Dao) в MS Access

Наборы записей — это объекты, представляющие коллекции (наборы) записей.
Наборы записей имеют множество методов и свойств, упрощающих работу с записями в коллекции.
На этой странице кратко описано, как создавать и использовать наборы записей DAO.
Посетите страницу Recordset Builder, чтобы узнать, как этот инструмент включен в
Надстройка Code VBA вставляет полные блоки кода для чтения и записи записей в базу данных MS Access.

Открыть набор записей

Существует несколько способов создать или получить набор записей:

  • Создать новый набор записей из таблицы или запроса в базе данных
  • Использовать свойство Recordset объекта Access, например связанной формы
  • Клонирование существующего набора записей
  • Создать новый набор записей, применив фильтр к существующему набору записей

В следующих разделах показаны эти различные подходы.
Будет включен небольшой скринкаст, чтобы показать, где щелкнуть, чтобы легко вставить код.

Приведенный ниже код открывает набор записей, взятый из таблицы в текущей базе данных

 Dim сначала как набор записей
Set rst = CurrentDb. OpenRecordset(Name:="Categories", Type:=RecordsetTypeEnum.dbOpenDynaset)
 

Щелкните здесь, чтобы увидеть, как создается код с помощью всего нескольких пунктов меню

В скринкасте происходят два действия:

  1. Вставьте метод OpenRecordset из объекта базы данных DAO
  2. Вставьте имя таблицы

Примечание. Код VBA автоматически понимает, что DAO OpenRecordset использует CurrentDb в качестве базы данных.

Примечание. При использовании OpenRecordset в запросе или прикрепленной таблице Access по умолчанию устанавливает для свойства Type значение dbOpenDynaset.
Когда вы используете OpenRecordset для локальной таблицы, по умолчанию используется dbOpenTable.
Тип Table имеет другие методы (например, Seek вместо FindFirst), но его нельзя использовать с прикрепленными таблицами.
Следовательно, если вы позже, в качестве хорошей практики, разделите свою базу данных, таблицы станут присоединенными таблицами, и код, скорее всего, даст сбой.
По этой причине безопаснее просто придерживаться dbOpenDynaset.

Чтобы добавить новую запись, должен быть доступен набор записей. Для добавления записи требуется:

  1. AddNew : Начать вставку записи
  2. Установить значения полей создаваемой записи
  3. Обновление : завершение добавления
 Dim rstCategories As Recordset
Установите rstCategories = CurrentDb.OpenRecordset(Name:="Categories", Type:=RecordsetTypeEnum.dbOpenDynaset)
С rstCategories
    .Добавить новое
    ![Имя категории] = "Лучшее программное обеспечение"
    !Описание = "5 звезд"
    .Обновлять
Конец с 

Примечания

  1. Если имя поля содержит пробел, его необходимо поместить в квадратные скобки.
  2. Если вы добавите запись в набор записей типа dynaset, новая запись появится в конце набора записей, независимо от того, как набор записей отсортирован. Чтобы заставить новую запись появиться в ее правильно отсортированном положении, вы можете использовать метод Requery .

Чтобы прочитать значения полей из записи, вы должны сначала сделать ее текущей.
Впоследствии значение поля может быть получено с помощью Метод .Fields или более короткие эквиваленты

 С rstCategories
    lng = !CategoryID
    str1 = ![Имя категории]
    str2 = .Поля("Описание")
Конец с 

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

  1. Редактировать : Указывает, что текущая запись должна быть отредактирована
  2. Установить значения полей создаваемой записи
  3. Обновление : завершение добавления
 С rstCategories
    .Редактировать
    ![Имя категории] = "Лучшее программное обеспечение"
    .Обновлять
Конец с 

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

Перемещение по набору записей изменяет то, что является «текущей» записью.

Найти запись

Самый прямой способ перейти к определенной записи — использовать метод FindFirst .

 С rstCategories
    .FindFirst "CategoryName = " & "'лучшее программное обеспечение'"
    Если .NoMatch Тогда

    Конец, если
Конец с 

Для наилучшей производительности критерии должны быть в форме «поле = значение», где поле — это индексированное поле в базовой таблице, или «поле LIKE префикс», где поле — это индексированное поле в базовой таблице и префикс — строка поиска префикса (например, «ART*»).

Найдя запись, вы можете прочитать или изменить значения полей записи, как описано в разделе «Редактирование записи в наборе записей DAO».

Обработка всех записей

Используйте методы Move для перехода от записи к записи без применения условия. Когда вы открываете набор записей, первая запись является текущей.
Использование любого из методов Move (MoveFirst, MoveLast, MoveNext или MovePrevious) вызывает ошибку, если в наборе записей нет записей.
поэтому вы должны проверить это условие, прежде чем использовать метод Move. Если, как это обычно бывает, вы используете MoveNext в цикле, как показано ниже, этот тест выполняется с .EOF .

 Делать пока не rst.EOF

    rst.MoveNext
Петля 

Если вы хотите удалить запись, вам сначала нужно перейти к ней (см. выше), сделав ее текущей. После этого просто

 рстКатегориес.Удалить 

При использовании метода Удалить ядро ​​базы данных Microsoft Access немедленно удаляет текущую запись без каких-либо предупреждений или подсказок. Удаление записи не приводит к тому, что следующая запись автоматически становится текущей записью; чтобы перейти к следующей записи, вы должны использовать метод MoveNext.

Советы Microsoft Access: ловушки VBA: работа с наборами записей

Советы Microsoft Access: ловушки VBA: работа с наборами записей

Советы Microsoft Access для серьезных пользователей

Предоставлено Алленом Брауном. Последнее обновление: апрель 2010 г.


Содержание:

1. DAO и ADO

2. Типы наборов записей

3. Move без записей

4. RecordCount без MoveLast

5. MoveNext без тестирования EOF 9000 3

6. Цикл без MoveNext

7 .Найти без NoMatch

8.AddNew без LastModified

9. Не удалось закрыть наборы записей

10. Вложенные наборы записей

В этой статье описаны десять распространенных ловушек с наборами записей DAO в коде VBA.

Большинство прерываний не приводят к синтаксической ошибке; это ошибки, которые скрыты в вашем коде до тех пор, пока не будут выполнены определенные условия. Затем ваша программа дает сбой или возвращает неточные результаты.

Обе библиотеки DAO и ADO имеют объект Recordset , но с разными методами, свойствами и параметрами.

DAO — это родная библиотека Access (то, что использует сам Access), тогда как ADO — это более общая библиотека (теперь замененная совершенно другой библиотекой ADO. NET).

Различные версии Access по умолчанию используют разные библиотеки. Дополнительные сведения см. в разделе «Решение проблем со ссылками на библиотеки».

В этой статье предполагается набор записей DAO.

Решение:

Чтобы ваш код работал надежно:

  1. Установите свои ссылки , чтобы использовать только ту библиотеку, которую вы хотите.
  2. Если вы должны использовать оба, сначала укажите основной.
  3. Устраните неоднозначность , указав нужный набор записей библиотеки. Использование:
        Dim rs As DAO.Recordset
    не:
        Dim rs As Recordset

Существуют разные типы наборов записей DAO с разными методами.

Когда вы используете OpenRecordset() для запроса или прикрепленной таблицы, Access по умолчанию использует Dynaset 9Тип 0157 (dbOpenDynaset). Когда вы используете OpenRecordset() для локальной таблицы, по умолчанию используется тип таблицы (dbOpenTable. )

Тип Table имеет разные методы (например, Seek вместо FindFirst), но его нельзя использовать с прикрепленными таблицами. Поэтому, если вы позже разделите свою базу данных, чтобы таблицы были присоединены, код даст сбой, когда вы используете метод, который больше не применяется.

Решение:

Всегда указывайте нужный тип. Dynaset гарантирует, что ваш код будет работать для всех запросов и таблиц, локальных и прикрепленных. Пример:

 Set rs = db.OpenRecordset("Table1", dbOpenDynaset) 

Использование любого из методов Move (MoveFirst, MoveLast, MoveNext или MovePrevious) вызывает ошибку , если в наборе записей нет записей .

Решение:

Проверка перед использованием любого из методов Move. Любой из этих подходов работает:

 If Not (rs.BOF And rs.EOF) Then 'Нет записей, если оба параметра Beginning-Of-File и End-Of-File верны.
    If rs.RecordCount <> 0 Then '100% надежность в DAO, но некоторые наборы записей ADO возвращают -1 в качестве счетчика.  

Для наборов записей, основанных на запросах, операторах SQL и прикрепленных таблицах, свойство RecordCount возвращает число записей, к которым был получен доступ на данный момент. Когда вы впервые используете OpenRecordset(), Access захватывает первую запись и продолжает обрабатывать ваш код, пока загружаются остальные. Таким образом, если вы тестируете RecordCount сразу после OpenRecordset, вы обычно получаете 0 (если записей нет) или 1 (если они есть, независимо от того, сколько будет загружено). Это не относится к наборам записей типа 9.0222 Тип dbOpenTable (по умолчанию для локальных таблиц)

Решение:

Если вам нужно узнать RecordCount, сначала используйте метод MoveLast. Это заставляет Access ждать загрузки всех записей, поэтому RecordCount отражает весь набор записей.

Подсказка:

Не используйте MoveLast, если вам это действительно не нужно: это будет медленный с большим набором записей или набором записей, передаваемым по сети. RecordCount всегда будет как минимум 1, если записи существуют, поэтому нет необходимости в MoveLast, если вы хотите знать, есть ли у вас записи для работы.


MoveNext может привести вас к концу набора записей (EOF) или MovePrevious к началу набора записей (BOF). Отсутствие проверки на эти условия означает, что ваш код работает в большинстве случаев, но однажды генерирует ошибку при доступе к последней/первой записи.

Проблема распространена, когда вы имеете в виду другое условие выхода для своего цикла, поэтому вы не думаете о EOF. Тест на EOF (или BOF при движении назад) перед проверкой реального условия выхода для вашего цикла .

Решение:

Используйте эту конструкцию для циклического просмотра наборов записей Access:

 Делать пока не rst.EOF
        If rst![MyField] <> Something Then 'Настоящее условие выхода из цикла.
            Выход Сделать
        Конец, если
        ' Остальная часть вашего кода здесь. 
        rst.MoveNext
    Петля 

При циклическом просмотре записей легко создать бесконечный цикл, опуская строку rst.MoveNext. Затем ваш код застревает в бесконечном цикле.

Решение:

VBA более щадящий, чем большинство других языков: просто нажмите Ctrl+Break , чтобы выйти из цикла.

Подсказка:

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

 я = я + 1
    Если i Mod 100 = 0, то Mod дает остаток от деления i на 100.
        DoCmd.Echo Истинно, я
    Конец, если 

Если вы используете поиск или один из методов поиска (FindFirst, FindLast, FindNext, FindPrevious) и не тестируете NoMatch, ваш код будет работать до тех пор, пока вы не обнаружите случай, когда поиск не удался.

Решение:

Всегда проверяйте на несоответствие после использования метода Seek или Find. Пример:

 rs.FindFirst "Город = ""Нью-Йорк"""
    Если Не rs.NoMatch Тогда
        «Все в порядке, продолжайте обрабатывать.
    Конец, если 

При вставке новой записи в набор записей новая запись не становится автоматически текущей записью.

Решение:

Для доступа к новой записи перейдите на закладку LastModified:

 рст.AddNew
        'Назначьте поля здесь.
    рст.Обновление
    rst.Bookmark = rst.LastModified
    ' Работайте с новой записью здесь. 

Плохо программировать открывать что-либо без явного закрытия. Эта проблема особенно остро стоит в Access 97. Если не нажимать Ctrl+Alt+Del, вы можете обнаружить, что Access не закроется, если наборы записей или другие объекты не закрыты и не разыменованы.

Решение:

Всегда закрывайте наборы записей и устанавливайте для объектов значение Ничего при устранении ошибок вашей процедуры. Используйте эту конструкцию:

 Подпрограмма MyProc
    При ошибке Перейти к Err_MyProc
        Dim db как база данных
        Dim сначала как набор записей

        Установить БД = ТекущаяБД()
        Установите сначала = db. OpenRecordset("MyTable")
        'Полезный код здесь.
        rst.Close 'Закройте то, что вы открыли.

    Выход_MyProc:
        Set rst = Nothing 'Отменить назначение всех объектов.
        Установить БД = Ничего
        Выйти из подпрограммы

    Err_MyProc:
        'Здесь обработчик ошибок.
        Возобновить Exit_MyProc
    Конец суб 

В Access 2007 появилась возможность того, что поле в наборе записей само может быть набором записей . Это относится к сложным типам данных — многозначным полям и вложениям — в ACCDB, а не в MDB.

Затрагивается любой код, который проверяет поля набора записей или применяет критерии. Проверьте тип поля и введите еще один цикл для обхода полей в наборе записей, который является полем в вашем основном наборе записей. Список типов полей см. в разделе Справочник по типам полей.

Многие профессиональные разработчики избегают сложных типов данных, полагая, что они создают больше проблем, чем решают. Скрытая структура усложняет управление ими, усложняет применение критериев, усложняет передачу аргументов, усложняет определение разделителей для использования в поле и усложняет увеличение размера, поскольку другие базы данных, такие как SQL Server, не используют эти сложные типы. Отказ от сложных типов данных — вполне правильный выбор, если вы имеете дело только с созданными вами базами данных, но если вы поддерживаете конечных пользователей или пишете универсальные утилиты для работы с любыми таблицами Access, вы должны научиться обращаться с ними.

Решения

Специально проверяйте и обрабатывайте сложные типы данных, если ваш код должен работать с базами данных в Access 2007 или более поздней версии. В частности, если вы:

  • Перебрать поля набора записей, проверяя каждое из них.
  • Применить критерии к полю, не зная его типа данных.

Утилита Find-as-you-type содержит практический пример проверки и исключения сложных типов данных в функции FindAsUTypeLoad(), при этом обеспечивая работоспособность кода в более ранних версиях Access.