Vba excel recordset свойства

Содержание

  • 1 A Recordset That Does Not Support the RecordCount Property
  • 2 A Recordset That Supports the RecordCount Property
  • 3 Assigning Recordsets Dynamically to a form
  • 4 Build a string text from result set
  • 5 Creating a Custom Recordset
  • 6 Creating a Disconnected Recordset
  • 7 Dynamic Recordset
  • 8 Filling a Combo Box with a Disconnected Recordset
  • 9 Looping Through a Recordset
  • 10 Move cursor in result set
  • 11 Refreshing Recordset Data
  • 12 Retrieve data from Recordset by table column name
  • 13 Row order in Dynamic Recordset
  • 14 Set Index and seek the recordset
  • 15 Set recordset to form
  • 16 Snapshot Recordset
  • 17 The Sort Property of the Recordset Object
  • 18 The Supports Method of the Recordset Object
  • 19 Using the AbsolutePosition Property
  • 20 Using the Bookmark Property
  • 21 Using the EOF Property to Determine the Bounds of a Recordset
  • 22 Whether Records Are Returned in a Recordset

A Recordset That Does Not Support the RecordCount Property

   <source lang="vb">

Sub CountRecordsBad()

   Dim rst As ADODB.Recordset
   Set rst = New ADODB.Recordset
   rst.ActiveConnection = CurrentProject.Connection
   rst.Open "Select * from Employees"
   Debug.Print rst.RecordCount  "Prints -1
   rst.Close
   Set rst = Nothing

End Sub

</source>
   
  

A Recordset That Supports the RecordCount Property

   <source lang="vb">

Sub CountRecordsGood()

   Dim rst As ADODB.Recordset
   Set rst = New ADODB.Recordset
   rst.ActiveConnection = CurrentProject.Connection
   rst.CursorType = adOpenStatic
   rst.Open "Select * from Employees"
   Debug.Print rst.RecordCount  "Prints Record count
   rst.Close
   Set rst = Nothing

End Sub

</source>
   
  

Assigning Recordsets Dynamically to a form

   <source lang="vb">

Sub runFormNY()

   Dim con As ADODB.Connection
   Dim myRecordset As Recordset
   Dim strFrmNm As String
   
   Set myRecordset = New ADODB.Recordset
   myRecordset.CursorType = adOpenKeyset
   myRecordset.LockType = adLockOptimistic 
   Set con = New ADODB.Connection
   con.Open "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=c:mydb.mdb;"
      myRecordset.Open "SELECT * FROM Employees", con
      strFrmNm = "frmCustomer"
   DoCmd.OpenForm strFrmNm
   Set Application.Forms(strFrmNm).Recordset = myRecordset
   
   myRecordset.Close
   con.Close
   Set myRecordset = Nothing
   Set con = Nothing

End Sub

</source>
   
  

Build a string text from result set

   <source lang="vb">

Sub MyFirstConnection4()

   Dim myConnection As ADODB.Connection
   Dim myRecordset As ADODB.Recordset
   Dim strSQL As String
   Dim strOutput As String
  
   strSQL = "SELECT FirstName, LastName FROM Employees"
   
   Set myConnection = CurrentProject.Connection
   
   Set myRecordset = New ADODB.Recordset
   myRecordset.Open strSQL, myConnection
   
   Do Until myRecordset.EOF
      strOutput = strOutput + myRecordset.Fields("FirstName") & " " & _
                              myRecordset.Fields("LastName") & vbCrLf
      myRecordset.MoveNext
   Loop
   myRecordset.Close
   msgBox strOutput
   myConnection.Close
   Set myConnection = Nothing
   Set myRecordset = Nothing

End Sub

</source>
   
  

Creating a Custom Recordset

   <source lang="vb">

Sub Custom_Recordset()

   Dim myRecordset As ADODB.Recordset
   Dim strFile As String
   Dim strFolder As String
   strFolder = "C:"
   strFile = Dir(strPath & "*.*")
   Set myRecordset = New ADODB.Recordset
   With myRecordset
      Set .ActiveConnection = Nothing
          .CursorLocation = adUseClient
          With .Fields
                    .Append "Name", adVarChar, 255
                    .Append "Size", adDouble
                    .Append "Modified", adDBTimeStamp
          End With
           .Open
             " Add a new record to the recordset
             .AddNew Array("Name", "Size", "Modified"), _
              Array("fileName.txt", 100, #9/9/1999#)
           .MoveFirst
            " Print the contents of the recordset to the Immediate window
                Do Until .EOF
                     Debug.Print !Name & vbTab & !Size & vbTab & !Modified
                    .MoveNext
                Loop
                .Close
        End With
    Set myRecordset = Nothing

End Sub

</source>
   
  

Creating a Disconnected Recordset

   <source lang="vb">

Sub Rst_Disconnected()

   Dim conn As ADODB.Connection
   Dim myRecordset As ADODB.Recordset
   Dim strConn As String
   Dim strSQL As String
   Dim strRst As String
   strSQL = "Select * From Orders where CustomerID = "VINET""
   strConn = "Provider=Microsoft.Jet.OLEDB.4.0;"
   strConn = strConn & "Data Source = " & CurrentProject.Path & "mydb.mdb"
   Set conn = New ADODB.Connection
   conn.ConnectionString = strConn
   conn.Open
   Set myRecordset = New ADODB.Recordset
   Set myRecordset.ActiveConnection = conn
   " retrieve the data
   myRecordset.CursorLocation = adUseClient
   myRecordset.LockType = adLockBatchOptimistic
   myRecordset.CursorType = adOpenStatic
   myRecordset.Open strSQL, , , , adCmdText
   Set myRecordset.ActiveConnection = Nothing
   myRecordset.MoveFirst
   Debug.Print myRecordset.Fields(0) & " was " & myRecordset.Fields(1) & " before."
   myRecordset.Fields("CustomerID").Value = "OCEAN"
   myRecordset.Update
   strRst = myRecordset.GetString(adClipString, , ",")
   Debug.Print strRst

End Sub

</source>
   
  

Dynamic Recordset

   <source lang="vb">

Sub exaRecordsetPosition()

   Dim db As Database
   Dim rsDyna As Recordset
   Set db = CurrentDb
   Set rsDyna = db.OpenRecordset("Books", dbOpenDynaset)
   rsDyna.MoveFirst
   Do While Not rsDyna.EOF
       Debug.Print rsDyna!PubID & " / " & rsDyna!Title
       Debug.Print rsDyna.AbsolutePosition
       Debug.Print Format$(rsDyna.PercentPosition
       rsDyna.MoveNext
   Loop
   rsDyna.Close

End Sub

</source>
   
  

Filling a Combo Box with a Disconnected Recordset

   <source lang="vb">

Private Sub Form_Load()

  Dim myRecordset As ADODB.Recordset 
  Dim strRowSource As String 
  Dim strName As String 
  strName = CurrentProject.Path & "Companies.rst" 
  Set myRecordset = New ADODB.Recordset 
     With myRecordset 
        .CursorLocation = adUseClient 
        .Open strName, , , ,  adCmdFile 
        Do Until .EOF 
           strRowSource = strRowSource & myRecordset!CompanyName & ";" 
           .MoveNext 
        Loop 
        With Me.cboCompany 
           .RowSourceType = "Value List" 
           .RowSource = strRowSource 
        End With 
        .Close 
     End With 
  Set myRecordset = Nothing 

End Sub

</source>
   
  

Looping Through a Recordset

   <source lang="vb">

Sub LoopThroughRecordset(rst As ADODB.Recordset, rg As Range)

   Dim nColumnOffset As Integer 
   Dim fld As ADODB.Field 
   With rst 
       Do Until .EOF 
           nColumnOffset = 0 
           For Each fld In .Fields 
               rg.Offset(0, nColumnOffset).Value = fld.Value 
               nColumnOffset = nColumnOffset + 1 
           Next 
           Set rg = rg.Offset(1, 0) 
           .MoveNext 
       Loop 
   End With 
   Set fld = Nothing 

End Sub

</source>
   
  

Move cursor in result set

   <source lang="vb">

Sub MyFirstConnection3()

   Dim myConnection As ADODB.Connection
   Dim myRecordset As ADODB.Recordset
   Dim strSQL As String
   
   strSQL = "SELECT FirstName, LastName FROM Employees"
   Set myConnection = CurrentProject.Connection
   
   Set myRecordset = New ADODB.Recordset
   myRecordset.Open strSQL, myConnection
   
   Do Until myRecordset.EOF
      Debug.Print myRecordset.Fields("FirstName") & " " & _
                  myRecordset.Fields("LastName")
      myRecordset.MoveNext
   Loop
   myRecordset.Close
   myConnection.Close
   Set myConnection = Nothing
   Set myRecordset = Nothing

End Sub

</source>
   
  

Refreshing Recordset Data

   <source lang="vb">

Sub PersistRecordset()

   Dim strFileName As String
   strFileName = "c:test.txt"
   Dim rst As ADODB.Recordset
   Set rst = New ADODB.Recordset
   rst.ActiveConnection = CurrentProject.Connection
   rst.CursorType = adOpenStatic
   rst.LockType = adLockOptimistic
   rst.Open Source:="Select * from Employees ", Options:=adCmdText
   On Error Resume Next
   Kill strFileName
   "Save the recordset
   rst.Save strFileName, adPersistADTG
   rst.Close
   Set rst = Nothing

End Sub

</source>
   
  

Retrieve data from Recordset by table column name

   <source lang="vb">

Sub MyFirstConnection()

   Dim myConnection As ADODB.Connection
   Dim myRecordset As ADODB.Recordset
   Set myConnection = CurrentProject.Connection
   
   Set myRecordset = New ADODB.Recordset
   myRecordset.Open "select * from employees", myConnection
   
   Do Until myRecordset.EOF
      Debug.Print myRecordset.Fields("FirstName"), _
                  myRecordset.Fields("LastName")
      myRecordset.MoveNext
   Loop
   myRecordset.Close
   myConnection.Close
   Set myConnection = Nothing
   Set myRecordset = Nothing

End Sub

</source>
   
  

Row order in Dynamic Recordset

   <source lang="vb">

Sub exaRecordsetMove()

   Dim db As Database
   Dim rsTable As Recordset
   Dim rsDyna As Recordset
   
   Set db = CurrentDb
   
   Set rsTable = db.OpenRecordset("Books")
   Debug.Print "Books indexed by PubID/Title:"
   
   rsTable.Index = "PubTitle"
   rsTable.MoveFirst
   Do While Not rsTable.EOF
       Debug.Print rsTable!PubID & " / " & rsTable!Title
       rsTable.MoveNext
   Loop
   
   Debug.Print "Dynaset-type recordset order:"
   Set rsDyna = db.OpenRecordset("Books", dbOpenDynaset)
   rsDyna.MoveFirst
   Do While Not rsDyna.EOF
       Debug.Print rsDyna!PubID & " / " & rsDyna!Title
       rsDyna.MoveNext
   Loop
   
   rsTable.Close
   rsDyna.Close

End Sub

</source>
   
  

Set Index and seek the recordset

   <source lang="vb">

Sub exaRecordsetSeek()

   Dim db As Database
   Dim rsTable As Recordset
   
   Set db = CurrentDb
   
   Set rsTable = db.OpenRecordset("Books")
   rsTable.Index = "Title"
   rsTable.Seek ">=", "On"
   If Not rsTable.NoMatch Then
       Debug.Print rsTable!Title
   Else
       Debug.Print "No title beginning with word "On"."
   End If
   
   rsTable.Close

End Sub

</source>
   
  

Set recordset to form

   <source lang="vb">

Private Sub Form_Open(Cancel As Integer)

   Dim con As ADODB.Connection
   Dim myRecordset As ADODB.Recordset
   Dim strFrmNm As String
   
   Set myRecordset = New ADODB.Recordset
   myRecordset.CursorType = adOpenKeyset
   myRecordset.LockType = adLockOptimistic
   Set con = New ADODB.Connection
   con.Open "Provider=Microsoft.Jet.OLEDB.4.0;" & _
      "Data Source=C:store.mdb;"
      
   myRecordset.Open "SELECT * FROM tblCustomer", con
   Set Me.Recordset = myRecordset
   
   myRecordset.Close
   con.Close
   Set myRecordset = Nothing
   Set con = Nothing

End Sub

</source>
   
  

Snapshot Recordset

   <source lang="vb">

Sub exaRecordsets()

   Dim db As Database
   Dim rsTable As Recordset
   Dim rsDyna As Recordset
   Dim rsSnap As Recordset
   Set db = CurrentDb
   Set rsTable = db.OpenRecordset("Employees")
   Debug.Print "TableCount: " & rsTable.RecordCount
   Set rsDyna = db.OpenRecordset("Employees", dbOpenDynaset)
   Debug.Print "DynaCount: " & rsDyna.RecordCount
   rsDyna.MoveLast
   Debug.Print "DynaCount: " & rsDyna.RecordCount
   
   Set rsSnap = db.OpenRecordset("Employees", dbOpenSnapshot)
   Debug.Print "SnapCount: " & rsSnap.RecordCount
   rsSnap.MoveLast
   Debug.Print "SnapCount: " & rsSnap.RecordCount
   
   rsTable.Close
   rsDyna.Close
   rsSnap.Close
   

End Sub

</source>
   
  

The Sort Property of the Recordset Object

   <source lang="vb">

Sub SortRecordset()

   Dim intCounter As Integer
   Dim rst As ADODB.Recordset
   Set rst = New ADODB.Recordset
   rst.ActiveConnection = CurrentProject.Connection
   rst.CursorLocation = adUseClient
   rst.Open "Select * from Employees"
   Debug.Print "NOT Sorted!!!"
   Do Until rst.EOF
       Debug.Print rst("EmployeeID")
       rst.MoveNext
   Loop
   Debug.Print "Now Sorted!!!"
   rst.Sort = "[EmployeeID]"
   Do Until rst.EOF
       Debug.Print rst("EmployeeID")
       rst.MoveNext
   Loop
   rst.Close
   Set rst = Nothing

End Sub

</source>
   
  

The Supports Method of the Recordset Object

   <source lang="vb">

Sub SupportsMethod()

   Dim rst As ADODB.Recordset
   Set rst = New ADODB.Recordset
   
   rst.ActiveConnection = CurrentProject.Connection
   rst.CursorType = adOpenStatic
   rst.LockType = adLockOptimistic
   rst.CursorLocation = adUseServer
   rst.Open Source:="Select * from Employees ", _
       Options:=adCmdText
   Debug.Print "Bookmark " & rst.Supports(adBookmark)
   Debug.Print "Update Batch " & rst.Supports(adUpdateBatch)
   Debug.Print "Move Previous " & rst.Supports(adMovePrevious)
   Debug.Print "Seek " & rst.Supports(adSeek)
   rst.Close
   Set rst = Nothing

End Sub

</source>
   
  

Using the AbsolutePosition Property

   <source lang="vb">

Sub FindPosition()

   Dim strSQL As String
   Dim rst As ADODB.Recordset
   Set rst = New ADODB.Recordset
   rst.ActiveConnection = CurrentProject.Connection
   rst.CursorType = adOpenStatic
   rst.Open "Select * from Products"
   strSQL = "[ProductID] = " & 1
   rst.Find strSQL
   "If record is found, print its position
   If rst.EOF Then
       msgBox lngValue & " Not Found"
   Else
       Debug.Print rst.AbsolutePosition
   End If
   rst.Close
   Set rst = Nothing

End Sub

</source>
   
  

Using the Bookmark Property

   <source lang="vb">

Sub UseBookmark()

   Dim strSQL As String
   Dim vntPosition As Variant
   Dim rst As ADODB.Recordset
   Set rst = New ADODB.Recordset
   rst.ActiveConnection = CurrentProject.Connection
   rst.CursorType = adOpenStatic
   rst.Open "Select * from Products"
   vntPosition = rst.Bookmark
   Do Until rst.EOF
       Debug.Print rst("ProductID")
       rst.MoveNext
   Loop
   rst.Bookmark = vntPosition
   Debug.Print rst("ProductID")
   rst.Close
   Set rst = Nothing

End Sub

</source>
   
  

Using the EOF Property to Determine the Bounds of a Recordset

   <source lang="vb">

Sub DetermineLimits()

   Dim rst As ADODB.Recordset
   Set rst = New ADODB.Recordset
   rst.ActiveConnection = CurrentProject.Connection
   rst.CursorType = adOpenStatic
   rst.Open "Select * from Employees"
   Do Until rst.EOF
       Debug.Print rst("EmployeeID")
       rst.MoveNext
   Loop
   rst.Close

End Sub

</source>
   
  

Whether Records Are Returned in a Recordset

   <source lang="vb">

Sub CheckARecordset()

   Dim rst As ADODB.Recordset
   Set rst = New ADODB.Recordset
   rst.ActiveConnection = CurrentProject.Connection
   rst.CursorType = adOpenStatic
   rst.Open "Select * from Employees"
   If Not rst.RecordCount Then
     msgBox "Recordset Empty...Unable to Proceed"
   End If
   rst.Close
   Set rst = Nothing

End Sub

</source>

Замечания
Объект Recordset представляет набор записей в основной таблице или набор записей, который получается в результате выполнения запроса.
Объекты Recordset используются для обработки данных в базе данных на уровне записи. При работе с объектами доступа к данным (DAO) почти все операции выполняются с помощью объектов Recordset. Каждый объект Recordset состоит из записей (строк) и полей (столбцов). Существуют объекты Recordset пяти типов:

  1. Объект Recordset типа таблицы — программное представление основной таблицы; используется для добавления, изменения или удаления записей из отдельной таблицы базы данных (только в рабочей области Microsoft Jet).
  2. Объект Recordset типа динамического набора записей — набор обновляемых записей, полученный в результате выполнения запроса. Объект Recordset типа динамического набора записей позволяет добавлять, изменять или удалять записи в основной таблице или таблицах. В объекте Recordset этого типа динамического набора могут содержаться поля из одной или нескольких таблиц базы данных. Этот тип объектов соответствует указателю ключевого набора записей ODBC.
  3. Объект Recordset типа статического набора записей — статическая копия набора записей, используемая для поиска данных или создания отчетов. Объект Recordset типа статического набора записей может содержать поля из одной или нескольких таблиц базы данных, но не допускает обновления полей. Этот тип объектов соответствует указателю статического набора записей ODBC.
  4. Объект Recordset типа статического набора записей с последовательным доступом — аналогичен статическому набору записей с тем лишь исключением, что в нем отсутствует указатель. Пользователь имеет возможность прокручивать записи только вперед. Это повышает быстродействие в ситуациях, когда достаточен однократный проход по набору записей. Этот тип объектов соответствует указателю набора записей с последовательным доступом ODBC.
  5. Объект Recordset динамического типа  результирующий набор записей запроса по одной или нескольким основным таблицам, в котором допускается добавление, изменение или удаление записей. В таком объекте Recordset отображаются записи, добавляемые, удаляемые или изменяемые в основных таблицах другими пользователями. Этот тип объектов соответствует динамическому указателю ODBC (только в рабочей области ODBCDirect).

При создании нового объекта Recordset тип объекта определяется с помощью аргумента тип метода OpenRecordset.
В рабочей области Microsoft Jet, если аргумент тип не задан, механизм DAO пытается создать тип объекта Recordset с максимально возможными функциональными характеристиками, начиная с таблицы. Если таблицу создать не удается, делается попытка создать динамический набор записей, затем статический набор записей и наконец, набор записей с последовательным доступом.
В рабочей области ODBCDirect, если аргумент тип не задан, механизм DAO пытается создать тип объекта Recordset, обеспечивающий максимально быстрое выполнение запроса, начиная с набора записей с последовательным доступом. Если объект этого типа создать невозможно, механизм DAO делает попытку создать статический набор записей, затем динамический набор записей, и наконец, объект Recordset динамического типа.
При создании объекта Recordset на основе неприсоединенного объекта TableDef в рабочей области Microsoft Jet создаются объекты Recordset типа таблицы. На основе присоединенных таблиц или таблиц в базах данных ODBC, подключенных к ядру Microsoft Jet, могут быть созданы только объекты Recordset типа динамического набора записей или статического набора записей.
Новый объект Recordset автоматически добавляется в семейство Recordsets при открытии объекта и автоматически удаляется из семейства при закрытии объекта.
При описании в программе объекта Recordset и содержащего его объекта Database с помощью объектных переменных необходимо обеспечить, чтобы эти переменные имели одинаковую область определения или одинаковое время жизни. Например, при описании общей переменной, представляющей объект Recordset, необходимо обеспечить, чтобы переменная, представляющая объект Database, содержащий объект Recordset, также была общей, либо описать эту переменную в процедуре Sub или Function с ключевым словом Static.
В приложении допускается определение произвольного числа объектных переменных, представляющих объект Recordset. Разные объекты Recordset могут иметь доступ к одним таблицам, запросам и полям без возникновения конфликтов.
Объекты Recordset типа динамического набора записей, статического набора записей и статического набора записей с последовательным доступом сохраняются в локальной оперативной памяти. Если в оперативной памяти не хватает места, ядро базы данных Microsoft Jet сохраняет избыточные данные в каталоге временных файлов на диске. Если и этот объем окажется недостаточным, возникает перехватываемая ошибка.
Объекты Recordset по умолчанию помещаются в семейство Fields. Используемым по умолчанию свойством объекта Field является свойство Value (значение). Эти используемые по умолчанию характеристики позволяют упростить программу.
Если созданный объект Recordset содержит записи, то текущей записью становится первая запись. Если записи в объекте отсутствуют, свойство RecordCount получает значение 0, а свойства BOF и EOF значение True.
Изменить положение указателя текущей записи позволяют методы MoveNext, MovePrevious, MoveFirst и MoveLast. Для объектов Recordset типа статического набора записей с последовательным доступом поддерживается только метод MoveNext. При выполнении цикла по всем записям с помощью методов Move («прохода» по объекту Recordset) свойства BOF и EOF используются для проверки начальной и конечной границы объекта Recordset.
Для объектов Recordset типа динамического статического набора записей в рабочей области Microsoft Jet допускается также использование методов группы Find, таких как FindFirst, позволяющих найти запись, удовлетворяющую определенным условиям. Если запись не обнаруживается, свойство NoMatch получает значение True. Для объектов Recordset типа таблицы допускается сканирование записей с помощью метода Seek.
Тип созданного объекта Recordset задается свойством Type, а возможность изменения записей в объекте определяется свойством Updatable.
Сведения о структуре основной таблицы, такие как имя и тип данных каждого поля (объект Field) и индекса (объект Index) сохраняются в объекте TableDef.
При ссылках на объект Recordset используют его порядковый номер в семействе или значение свойства Name (имя):

Recordsets(0)
Recordsets("имя")
Recordsets![имя]

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

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

Sub dbOpenForwardOnlyX()

	Dim dbsNorthwind As Database
	Dim rstEmployees As Recordset
	Dim fldLoop As Field

	Set dbsNorthwind = OpenDatabase("Борей.mdb")
	' Открывает набор записей с последовательным доступом. 
	' Для перемещения по этому объекту Recordset могут 
	' использоваться только методы MoveNext и Move.
	Set rstEmployees = dbsNorthwind.OpenRecordset("Сотрудники", dbOpenForwardOnly)

	With rstEmployees
		Debug.Print "Набора записей с последовательным доступом: " & .Name & ", Updatable = " & .Updatable

		Debug.Print "    Field - DataUpdatable"
		' Отображает семейство Fields, печатает свойства Name 
		' и DataUpdatable каждого объекта Field.
		For Each fldLoop In .Fields
			Debug.Print "        " & fldLoop.Name & " - " & fldLoop.DataUpdatable
		Next fldLoop

		Debug.Print "    Данные"
		' Печатает данные из набора записей.
		Do While Not .EOF
			Debug.Print "        " & !Имя & " " & !Фамилия
			.MoveNext
		Loop

		.Close
	End With
	dbsNorthwind.Close
End Sub

Чтобы подключиться к файлу Excel, нам потребовалось: создать именованный диапазон в книге Excel;

создать источник данных ODBC с именем ExcelVolumes;

написать три строки кода, начиная с создания объекта Connection до вызова его метода Open.

9.5.1. Открытие Recordset

Обычно следующий после установки соединения этап — это создание объекта Recordset и работа с ним.

Что такое объект Recordset? Само слово Recordset расшифровывается как Set of Records, т. е. набор записей. Проще всего представить его как таблицу (аналогичную таблицам в Excel), которая находится в оперативной памяти компьютера. Однако у Recordset есть принципиальные отличия от таблиц

Excel:

Excel не следит за «строгостью» таблиц. На предприятиях часто можно встретить таблицы, в середину которых вставлены, например, промежуточные итоги по группам или заметки. Recordset — это «строгая» таблица. В ней четко определены столбцы и строки и разрывов она не допускает (хотя какие-то значения на пересечении строк и столбцов вполне могут быть пустыми);

в таблице Excel в одном столбце без проблем можно использовать самые разные значения — числовые, даты и времени, строковые, формулы и т. п. В Recordset для каждого столбца определяется тип данных и значения в этом столбце должны соответствовать этому типу данных.

Recordset обычно создается на основе данных, полученных с источника (но может быть создан и заполнен вручную), в которых предусмотрены столбцы (Fields) и строки (Rows). Создание объекта Recordset и заполнение его данными с источника в самом простом варианте выглядит так (подразумевается, что мы открыли при помощи объекта cn соединение с учебной базой данных

Northwind на SQL Server):

Dim rs As New ADODB.Recordset rs.Open «customers», cn

Убедиться, что Recordset действительно создан и существует, можно, например, при помощи строки:

MsgBox rs.GetString

Работа с базами данных и применение объектной модели ADO

175

При открытии Recordset вполне могут возникнуть ошибки, поэтому рекомендуется использовать обработчик ошибок. Специальной коллекции Errors в Recordset не предусмотрено, а значит, придется обойтись стандартным объектом Err.

В нашем примере мы открыли таблицу Customers целиком. Однако это не единственный (и не лучший) способ извлечения данных с источника. Для метода Open() рекомендуется использовать запрос на языке SQL. Например, в нашем случае можно было бы использовать такой код:

rs.Open «select * from dbo.customers», cn

Запрос использовать лучше, потому что:

есть возможность указать фильтр Where (условие обязательно заключать в одинарные кавычки) и скачать в Recordset не все записи, а только удовлетворяющие вашему условию;

есть возможность точно так же ограничить число возвращаемых столбцов — снова сокращение объема передаваемых данных и уменьшение расхода памяти;

есть возможность использовать функции SQL, сортировку на источнике данных и множество полезных дополнительных возможностей.

Очень часто в реальных приложениях текст запроса «склеивается» из кусочков, которые поступают из разных мест. Например, пользователь выбрал в раскрывающемся списке имя заказчика, и для события Change этого списка тут же сработала процедура, которая выполнила запрос на SQL Server, получив данные только для этого заказчика, и присвоила полученные значения другим элементам управления. В нашем случае соответствующая строка кода может выглядеть так:

rs.Open «select * from dbo.customers Where CompanyName = » & «‘» _ & ComboBox1.Value & «‘» , cn

Набор символов «‘» — это одинарная кавычка внутри двух двойных. Такая конструкция нужна, чтобы текст запроса мог выглядеть, например, так:

select * from dbo.customers Where CompanyName = ‘Alfreds Futterkiste’

Причина проста — в языке SQL строковые значения нужно заключать в одинарные кавычки.

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

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

И еще один практический момент. Конечно, для работы с базами данных знать язык запросов SQL очень полезно. Литературы по нему очень много, и его вполне реально освоить за несколько дней. Однако, если вы — обычный пользователь и не имеете об языке SQL никакого представления, ничего страшного. Просто открывайте таблицы целиком без всяких запросов, а все остальное можно будет сделать средствами VBA.

9.5.2. Настройки курсора

и другие параметры открытия Recordset

При открытии объекта Recordset можно определить еще несколько важных его свойств (их можно определить как напрямую перед открытием, так и передать как дополнительные параметры методу Open()).

Первое свойство — CursorType, тип курсора. Это свойство определяется только перед открытием Recordset (после открытия оно доступно только для чтения). Курсор можно представить себе как указатель на записи в Recordset. В зависимости от типа курсора мы определяем возможности работы с Recordset и производительность выполняемых операций (чем больше возможностей, тем меньше производительность, и наоборот). Можно задавать следующие значения:

adOpenForwardOnly — это значение используется по умолчанию. Оно

оптимизировано для достижения максимальной производительности (его возможности будут минимальными). Курсор может двигаться только вперед, а изменения, вносимые другими пользователями, видны не будут;

adOpenStatic — то же самое, что и предыдущее значение, за исключе-

нием того, что курсор может двигаться во всех направлениях;

adOpenKeyset — позволяет двигаться курсору в любом направлении,

видны только изменения существующих записей другими пользователями (удаление старых записей и добавление новых не видны);

adOpenDynamic — обеспечивает максимальные возможности: позволяет

двигаться в любых направлениях, видны любые изменения в записях, производимые другими пользователями. К сожалению, провайдер Microsoft.Jet.OLEDB.4.0 этот тип курсора не поддерживает, поэтому с Access и Excel его использовать не получится.

Свойство Recordset.RecordCount нормально функционирует только для курсоров типа adOpenStatic и adOpenKeyset. Для курсоров типа

Работа с базами данных и применение объектной модели ADO

177

adOpenForwardOnly и adOpenDynamic оно возвращает 1, поскольку драйвер подключения не может определить количество записей.

Второе важное свойство — CursorLocation. Оно определяет, где будет создан курсор — на сервере или на клиенте. По умолчанию используется значение adUseServer (создавать на сервере). Второе значение — adUseClient (создавать на клиенте). В целом, практически во всех ситуациях удобнее и производительнее использовать серверные курсоры, за одним исключением — в реализации серверных курсоров на разных источниках данных много отличий, поэтому если вы планируете работать с разными источниками, имеет смысл подумать о клиентских курсорах.

Третье важное свойство — LockType. Это свойство определяет тип блокировок, которые будут наложены на записи на источнике, помещенные в Recordset. Можно использовать следующие значения:

adLockReadOnly — записи в Recordset будут доступны только для чте-

ния, вы не сможете их изменять. Это значение используется по умолчанию;

adLockPessimistic — наиболее надежный, с точки зрения целостности

данных, вид блокировки. Вы можете изменять записи в Recordset, но при начале изменения записи она блокируется на источнике таким образом, что другие пользователи не смогут обратиться к ней ни на чтение, ни на запись, пока вы не вызовете методы Update() или

CancelUpdate();

adLockOptimistic — это значение позволяет выиграть в производитель-

ности за счет проигрыша в надежности обеспечения целостности данных. Запись на источнике блокируется только на время выполнения метода Update(). Остальные пользователи могут одновременно с вами читать и изменять данные на источнике;

adLockBatchOptimistic — то же самое, что и adLockOptimistic, но вме-

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

Первый параметр метода Open() в наших примерах был как именем таблицы, так и командой SQL (могут использоваться и другие варианты). Поскольку драйвер OLE DB не знает, чем может быть передаваемый текст, он взаимодействует с сервером баз данных, чтобы определить это. На практике такое выяснение может сильно тормозить работу приложения, поэтому имеет смысл перед открытием Recordset явно указать тип передаваемых параметров. Это делается при помощи параметра Options, который передается этому методу.

Return to VBA Code Examples

In this tutorial, we will learn how to open a Recordset, count the number of records in the Recordset, loop through the Recordset, add a record, update a record, read a value from a record, and delete a record.

We have an Access Table, called ProductsT shown below:

Source Data Table

Opening a Recordset

We first need to establish the database we intend to use, in this case it is the currently opened database. We can then use the CurrentDB.OpenRecordSet method to open/create our Recordset.

In order to create a Recordset that will allow us to manipulate the data in the table called ProductsT, we would use the following code:

CurrentDb.OpenRecordset ("ProductsT")

Counting the number of Records using VBA

Once you have created a Recordset, you would more than likely want to do something useful with it or manipulate the data in it in some way. You can count the number of records in your dataset (in this case the table called ProductsT) using the following code:

MsgBox CurrentDb.OpenRecordset("ProductsT").RecordCount

Counting the number of records in a Recordset using Access VBA

Looping through a RecordSet using VBA

The following code loops through our RecordSet:

Sub RecordSet_Loop ()

Dim ourDatabase As Database
Dim ourRecordset As Recordset

Set ourDatabase = CurrentDb
Set ourRecordset = ourDatabase.OpenRecordset("ProductsT")

Do Until ourRecordset.EOF
  MsgBox ourRecordset!ProductID
  ourRecordset.MoveNext
Loop

End Sub

Adding a record to a RecordSet

Use the Recordset.AddNew method to add a new record to the RecordSet:

Sub RecordSet_Add()

With CurrentDb.OpenRecordset("ProductsT")
.AddNew
![ProductID] = 8
![ProductName] = "Product HHH"
![ProductPricePerUnit] = 10
![ProductCategory] = "Toys"
![UnitsInStock] = 15
.Update
End With


End Sub

The result is:

Updating a Recordset

You have to use the Recordset.AddNew or Recordset.Edit method. After this statement you must use the Recordset.Update method in order to keep the changes.

Reading Values from a Record

You have to use the Recordset.FindFirst method to make a record, the current record. You then have to use Recordset.Fields to specify which field to look at.

Sub RecordSet_ReadValue ()

Dim ourDatabase As Database
Dim ourRecordset As Recordset
Set ourDatabase = CurrentDb
Set ourRecordset = ourDatabase.OpenRecordset("ProductsT", Type:=RecordsetTypeEnum.dbOpenDynaset)
With ourRecordset
.FindFirst "ProductName = " & "'Product CCC'"
If .NoMatch Then
MsgBox "No Match Found"
Else
MsgBox ourRecordset.Fields("ProductCategory")
End If
End With

End Sub

The result is:

Reading Record Values from a Recordset

VBA Coding Made Easy

Stop searching for VBA code online. Learn more about AutoMacro — A VBA Code Builder that allows beginners to code procedures from scratch with minimal coding knowledge and with many time-saving features for all users!

automacro

Learn More

Deleting a Record from a Recordset

In order to delete a record from a Recordset you have to first make it the current record using the Recordset.FindFirst method. You can then delete it using the Recordset.Delete method. The following code shows how to delete record 2 in the data set:

Sub RecordSet_DeleteRecord ()

Dim ourDatabase As Database
Dim ourRecordset As Recordset

Set ourDatabase = CurrentDb
Set ourRecordset = ourDatabase.OpenRecordset("ProductsT", Type:=RecordsetTypeEnum.dbOpenDynaset)

With ourRecordset
  .FindFirst "ProductName = " & "'Product BBB'"

  If .NoMatch Then
    MsgBox "No Match Found"
  Else
    ourRecordset.Delete
  End If
End With

'Re-open Table
DoCmd.Close acTable, "ProductsT"
DoCmd.OpenTable "ProductsT"

End Sub

The result is:

Deleting a Record from a Recordset

Like this post? Please share to your friends:
  • Vba excel range по номерам ячеек
  • Vba excel range количество строк
  • Vba excel range записать
  • Vba excel hyperlink cells
  • Vba excel http запросы