Visual Basic for Applications or VBA is an important event driven programming language. It is used for creating programs which enhance the Microsoft Office suite of applications. Visual Basic for Applications is perfect for developing specific applications, whether these are office resources, graphics programs, file sorting programs, or any other kind of Windows-based software programs. Today we look at the useful and frequently used Recordset function, in this intermediate level tutorial. You require a basic level of familiarity with Microsoft Access. If you’re new to them, you should first do this introductory course to Microsoft Access. For folks who are familiar with VBA, you can just do a quick brush up with this VBA tutorial.
What is Recordset
A recordset is a structure which stores a group of records in a database. These records could be the result of a query or the contents of an individual table. Modifying the information stored in record sets does not affect the corresponding information contained in the actual database tables. Recordsets are widely employed as an integral part of database programming which includes Visual Basic for Applications.
Note that recordset is a blank table which is fully customizable with infinite rows and columns. These include whatever information a computer’s database returns, no matter how small or large. Good databases have the ability to generate and display recordsets. You can learn more about managing databases in Excel in this course.
Microsoft Office Access, a database, permits you to use VBA to create applications in Access. VBA is usually used to automate repetitive tasks in MS Office applications. MS Access is a relational database system generally used for smaller databases. A select query retrieves data from a database table. A recordset reads the content returned by the query. Here we look at a program to create a table and view its content using a select query. You can take this course from Udemy to learn more about using VBA with MS Access.
Example 1: How to use recordset in a query
Sub useRecordset() Dim strSQL1 As String Dim dbs1 As Database Dim rst1 As Recordset Dim tmpStr As String Set dbs = CurrentDb tmpStr = "Company | Last Name | " tmpStr = tmpStr& "First Name | " tmpStr = tmpStr& "Job Title | " tmpStr = tmpStr& "Business Phone" Debug.PrinttmpStr strSQL1 = "SELECT Customers.Company, Customers.[Last Name], " strSQL1 = strSQL1& "Customers.[First Name], " strSQL1 = strSQL1& "Customers.[Job Title], Customers.[Business Phone]" strSQL1 = strSQL1& "FROM Customers;" Set rst1 = dbs1.OpenRecordset(strSQL) rst1.MoveLast rst1.MoveFirst Do While Not rst1.EOF tmpStr = rst1.Fields(0).Value tmpStr = tmpStr& " | " & rst1.Fields(1).Value tmpStr = tmpStr& " | " & rst1.Fields(2).Value tmpStr = tmpStr& " | " & rst1.Fields(3).Value tmpStr = tmpStr& " | " & rst1.Fields(4).Value Debug.PrinttmpStr Rst1.MoveNext Loop rst1.Close dbs1.Close
In this program, declare the variables dbs1 as database object, rst1 as recordset object. Use SQL select command to the query the customer’s table. Open the recordset using the query. Loop through the recordset and display the records till the end of the recordset. In the end, close the database and the recordset objects.
Example 2: VBA Recordset to run a select Query
Private Sub runSelectQuery() Dim db1 As Database Dim rcrdSe1t As Recordset Dim strSQL1 As String Dim Xcntr1As Integer Set db1 = CurrentDb strSQL1 = "CREATE TABLE selectQueryData (NumField NUMBER, Tenant TEXT, Apt TEXT);" DoCmd.RunSQL (strSQL1) strSQL1 = "INSERT INTO selectQueryData (NumField, Tenant, Apt)” strSQL1 = strSQL1& "VALUES (1, 'John', 'A');" DoCmd.SetWarnings False DoCmd.RunSQL (strSQL1) strSQL1 = "INSERT INTO selectQueryData (NumField, Tenant, Apt) " strSQL1 = strSQL1& "VALUES (2, 'Susie', 'B');" DoCmd.SetWarnings False DoCmd.RunSQL (strSQL1) strSQL1 = "INSERT INTO selectQueryData (NumField, Tenant, Apt) " strSQL1 = strSQL1& "VALUES (3, 'Luis', 'C');" DoCmd.SetWarnings False DoCmd.RunSQL (strSQL1) strSQL1 = "Select selectQueryData.* from selectQueryData " strSQL1 = strSQL1& "WHERE selectQueryData.Tenant = 'Luis';" Set rcrdSet1 = db.OpenRecordset(strSQL1) rcrdSet1.MoveLast rcrdSet1.MoveFirst For Xcntr = 0 To rcrdSet1.RecordCount - 1 MsgBox "Tenant: " &rcrdSet.Fields("Tenant").Value & ", Lives in apt: " & _ rcrdSet1.Fields("Apt").Value rcrdSet1.MoveNext Next Xcntr rcrdSet1.Close db.Close End Sub
In this program, we declare the variables Db1 as database object, rcrdSet1 as recordset object, strSQL1 as string object and Xcntr as Integer.The string object is assigned a query string. DoCmd.RunSQL is a command which runs the string to create a table. A new table is created. Insert SQl command is used to insert records in the table. The recordset is opened and we move to the first record in the recordset. Display each record in the recordset until we reach the last record of the recordset. In the end we close both the recordset object and the database object.
Example 3: Program to Set the Value of a Specific Record
Dim sqlStr1 As String Dim rst1 As Recordset Dim dbs1 As Database Set dbs1 = CurrentDb sQLString = "CREATE TABLE editRecord (F_Name TEXT, L_Name TEXT)" DoCmd.SetWarnings False DoCmd.RunSQL (sQLString) Strsql1 = "INSERT INTO editRecordVALUES('JOhn','Smith')" DoCmd.RunSQL (strsql1) strsql = "INSERT INTO editRecord VALUES('George','Bailey')" DoCmd.RunSQL (strsql1) strsql = "INSERT INTO editRecord VALUES('Glen','Maxwell')" DoCmd.RunSQL (strsql1) Set rst1 = dbs.OpenRecordset("SELECT editRecord.* FROM editRecord") Set rst1 = dbs.OpenRecordset("SELECT editRecord.* FROM editRecord") rst1.Move (2) rst1.Edit rst1.Fields("F_Name").Value = "PAUL" rst1.Update rst1.Close Set dbs = Nothing
In this program, we declare sqlStr1 as string variable, rst1 as recordset object and dbs1 as database object. A new table is created using the DoCmd.RunSQL command. Three records are inserted into the table. A recordset is created by querying the table for allits records.We move through the record set to the record number 3 and update the “F_name” field to “Paul.” Then close the recordset. Press “F5” Functional key to run the subroutine. You may want to learn more about Microsoft Access with this course to understand these examples better.
Example 4: Search for Records in a Table
Sub searchRecords() Dim rst1 As Recordset Dim dbs1 As Database Dim stringToSearch1 As String Set dbs1 = CurrentDb stringToSearch1 = "Dyna" Set rst1 = dbs1.OpenRecordset("SELECT Customers.* FROM Customers") Set rst1 = dbs1.OpenRecordset("SELECT <table name>.* FROM <table name>") Rst1.MoveFirst Do While Not rst1.EOF If rst1.Fields("First Name").Value = stringToSearch1 Then MsgBox "Found "&stringToSearch& " in record number: " & rst1.AbsolutePosition rst1.MoveLast Else Rst1.MoveNext End If Loop stringToSearch1 = "<your text to search>" If rst1.Fields("<your column name>").Value = stringToSearch Then rst1.Close dbs1.Close
In the program, we declare the variables rst1 as Recordset object and dbs1 as database object. Create a recordset by querying the customer’s table. Move to the first record of the recordset. Loop through the recordset by incrementing recordset position and search for “Dyna” in the first name column. After the record is found, close the recordset and database objects. This course on using VBA with Microsoft Access has many more examples you may want to try out.
Example 5: How to copy from a recordset into a Table
Sub RecordsetExample() Dim dbTest1 as Database Dim rsRecordset1 as Recordset Dim sqlStatement1 as String Set dbTest1 = OpenDatabase("MyDatabase.mbd") set rsRecordset1 = .OpenRecordset("Table1",dbOpenTable) End With sqlStatement1 = "INSERT INTO Table2 VALUES" & rsRecordset1 With rsRecordset1 rsRecordset1.MoveFirst Do rsRecordset1.RunSQL(sqlStatement1) rsRecordset1.MoveNext Loop While Not rsRecordset1.EOF End With End Sub
Declare the variables dbTest1, rsRecordset1,sqlStatement1 as type database, recordset and string objects respectively. Open the recordset object read the records and inserts the values into the database table. This operation terminates reaching the end of the recordset. In the end close the database and recordset objects.
Example 6:How to Use VBA to Import Data From Excel Into Access
Sub importExcelData() Dim xlApp As Excel.Application Dim xlBk As Excel.Workbook Dim xlSht As Excel.Worksheet Dim dbRst1 As Recordset Dim dbs1 As Database Dim SQLStrAs String Set dbs1 = CurrentDb Set xlApp = Excel.Application Set xlBk = xlApp.Workbooks.Open("C:TempdataToImport.xlsx") Set xlSht = xlBk.Sheets(1) SQLStr = "CREATE TABLE excelData(columnOne TEXT, columnTwo TEXT)" DoCmd.SetWarnings False DoCmd.RunSQL (SQLStr) Set dbRst1 = dbs.OpenRecordset("excelData") dbRst1.AddNew xlSht.Range("A2").Select dbRst1.Fields(0).Value = xlSht.Range("A2").Value xlSht.Range("B2").Select dbRst1.Fields(1).Value = xlSht.Range("B2").Value dbRst1.Update dbRst1.Close dbs1.Close xlBk.Close End Sub
In the beginning, we declare xlApp, xlBk and xlSht as variables you will use to read Excel. Also, we declare the variables dbrst1 as recordset object and dbs1 as database object. Use DoCmd.RunSQL to execute an SQL command. We get values from the Excel workbook, save them to your table and update the records. In the end always remember to close the database and recordset objects. If you’d like a more hands on approach, you can check out this course on MS Access.
Hope you had fun learning the Recordset function. Programming is best learnt by creating your own programs. Go through the examples above and play with the code. Once you’re ready to move it up to the next level, you can take this advanced VBA course for Microsoft Access by Simon Sez. It has a lot more juice and tips to make your work with MS Access so much more easier!
Содержание
- 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>
Содержание
- Как в Access на VBA выгрузить Recordset в Excel?
- Исходные данные
- Код VBA для выгрузки Recordset формы в Excel
- Код VBA для выгрузки объекта Recordset в Excel
- Метод DoCmd.TransferSpreadsheet (Access)
- Синтаксис
- Параметры
- Примечания
- Пример
- Поддержка и обратная связь
- Subscribe to Developer Soapbox
- Export Microsoft Access Data to Excel
- Developer
- Developer
- The Simple Way
- For More Complex Cases
- DEVelopers HUT
- Taking Things Even Further :: ExportRecordset2XLS V2.0!
- Download
- Disclaimer/Notes:
- The YouTube Demo File:
- The Original Article File:
- 21 responses on “ MS Access – VBA – Export RecordSet to Excel ”
- Leave a Reply Cancel reply
- My YouTube Channel
Как в Access на VBA выгрузить Recordset в Excel?
Всем привет! Материал сегодня будет посвящен рассмотрению возможности Access выгружать Recordset в Excel на VBA. Данный способ достаточно простой и предполагает использование Recordset как формы, так и специально созданного объекта.
Ранее мы с Вами уже рассматривали возможность выгрузки данных из Access в Excel в материале «Выгрузка данных из Access в шаблон Word и Excel», но там мы использовали специально созданный шаблон, что не совсем удобно, если например, нам необходимо выгрузить просто набор данных с заголовками полей.
Также если кого интересует, недавно мы рассматривали возможность выгрузки данных из базы MS SQL Server в формат CSV (текстовый файл с разделителями) с помощью VBA Access в материале «Экспорт данных в CSV файл из Microsoft SQL Server, используя Access 2003».
Сейчас я покажу простой пример реализации возможности выгружать наборы данных с заголовками из базы MS SQL Server средствами VBA Access в Excel.
Весь смысл сводится в использование метода CopyFromRecordset, который позволяет переносить Recordset в Excel в том виде, какой он и есть, т.е. в виде таблицы. Единственное что нам необходимо будет сделать, это выгрузить заголовки, чтобы было понятней, что за данные содержатся в той или иной колонке.
Итак, давайте приступать и для начала рассмотрим исходные данные.
Примечание! В качестве примера источником данных у меня будет выступать MS SQL Server 2012 Express, а в качестве клиента ADP проект Access 2003. Также на компьютере клиенте установлен Microsoft Office 2010.
Исходные данные
Допустим, на сервере у нас есть таблица TestTable.
И она содержит следующие данные.
Также допустим, что в ADP проекте Access у нас есть форма, источником данных которой выступает наша тестовая таблица TestTable.
Код VBA для выгрузки Recordset формы в Excel
Сначала давайте рассмотрим пример выгрузки объекта Recordset формы в Excel. Для этого добавляем на форму кнопку, для примера я ее назвал RSExportInExcel. В обработку события нажатие кнопки вставляем следующий код, я его прокомментировал:
Сохраняем изменения и пробуем нажать на кнопку. В итоге у нас запустится Excel, а в нем будут необходимые нам данные.
Примечание! Свойства HorizontalAlignment и VerticalAlignment могут не работать, если на компьютере не установлен Microsoft Office 2010, поэтому в случае возникновения ошибок связанных с этими свойствами просто закомментируйте их.
Код VBA для выгрузки объекта Recordset в Excel
Теперь давайте напишем код, который позволяет выгружать объект Recordset, данные которого получены, скажем с помощью запроса к базе данных. Для этого добавьте еще одну кнопку (я ее назвал RSExportInExcel2) и вставьте немного модифицированный код:
Снова сохраняем и пробуем нажать на кнопку, в итоге у нас получится точно такая же выгрузка, как и чуть ранее, только сейчас в качестве источника данных Recordset у нас может выступать любой запрос, а не только данные формы.
На этом у меня все! Надеюсь, материал был Вам полезен, пока!
Источник
Метод DoCmd.TransferSpreadsheet (Access)
Метод TransferSpreadsheet выполняет действие TransferSpreadsheet в Visual Basic.
Синтаксис
выражение.TransferSpreadsheet (TransferType, SpreadsheetType, TableName, FileName, HasFieldNames, Range, UseOA)
выражение: переменная, представляющая объект DoCmd.
Параметры
Имя | Обязательный или необязательный | Тип данных | Описание |
---|---|---|---|
TransferType | Необязательный | AcDataTransferType | Нужный тип переноса. Значение по умолчанию — acImport. |
SpreadsheetType | Необязательный | AcSpreadSheetType | Тип электронной таблицы для импорта, экспорта или связи. |
TableName | Необязательный | Variant | Строковое выражение, являющееся именем таблицы Office Access, предназначенной для импорта данных электронной таблицы, экспорта данных электронной таблицы или связывания данных электронной таблицы, или запрос на выборку Access, результаты которого нужно экспортировать в электронную таблицу. |
FileName | Необязательный | Variant | Строковое выражение, являющееся именем и путем электронной таблицы для импорта, экспорта или связывания. |
HasFieldNames | Необязательный | Variant | Используйте значение True (1), чтобы использовать первую строку электронной таблицы в качестве имен полей при импорте или связывании. Используйте значение False (0), чтобы считать первую строку электронной таблицы обычными данными. Если оставить этот аргумент пустым, предполагается, что используется значение по умолчанию (False). При экспорте таблицы или данных запроса на выборку Access в электронную таблицу имена полей записываются в первую строку электронной таблицы независимо от введенного значения этого аргумента. |
Range | Необязательный | Variant | Строковое выражение, являющееся допустимым диапазоном ячеек или именем диапазона в электронной таблице. Этот аргумент применяется только для импорта. Чтобы импортировать электронную таблицу целиком, оставьте этот аргумент пустым. При экспорте в электронную таблицу необходимо оставить этот аргумент пустым. Если ввести диапазон, экспорт завершится сбоем. |
UseOA | Необязательный | Variant | Этот аргумент не поддерживается. |
Примечания
Используйте метод TransferSpreadsheet для импорта или экспорта данных между текущей базой данных Access или проектом Access (ADP) и файлом электронной таблицы. Вы также можете связать данные в электронной таблице Excel с текущей базой данных Access. Это позволит просматривать и изменять данные электронной таблицы с помощью Access, при этом не теряя возможность полного доступа к ним в Excel. Кроме того, вы можете связать данные в файле электронной таблицы Lotus 1-2-3, но они будут доступны в Access только для чтения.
Также можно использовать объекты данных ActiveX (ADO) для создания связи с помощью свойства ActiveConnection для объекта Recordset.
Пример
В следующем примере импортируются данные из указанного диапазона электронной таблицы Lotus Newemps.wk3 в таблицу Employees (Сотрудники) Access. В качестве имен полей используется первая строка электронной таблицы.
Поддержка и обратная связь
Есть вопросы или отзывы, касающиеся Office VBA или этой статьи? Руководство по другим способам получения поддержки и отправки отзывов см. в статье Поддержка Office VBA и обратная связь.
Источник
Subscribe to Developer Soapbox
Stay up to date! Get all the latest & greatest posts delivered straight to your inbox
Export Microsoft Access Data to Excel
Developer
Our resident opinionated developer.
Developer
For this example, we will be using a simple table with a list of beer names. Our goal is to export the contents of this table into an Excel workbook.
Access provides two ways to do this. If you wish to export the entire table, without any frills, Access provides a simple method to export (and import or link) Excel data.
If you need to use some custom logic while exporting though, you can also use VBA’s Excel object model. You will learn both ways in this tutorial.
Test Data
As mentioned, we will use the very simple data below for this tutorial.
The Simple Way
1. Create VBA Procedure
Microsoft Access provides the very handy method DoCmd.TransferSpreadsheet to export, import, or link Excel data. The procedure below shows how to use this method to export our simple table. Create a new VBA Module and paste the code.
2. Run Procedure
Run the procedure and check that the file was created in the path listed in the excel_file_name variable in your procedure. You will notice that the field names were also exported. This is one of the parameters for TransferSpreadsheet , which can be excluded if needed.
For More Complex Cases
1. Import Excel References
In order to use the Excel object model in VBA, we must first import the Excel object library reference. This can be done by going to Tools->References in the VBA editor menu.
Scroll down to the “Microsoft Excel Object Library” entry (Excel version may vary), check it, and click OK.
2. Create VBA Procedure
Although the name of the tutorial step is the same, more complex cases require more than a single method. The code below uses VBA’s Excel object model to create a workbook and write to cells within a sheet.
3. Run Procedure
Run the procedure and check that the file was created in the path listed in excelfilename variable for your procedure.
As you can see, we were able to do some customization by using the Excel object model. For example, we were able to append to the text for each record, and format the header font. Basically, anything you can do in Excel can be done in VBA using the object model.
Источник
DEVelopers HUT
Very similarly to my MS Access – VBA – Export Records to Excel post, I found myself needing to easily export a form’s recordset to Excel. Not the underlying table or query, but the filtered, currently viewed recordset. I already had the above code so I made a few very minor tweaks et voila I had a new function that could export, with ease, any recordset to Excel. Hopefully it can help someone else!
As you can see by examining the code it includes Conditional Compiling Directive so you can have it either as Early or Late Binding to suit your preferences.
Furthermore, the following sections of code are completely optional and are simply used to perform some basic formatting (pretty things up and make the worksheet easier to work with IMHO). I’ve left it in place should it be useful to you and also to illustrate how easily you can perform other automations at the same time as performing the export (show some of the syntax). Feel free to remove it as you see fit.
Taking Things Even Further :: ExportRecordset2XLS V2.0!
Now the above functions does exactly as intended, but what if we wanted more flexibility and more control over what is applied depending on the situation! This is the beauty of VBA once you truly get into it, you can develop some true coding gems that can be utilized in all sorts of situations.
So let reexamine the above function, how could we modify it to not need to actually remove sections of code depending on whether or not we want autofilters applies, or freeze panes, …? How could we make if flexible enough to even allow the user to specify an exist workbook to export to, and if none is specified then create a new one. How can we make a universal function?
Surprisingly, with a pretty small number of tweak to the above function we can do all that!
Download
Feel free to download a copy by using the links provided below:
Disclaimer/Notes:
All code samples, download samples, links, . on this site are provided ‘AS IS‘.
In no event will Devhut.net or CARDA Consultants Inc. be liable to the client/end-user or any third party for any damages, including any lost profits, lost savings or other incidental, consequential or special damages arising out of the operation of or inability to operate the software which CARDA Consultants Inc. has provided, even if CARDA Consultants Inc. has been advised of the possibility of such damages.
The YouTube Demo File:
Download “Access — Export to Excel”
The Original Article File:
As requested, feel free to download a fully function sample 2003 mdb of the above code which illustrates how it can be implemented.
Export Recordset To Excel (2K3 mdb)
21 responses on “ MS Access – VBA – Export RecordSet to Excel ”
Sorry I found the error, the Usage you put in the comments isn’t the right name compared to the actual function name: Export2XLS vs ExportRecordset2XLS
The code works great by the way except for one thing. it doesn’t actually copy the data across… The header titles are all right and formatted but there’s no lines of data… Help?
Thank you for the heads up. As you can tell the code evolved over time. I have update the usage to use the proper procedure name now.
I’m trying to use this code Function but having issues. I copied the Function to a ‘module’ – it compiled, no issues. I then added the following code to ‘Report_Open’ and it’s not working –
Dim rst As DAO.Recordset
‘Set rst = Me.Recordset
‘Set rst = Me.Recordset.Clone
(I TRIED EACH TO THE ABOVE (2) ‘SET’ STATEMENTS AND NEITHER WORK.
Call ExportRecordset2XLS(rst)
Any suggestions would be greatly appreciated and thanks for your help!
What happens exactly? Do you receive any error messages?
I just quickly tested and place my code in a standard module and added a button to a random form and tried (using the button’s On Click event)
and both worked fine.
That said, I’m confused by the choice of Event you are trying to use. Normally, you’d call this function from a command button that the user initiates, so the On Click event.
Also, be sure that Excel didn’t open up in the background somewhere. You may need to use some Windows APIs to bring Excel to the forefront when you run this procedure (that’s what I do when I call any external program to ensure it gains the focus and isn’t hidden from the user).
Copied both your suggested functions and noon eo them get past this line
Set oExcel = GetObject(, “Excel.Application”) ‘Bind to existing instance of Excel
gives me a error message
run time error 429 ActiveX component can’t create object
any suggestions
I went to references and added references to anything that resembled the words active X , script & excel
Considering the line right above is a On Error Resume Next statement that extremely odd.
What is your Error Handling Settings?
Tools->Options->General->Error Trapping
It should be set to Break on Unhandled Errors
There is no need to for any References whatsoever. That is the whole point of using Late Binding!
You do have Excel installed on your computer?
error trapping is set to “Break on all errors ” why
OMG…I changed the Break on all errors to either of the other 2 options and now I don’t get an Error abut active X…what on earth does this have to do with Active X 429…Microsoft developers need to get a grip with the error messages ..the ones that have no apparent reference to the real issue and as a result of that they throw you in a complete wrong direction.
Thank for your help as I would never have solved this one…ever in a million years!!
Now were talking your code is amazing ..Love it now have something I can work and play with..
Hi Daniel,
Thanks for all your great Access help and code samples!
Apparently I either don’t understand or passing the sFile info incorrectly. Based on the sFile input variable comment, I assumed if I passed a file path & name the routine would create a new Excel file and export the recordset data. But I am receiving an error when I provide the sFile info. I’m getting the following error info:
Error Number = 1004
Error Description = Sorry, we couldn’t find C:TEMP qryMyTestQuery.xlsx. Is it possible it was moved, renamed or deleted?
The error is on the following line:
Set oExcelWrkBk = oExcel.Workbooks.Open(sFile) ‘Start a new workbook
My test routine:
Private Sub ExportMyData()
Dim db As DAO.Database
Dim rsQuery As DAO.Recordset
Set db = CurrentDb
Set rsQuery = db.OpenRecordset(“qryMyTestQuery”, dbOpenSnapshot)
Call ExportRecordset2XLS(rsQuery, “C:TEMPqryMyTestQuery.xlsx”)
Set rsQuery = Nothing
Set db = Nothing
End Sub
Please help me understand how to correctly utilize the sFile feature.
Again thanks for all your help!
sFile is used to open/append an existing workbook. If you want a new workbbok to be created then you simply omit the sFile input variable.
That said, I think I understand what you would like to happen, that is create a new file, export the data and save it as sFile. I will see what I can do.
You are correct . My thought – if the file exists, then open/append the existing workbook. If the file does not exist, create a new file, export the recordset, and save the file.
The Input Parameter notes implies this functionality:
sFile Optional -> File path and name to update
‘If none is provided a new Excel file is created
Thanks for all you help!
“If none is provided a new Excel file is created Thanks for all you help!”
That’s exactly what it currently does. If you omit the sFile input variable then a new instance of Excel is created with a new blank workbook in which the data is imported. Then it is up to the user as to how/where to save it.
That all said, I like your idea, and will see what I can do at a later date.
Hello Daniel,
I am using your code to export the data to excel worksheet but i have one problem with Richtext.
For ex.
if I have column in database with datatype ‘LongText’ and TextFormat ‘Richtext’ than after exporting to excel it shows me a tags of html Like ‘div’ ‘br’ etc..
How can i export to excel without any such tags?
Can you help me on this.?
Thanks for your input.
Hello Daniel,
Great code, it saves me a lot of time and works great at the first try
Will be embedded in a powershell applet (let’s play the fool)
Thank you! Worked first go!
I really appreciate you sharing this function 🙂
Awesome and thank-you soooo much Daniel, saved a novice like me big time.
Thanks for sharing this little bit of your IP as it is truly appreciated.
Hello everyone,
This function is extremely well made, and it also works with ADO, only one tiny tweak necessary: “ByVal rs As DAO.Recordset” -> “ByVal rs As ADODB.Recordset”.
Many thanks Daniel.
Pierre
Thank you for sharing. I’m sure others will find that option useful.
Thanks for this smart & friendly solution, worked well for me.
Leave a Reply Cancel reply
If you found this site helpful, consider giving a donation to offset the costs to keeping it running and thank you.
My YouTube Channel
Be sure to check out my latest videos on Access, Excel, VBA and more . by visiting:
Источник
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:
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
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:
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!
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:
Dear Friends,
In my previous article, I emphasized mainly on how to execute different kind of queries in database using Excel VBA. I covered one example How to display or spread a RecordSet in excel Sheet. But in this article I am going to focus on different ways of reading RecordSet Object.
How to get Column Names from your recordSet Object
RecordSetObject.Fields.Count gives the total number of Columns present in your RecordSet Object. You can use following for loop to get all all the column names of a recordSet in your Excel Sheet.
Following is the Syntax to get the column names of a recordSet where all the records are stored.
Column Name of First Column = RecordSetObject(0).Name
Column Name of Second Column = RecordSetObject(1).Name
Similarly…
Column Name of Last Column = RecordSetObject(Total Columns – 1).Name
For DBCol = 0 To RecordSetObject.Fields.Count - 1
Worksheets("Data").Cells(xlRow, xlCol).Value = RecordSetObject(DBCol).Name
xlCol = xlCol + 1 'move to next column in same row
Next
RecordSet Object stores all the columns in form of an Array which can be accessed by passing an array Index which starts from Zero (0). This is why in above for loop, DBCol Index variable is initialized from Zero and goes up to one less than total number of columns available ( 0 to n-1 )
1. Spreading the whole RecordSet in Sheet (Without Loop)
I have explained this with an Example VBA code in my previous article. Click here to read and understand this Method.
2. Reading the whole RecordSet Object using Loop
RecordSetObject(0).Value gives you the value of the 1st Column value of the 1st Record of your RecordSet Object. .MoveNext is the method of your RecordSet Object which takes you to the Next Record of your recordSet. Below is the VBA code snippet which reads all the Records of your RecordSet and put it in your Excel Sheet named Data.
xlRow = 1 ' Set it for your Excel Sheet Starting Row
Do While Not RecordSetObject.EOF 'to traverse till last record
'This for loop will display the values
'of all column values in one Single record
xlCol = 1 'Every next Record Should start from Starting Column
For DBCol = 0 To RecordSetObject.Fields.Count - 1
Worksheets("Data").Cells(xlRow, xlCol).Value = RecordSetObject(DBCol).Value
xlCol = xlCol + 1 'move to next column in same row
Next
RecordSetObject.MoveNext 'This moves the loop to next record from the record set
xlRow = xlRow + 1 'Move to next row in Excel
Loop
3. Reading RecordSet Values by Passing Column Names
Above VBA code reads all the column values from the RecordSet by passing the Column Index – 0 to Total Columns-1. Suppose, If you want to read values of a particular column which Name is known to you but it could be 1st Column or 2nd Column or any nth column of your RecordSet Object. I will explain you the method of accessing the value of a column by passing the column name rather Column Index as passed in above example.
Syntax is very much same as above. Instead of passing the Index Number of the Column, you need to pass the Column Name in Double Quotes (” “). RecordSetObject(“Column_Name”).Value
xlRow = 1 ' Set it for your Excel Sheet Starting Row
Do While Not DBrs.EOF 'to loop till last record of the recordSet
Worksheets("Data").Cells(xlRow, 1).Value = RecordSetObject("Column_NAME_1").Value
Worksheets("Data").Cells(xlRow, 2).Value = RecordSetObject("Column_NAME_2").Value
Worksheets("Data").Cells(xlRow, 3).Value = RecordSetObject("Column_NAME_3").Value
DBrs.MoveNext 'This reads the next record from the record set
xlRow = xlRow + 1 'Move to next row in Excel
Loop
I prefer accessing column values by passing the column name. There are two benefits of using this method:
1. In case of Select * from… queries you do not need to check the position of your column to access it. No matter at what position your column is..can be accessed correctly from this method.
2. Easy to debug: While debugging your code – Statement RecordSetObject(“Column_NAME_1”).Value is clearly understood without referring the actual database table as compared to RecordSetObject(5).Value. To know which column is being referred in this statement I need to check the NAME proprty of the 5th Column of your RecordSet
Are you facing any difficulty in accessing your RecordSet Object?? Put your queries here in comment. We will try to get back on that ASAP 🙂
Table of Contents
Definitive Guide To ADO in Excel and VBA
There are several methods to work with external data and files in Excel. ADO (ActiveX Data Objects) is one of the best and most frequently used tools to work with external data and files. In Excel, we can use the combination of ADO with VBA (Visual Basic for Applications) to work with external data sets in memory. ADO always comes in handy when we need to perform complex, multi-layered procedures and checks on external datasets.
What is ActiveX Data Objects (ADO)?
ADO in Excel and VBA is a tool in that helps developers to write VBA code to access data without knowing how the database is implemented; developers should be aware of the database connectivity only. Being a developer, you don’t need to know the SQL to access a database when using ADO, although you can run SQL commands directly using ADO. So, in short, ADO helps developers accomplish two major tasks:
- Connect to a data source
- Specify the datasets with which to work
Using the ADODB connection, we connect our VBA application with the databases e.g., SQL, MS Access, Microsoft List, Excel workbook, etc.,
Understanding the fundamental syntax of ADO (Connection String and Recordset)
While dealing with external data and files, we must connect the data source before doing anything. To establish the connection, we must provide VBA a few pieces of information. The required information will be provided to VBA in the form of the connection string.
What is a connection string?
A connection string is nothing but a text string that contains a series of variables (also called arguments), which VBA uses to identify the data source and open the connection for further use.
Let’s understand the connection string and its arguments that point to an MS Access database and MS Excel Workbook. You can find several other connection strings at ConnectionStrings.com – Forgot that connection string? Get it here!
Connection Sting – MS Access database
“Provider=Microsoft.ACE.OLEDB.12.0; ” & _
“Data Source= C:MyDatabase.accdb;” & _
“User ID= Administrator;” & _
“Password= AdminPassword”
Connection Sting – MS Excel workbook
“Provider=Microsoft.ACE.OLEDB.12.0; ” & _
“Data Source= C:MyExcelWorkbook.xlsx;” & _
“Extended Properties=Excel 12.0”
ADO connection string can have multiple arguments basis the data source type. Let’s understand the arguments which commonly used i.e., Provider, Data Source, Extended Properties, User ID, and Password (the same have been used in the previous example for MS Access and Excel).
Live Project – Data Entry Application in Excel and VBA using ADO
Data Entry Application in Excel and Access
Provider: With the help of Provider argument in the connection string, VBA identifies the type of data source we are going to work with. Suppose we are going to work with MS Access or MS Excel datasets, then the Provider syntax will be:
Provider=Microsoft.ACE.OLEDB.12.0
Data Source: This argument helps VBA to find the source of database or workbook that contains the data needed. For this parameter, we need to pass the full path of the database or workbook. For example:
Data Source=C:MydirectoryMyDatabaseName.accdb
Extended Properties: Extended Properties is required when we connect to an Excel Workbook. With the help of this argument, VBA identifies that data source is something else than a database. You can use this argument below:
Extended Properties=Excel 12.0
User ID: The User ID argument is optional and only used if the data source is protected with a user id and password. For example:
User Id = Admin
Password: This argument is optional and only need if the password is required to connect to the data source. For example:
Password = MyPassword
Note: You can skip User ID and Password arguments if the data source is not protected.
What is a Recordset?
A Recordset object is a group of records that can either come from a data source or as the output of a query to the table. The Recordset provides several methods and properties to examine the data that exists within the data source.
In addition to building a connection to the data source, we need to define the dataset (Recordset) with which we need to work. We can define the Recordset to open an existing table or query using the 4 common arguments: Source, ConnectString, CursorType, and LockType.
Recordset.Open Source, ConnectString, CursorType, LockType
Let’s understand all these 4 parameters.
Source in Recordset
The source data is typically a table, a SQL statement, or a query that retrieves records from the data source. Please see the below example of Source in different scenarios.
Providing MS Access table name ‘Product’ to Source
Recordset.Open “Product”
SQL statement to Source. In below code, MySQL is a variable holding SQL statement.
MySQL=”Select * from [Product] where Region=”North’”
Recordset.Open MySQL
ConnectString in Recordset
ConnectString is the argument that we have already discussed while understanding the ConnectionString. We just need to pass the ConnectionString here so that Recordset can identify the data source.
So, suppose we are going to connect with MS Access table ‘Product’ in Recordset then the code will be like:
Recordset.Open Product, ConnectionString
CursorType in Recordset
A cursor is a mechanism that enables the Recordset to move over the records in a database. It allows developers to retrieve each row at a time and manipulate its data. In simple language, a cursor is nothing more than a point to a row on which you are performing the data manipulation work.
The CursorType that are commonly used in Recordset code:
- adOpenForwardOnly: This is the default cursor type available in Recordset. If we don’t pass any CursorType in the code, then Recordset will automatically consider adOpenForwardOnly. This cursor is very efficient and allows us to move through the Recordset from beginning to end (one way only). This cursor is ideal for reporting purposes where we need to extract the data. This cursor does not allow to perform any changes to data.
- adOpenDynamic: When we need to loop through the data, moving up and down in the datasets, and want to identify any edits made to the dataset then adOpenDynamic can be used in Recordset. As it performs almost all the activities required in database operation, this cursor takes a lot of memory and resources of the system and should be used only when needed.
- adOpenStatic: This CursorType is ideal for quick return as it uses a static copy of data from the database. This is different from adOpenForwardOnly CursorType as it allows the developer to navigate the returned records. In addition to these, this CursorType allows data to be updateable by setting the LockType except adLockReadOnly (we will see LockType in upcoming part of this blog).
LockType: A LockType is a mechanism that helps developer to apply restrictions on a table or datasets to avoid unauthorized access or changes to the Recordset. We usually use two LockType in ADO:
- adLockReadOnly: This is the default LockType in Recordset which indicates that there is no need to edit the data returned. If we don’t provide the LockType to Recordset then VBA considers this internally.
- adLockOptimistic: This LockType is ideal when we need to edit the data returned to Recordset. We can use this if we want to perform Add, Update and Delete method in the database.
Referencing the ADO object library in VBA
Now, we have strong fundamentals of ADO and the codes/arguments. Let’s create our own ADO procedures to perform some basic operations. It will help us get more clarity and understanding of ADO in real projects.
To use the ADO in the Excel project, we need to add the reference of the ADO object library in the Visual Basic Application (VBA) window. Once we add the reference of ADO in the Excel project, Excel will start understanding the objects, properties, and methods of ADO.
Note: we can use ADO library without giving the reference of ADO in Excel with Late Binding technique, but it will increase the complexity of code and you will not be able to get the help while writing the code. So, we would recommend you start using the Early Binding i.e., giving the reference of ADO and then writing the code. Once you have expertise in the code then you can move to Late Binding technique.
To start adding the reference of ADO, just open the MS Excel application and create a new workbook and save the file with a Macro enabled extension e.g., .xlsm. Open the Visual Basic Editor window using the Shortcut key ALT + F11.
Once Visual Basic Editor window will appear on screen then click on Tools (available in the application menu) -> References….
Once you click on References.. then it will open the References dialog box as shown in the picture below. In the available references list, just scroll down until you find the latest version of the Microsoft ActiveX Data Objects Library. Just tick the Checkbox and click on the OK button available in the dialog box to add the ADO reference to the current Excel file.
Note: you can see several versions of the ADO library in Reference dialog box. We would recommend you select the latest version from the list or if you are developing a project for your client then check the version of MS Excel and available ADO on client system and then go with that library to make your code compatible.
After clicking on OK button, we can open the Reference dialog box again to ensure that whether the ADO reference is selected or not. If that is selected, then it will start appearing on top of the list as check marked (as you can see in above image).
VBA code to Use ADO and get data from MS Access database
Writing the code to get the data from Customer table of MS Access database.
Sub GetCustomerData ()
Dim MyConnect as String
Dim MyRecordset as ADODB.Recordset
MyConnect= “Provider=Micorosft.ACE.OLEDB.12.0;” & _
“Data Source= D:TheDataLabsSales.accdb”
Set MyRecordset= New ADODB.Recordset
MyRecordset.Open “Customer”, MyConnect, adOpenStatic, adLockReadOnly
ThisWorkbook.Sheets(“Customer”).Range(“A2”).CopyFromRecordset MyRecorset
With ActiveSheet.Range (“A1:C1”)
.value = Array (“Name”, “Gender”, “Address”)
.EntireColumn.AutoFit
End With
End Sub
Now we are done with putting all the code together in a procedure to get the data from Customer table and provide the output in MS Excel worksheet “Customer”.
Understand VBA Codes line by line
For better clarity, let’s take a moment to understand the VBA code.
Sub GetCustomerData ()
With the help of this line, we are declaring a procedure named ‘GetCustomerData’.
Dim MyConnect as String
Declaring a string variable to hold the Connection sting so that VBA can identify the data source.
Dim MyRecordset as ADODB.Recordset
Declaring a Recordset object variable to hold the data that will be returned by the procedure.
MyConnect= “Provider=Micorosft.ACE.OLEDB.12.0; Data Source= D:TheDataLabsSales.accdb”
Here, we are defining the connection string for the ADO procedure. As we are connecting the ‘Sales’ MS database to get the data from the Customer table hence, we are passing the Provider parameter as Micorosft.ACE.OLEDB.12.0 and Source as D:TheDataLabsSales.accdb. The same has been already discussed in the Connection String section of the post.
Set MyRecordset= New ADODB.Recordset
With the help of the line of code, we are setting the reference of ADODB Recordset to MyRecordset object variable.
MyRecordset.Open “Customer”, MyConnect, adOpenStatic, adLockReadOnly
This line of code helps us in opening the Recordset to return static and read-only data.
ThisWorkbook.Sheets(“Customer”).Range(“A2”).CopyFromRecordset MyRecorset
Here, we are using Excel’s CopyFromRecordset method to get the data from the Recordset and provide the output in the range starting from the “A2” to the spreadsheet named ‘Customer’.
With ActiveSheet.Range (“A1:C1”) …. End With
These lines of Code help us in getting the column header and putting the header name in active sheet range A1 to C1. We need these lines of code because the CopyFromRecordset method does not return column headers or field names.
Live Project in Excel
Using ADO with Microsoft Visual Basic, we have developed the Data Entry Application Project in MS Excel and MS Access to transfer the data. Refer the below link.
Data Entry Application in Excel and Access
Interested in developing Data Entry Form without Using ADO
Easy-To-Follow: Create a Fully Automated Data Entry Userform in Excel and VBA in 5 Easy Steps
How to Create a Multi-User Data Entry Form in Excel (Step-by-step Guide)
Advance Data Entry Form
Read more topics
If you have any question on ‘Definitive Guide To ADO in Excel and VBA’ then please leave your comment in comment section. Thanks!
Работа с внешними источниками данных
Материалы по работе с внешними источниками данных на примере Excel и SQL.
Рассмотрим способы передачи данных между Excel и внешней базой данной на SQL сервере с помощью ADO.
Задача первая. Подключаемся к внешней базе данных.
Для начала надо подключиться к внешней базе данных. Подключение возможно если на компьютере установлен драйвер. Список установленных драйверов для подключения к базам данных на компьютере под управлением Windows:
Панель управленияВсе элементы панели управленияАдминистрированиеИсточники данных (ODBC)
Проверить подключение к базе данных можно простым способом. Создаем пустой файл (например, «текстовый документ.txt»), затем изменяем имя и расширение на .udl (например, «connect.udl»). Двойной клик мышкой по новому файлу, далее приступаете к настройке и проверке подключения к базе данных. После того, как удалось настроить корректное подключение к базе данных, сохраняем файл «connect.udl». Открываем файл «connect.udl» обычным текстовым редактором (например, блокнотом), и видим в строке подключения все необходимые параметры. Про подключение к внешним базам данных можно посмотреть на ресурсе ConnectionStrings .
Теперь возвращаемся к нашему VBA для Excel. В редакторе VBA подключаем последнюю версию библиотеки:
Microsoft ActiveX Data Objects Library
Пример кода:
Sub TestConnection() Dim cn As ADODB.Connection Set cn = New ADODB.Connection cn.ConnectionString = "" 'Параметры строки подключения cn.Open 'Открываем подключение cn.Close 'Закрываем подключение Set cn = Nothing 'Стираем объект из памяти End Sub
Задача вторая. Загружаем данные из внешней базы данных на SQL сервере в Excel.
После того, как мы установили подключение к внешней базе данных можно приступать к чтению данных и выводу в Excel. Здесь потребуется знание языка запросов SQL. В результате выполнения SQL запроса к нам возвращается некая таблица с данными в объект RecordSet. Далее из объекта RecordSet можно выгружать данные непосредственно на лист или в сводную таблицу.
Пример кода простой процедуры:
Sub LoadData() Dim cn As ADODB.Connection Dim rst As ADODB.Recordset Set cn = New ADODB.Connection Set rst = New ADODB.Recordset cn.ConnectionString = "" 'Параметры строки подключения cn.Open rst.Open "SELECT TOP 10 * FROM <таблица>", cn 'SQL-запрос, подключение ActiveSheet.Range("A1").CopyFromRecordset rst 'Извлекаем данные на лист rst.Close cn.Close Set rst = Nothing Set cn = Nothing End Sub
Для удобства работы. Предлагаю создать собственный класс «tSQL» для работы с базой данных. У класса будет одно свойство:
Public ConnectionSring As String
Для чтения данных напишем метод SelectFrom с параметрами TableName и ws. TableName — это имя таблицы, откуда будем считывать данные и ws — лист Excel, куда будем записывать данные.
Public Sub SelectFrom(TableName As String, ws As Worksheet) Dim cn As ADODB.Connection Dim rst As ADODB.Recordset Dim SQLstring As String Dim i As Long Set cn = New ADODB.Connection Set rst = New ADODB.Recordset SQLstring = "SELECT * FROM " & TableName ws.Cells.Clear cn.ConnectionString = ConnectionSring cn.Open rst.Open SQLstring, cn For i = 1 To rst.Fields.Count ws.Cells(1, i) = rst.Fields(i - 1).Name Next i ws.Range("A2").CopyFromRecordset rst rst.Close cn.Close Set rst = Nothing Set cn = Nothing SQLstring = Empty i = Empty End Sub
Пример использования класса tSQL в процедуре
Sub mySQL() Dim ts As tSQL Set ts = New tSQL ts.ConnectionSring = '<Строка подключения> ts.SelectFrom "Название таблицы", ActiveSheet Set ts = Nothing End Sub
Задача третья. Загружаем данные из Excel во внешнюю базу данных.
Для записи данных напишем метод InsertInto с параметрами TableName. rHead и rData. TableName — это имя таблицы, куда будем добавлять данные; rHead — диапазон ячеек, с указанием полей; rData — диапазон ячеек с данными, которые будем добавлять.
Public Sub InsertInto(TableName As String, rHead As Range, rData As Range) Dim cn As ADODB.Connection Dim SQLstring As String Dim SQLstringH As String Dim SQLstringV As String Dim i As Long Dim j As Long Dim arrHead() Dim arrData() arrHead = rHead.Value arrData = rData.Value Set cn = New ADODB.Connection cn.ConnectionString = ConnectionSring cn.Open SQLstringH = "INSERT INTO " & TableName & "(" For j = LBound(arrHead, 2) To UBound(arrHead, 2) SQLstringH = SQLstringH & " " & arrHead(1, j) If j < UBound(arrHead, 2) Then SQLstringH = SQLstringH & "," Else SQLstringH = SQLstringH & ")" End If Next j SQLstringH = SQLstringH & " VALUES(" For i = LBound(arrData, 1) To UBound(arrData, 1) For j = LBound(arrData, 2) To UBound(arrData, 2) SQLstringV = SQLstringV & " " & arrData(i, j) If j < UBound(arrHead, 2) Then SQLstringV = SQLstringV & "," Else SQLstringV = SQLstringV & ") " End If Next j SQLstring = SQLstringH & SQLstringV SQLstringV = Empty cn.Execute SQLstring Next i cn.Close Set cn = Nothing SQLstring = Empty i = Empty j = Empty SQLstring = Empty SQLstringH = Empty SQLstringV = Empty Erase arrHead Erase arrData End Sub
Пример использования класса tSQL в процедуре
Sub mySQL() Dim ts As tSQL Set ts = New tSQL ts.ConnectionSring = '<Строка подключения> ts.InsertInto "Название таблицы", Range("B1:D1"), Range("B8:D300") Set ts = Nothing End Sub
Задача четвертая. Управляем внешней базой данных из Excel
Рекомендую использовать запросы в основном для чтения данных из внешней БД. Можно записывать данные в таблицы внешней БД.
Но крайне не желательно использовать Excel для управления внешней базой данных, лучше использовать стандартные средства разработки.
Полезные ссылки:
Data from Excel to SQL
http://www.excel-sql-server.com/excel-sql-server-import-export-using-vba.htm