I am attempting to iterate a query as a DAO.Recordset, my issue is that my recordset never prints anything. If I look at my table, and my query both of them have the data that I am after, but the VBA is not producing the data that I expect. Below is synatx - why will this not write my data?
Option Compare Database
Sub Test()
Dim query1 As String, rs1 As DAO.Recordset
Dim qryDef As QueryDef, strSQL As String
query1 = "qryPullData"
strSQL = "SELECT fl1 As [Field With Spaces One],fl2 As [Field With Spaces Two], " & _
"fl3 As [Field WIth Spaces Three], fl4 As [Field With Spaces Four] " & _
"FROM smallsubset ORDER BY fl1 ASC;"
Set qryDef = CurrentDb.CreateQueryDef(query1, strSQL)
Set rs1 = CurrentDb.OpenRecordset(query1)
If Not rs1.EOF Then
While Not rs1.EOF
Debug.Print rs1("Field With Spaces One")
Debug.Print rs1("Field With Spaces Two")
Debug.Print rs1("Field With Spaces Three")
Debug.Print rs1("Field With Spaces Four")
Debug.Print rs1("[Field With Spaces One]")
Debug.Print rs1("[Field With Spaces Two]")
Debug.Print rs1("[Field With Spaces Three]")
Debug.Print rs1("[Field With Spaces Four]")
Wend
rs1.Close
End If
End Sub
Here is the code using several of the suggestions from the above comments:
Sub Test()
Dim query1 As String, rs1 As DAO.Recordset
Dim qryDef As QueryDef, strSQL As String
If CheckQuery("qryPullData") = "Yes" Then
DoCmd.DeleteObject acQuery, "qryPullData"
End If
query1 = "qryPullData"
strSQL = "SELECT fl1 As [Field With Spaces One],fl2 As [Field With Spaces Two], " & _
"fl3 As [Field WIth Spaces Three], fl4 As [Field With Spaces Four] " & _
"FROM smallsubset ORDER BY fl1 ASC;"
Set qryDef = CurrentDb.CreateQueryDef(query1, strSQL)
Set rs1 = CurrentDb.OpenRecordset(query1)
rs1.MoveFirst
While Not rs1.EOF
Debug.Print rs1("Field With Spaces One")
Debug.Print rs1("Field With Spaces Two")
Debug.Print rs1("Field With Spaces Three")
Debug.Print rs1("Field With Spaces Four")
rs1.MoveNext
Wend
rs1.Close
End Sub
Here is the CheckQuery sub stolen from here: http://www.access-programmers.co.uk/forums/showthread.php?t=206298
Function CheckQuery(queryName As String)
Dim qryLoop As QueryDef
Dim dbs As Database
Dim exists As String
exists = "No"
For Each qryLoop In CurrentDb.QueryDefs
If qryLoop.Name = queryName Then
exists = "Yes"
Exit For
End If
Next
CheckQuery = exists
End Function
Make sure that you are looking in the immediate window for the Debug.Print results.
Slightly tidier version of code from #tlemaster. This will format your output a little better rather than just running all the fields and records together one after the other, removes unnecessary variables from the CheckQuery function and properly releases all the object variables.
Public Sub Test()
Dim rs1 As DAO.Recordset
Dim qryDef As QueryDef
Dim query1 As String
Dim strSQL As String
Dim lngRecordNum As Long '(how many records are you expecting?)
query1 = "qryPullData"
If QueryExists(query1) Then
DoCmd.DeleteObject acQuery, query1
End If
strSQL = "SELECT fl1 As [Field With Spaces One], fl2 As [Field With Spaces Two], " & _
"fl3 As [Field WIth Spaces Three], fl4 As [Field With Spaces Four] " & _
"FROM smallsubset ORDER BY fl1 ASC;"
Set qryDef = CurrentDb.CreateQueryDef(query1, strSQL)
Set rs1 = CurrentDb.OpenRecordset(query1)
lngRecordNum = 1
Do While Not rs1.EOF
Debug.Print "Record " & lngRecordNum & ":"
Debug.Print " " & rs1("Field With Spaces One")
Debug.Print " " & rs1("Field With Spaces Two")
Debug.Print " " & rs1("Field With Spaces Three")
Debug.Print " " & rs1("Field With Spaces Four")
rs1.MoveNext
Loop
Set rs1 = Nothing
Set qryDef = Nothing
End Sub
Public Function QueryExists(queryName As String) As Boolean
Dim qryLoop As QueryDef
For Each qryLoop In CurrentDb.QueryDefs
If qryLoop.Name = queryName Then
QueryExists = True
Exit For
End If
Next
Set qryLoop = Nothing
End Function
Related
I have a MultiSelect List Box that I'm trying to use as criteria in a query. I'm fine until the line of code "qdf.SQL = strSQL" at which point I receive the error code 3131. If I place a message box just after the "strSQL =" command, it appears to populate with the correct data.
I am pulling from a list of Categories on a form (Forms("frmMain").listCat1).
What am I doing wrong? Thank you in advance.
Private Sub CAT1_Criteria()
Dim varItem As Variant
Dim strCAT1 As String
Dim ctl As Control
Dim strSQL As String
Dim db As Database
Dim qdf As QueryDef
Set ctl = Forms("frmMain").listCat1
For Each varItem In ctl.ItemsSelected
strCAT1 = strCAT1 & ",'" & ctl.ItemData(varItem) _
& "'"
Next varItem
If Len(strCAT1) = 0 Then
strCAT1 = "Like '*'"
Else
strCAT1 = Right(strCAT1, Len(strCAT1) - 1)
strCAT1 = "IN(" & strCAT1 & ")"
End If
strSQL = "SELECT dbo_CATEGORY1.* FROM dbo_CATEGORY1" & _
"WHERE dbo_CATEGORY1.[LEVEL1] " & strCAT1 & ";"
Set db = CurrentDb
Set qdf = db.QueryDefs("qryCAT1_Sel")
qdf.SQL = strSQL
'Set qdf = Nothing
'Set db = Nothing
DoCmd.OpenQuery "qryCAT1_Sel"
End Sub
I am trying to use a ComboBox to append a query through a form I built. The Combobox should be optional, but I can't seem to get around the Invalid use of null error. Here is the code I have currently
Dim MyDB As DAO.Database
Dim qdef As DAO.QueryDef
Dim i As Integer
Dim strSQL As String
Dim strWhere As String
Dim strIN As String
Dim Box1 As String
Dim strBox1 As String
Dim flgSelectAll As Boolean
Dim varItem As Variant
Set MyDB = CurrentDb()
'General SQL Code
strSQL = "SELECT * FROM Test1"
'Build the IN string by looping through the listbox
For i = 0 To List6.ListCount - 1
If List6.Selected(i) Then
If List6.Column(0, i) = "_All" Then
flgSelectAll = True
End If
strIN = strIN & "'" & List6.Column(0, i) & "',"
End If
Next i
'Create the WHERE string, and strip off the last comma of the IN string
strWhere = " WHERE [Test1.Brand_Name] in " & _
"(" & Left(strIN, Len(strIN) - 1) & ")"
'Create the AND string
Box1 = Me.Combo8.Value
If IsNull(Me.Combo8.Value) Then
strBox1 = Nz(Me.Combo8.Column(0), "")
Else: strBox1 = " AND [Test1.Population] = '" & Box1 & "'"
End If
If Not flgSelectAll Then
strSQL = strSQL & strWhere & strBox1
End If
MyDB.QueryDefs.Delete "cpwg"
Set qdef = MyDB.CreateQueryDef("cpwg", strSQL)
'Open the query, built using the IN clause to set the criteria
DoCmd.OpenQuery "cpwg", acViewNormal
I have also tried
If IsNull(Box1) Or Box1 = "Null" Then
strBox1 = Nz(Me.Combo8.Column(0), "")
Else: strBox1 = " AND [Test1.Population] = '" & Box1 & "'"
End If
Try:
if isnull(me.combo8) then
Also, I Dont know how your combobox is populated, But Null is different than no data. Perhaps try
if me.combo8.value = "" then
IF IsNull(Trim(me.combo8)) Then
'Do Stuff
End if
I want to find the distinct list of values from a collection of certain fields across a number of tables in MS Access. However, my VBA code only returns the first value from every field (and not the full collection of distinct values in each field). Please see below:
Sub GetDistinctValues()
Dim tbl As DAO.TableDef
Dim fld As DAO.Field
Dim rs As DAO.Recordset
Dim rs1 As DAO.Recordset
Set rs = CurrentDb.OpenRecordset("Fields_To_Examine")
Do While Not rs.EOF
For Each tbl In CurrentDb.TableDefs
If tbl.Name = rs("Table_Name") Then
Debug.Print tbl.Name
For Each fld In tbl.Fields
If fld.Name = rs("Field_Name") Then
Debug.Print fld.Name
Set rs1 = CurrentDb.OpenRecordset("SELECT DISTINCT " & tbl.Name & ".Source_System, " & tbl.Name & "." & fld.Name & " FROM " & tbl.Name)
Debug.Print rs1(0), rs1(1)
rs.MoveNext
End If
Next
End If
Next
Loop
rs.Close
rs1.Close
Set rs = Nothing
Set rs1 = Nothing
End Sub
Any suggestions on where I am going wrong?
MoveNext is inside the field loop, so:
For Each tbl In CurrentDb.TableDefs
If tbl.Name = rs("Table_Name") Then
Debug.Print tbl.Name
For Each fld In tbl.Fields
If fld.Name = rs("Field_Name") Then
Debug.Print fld.Name
Set rs1 = CurrentDb.OpenRecordset("SELECT DISTINCT " & tbl.Name & ".Source_System, " & tbl.Name & "." & fld.Name & " FROM " & tbl.Name)
Debug.Print rs1(0), rs1(1)
End If
Next
End If
Next
rs.MoveNext
My form takes the data the user entered, constructs a SQL statement and returns the results. I would like to have a message box pop up when there are no matches found.
My current code/idea:
If qdf.sql = 0 Then
MsgBox "No clients matching your information." & _
vbCrLf & "have been found. Please try again." & _
, vbCritical, "No Matches"
Else
DoCmd.OpenForm "frmSearchResults"
Me.Visible = False
End If
I'm having trouble figuring out the correct syntax for if qdf.sql = 0 .
UPDATE: Full query
Private Sub cmdSearch_Click()
'On Error GoTo cmdSearch_Click_err
Dim db As Database
Dim strSQL As String
Dim rs As DAO.Recordset
Dim qdf As QueryDef
Dim strClientID As String
Dim strLastName As String
Dim strFirstName As String
Dim strDOB As String
Set db = CurrentDb
Set rs = db.OpenRecordset(qdf.sql)
' call QueryCheck module to determine if query exists
If Not QueryExists("qrySearch") Then
Set qdf = db.CreateQueryDef("qrySearch")
Else
Set qdf = db.QueryDefs("qrySearch")
End If
' handle nulls in the user's entries
If IsNull(Me.txtClientID.Value) Then
strClientID = " Like '*' "
Else
strClientID = "='" & Me.txtClientID.Value & "' "
End If
If IsNull(Me.txtLastName.Value) Then
strLastName = " Like '*' "
Else
strLastName = " Like '" & Me.txtLastName.Value & "*' "
End If
If IsNull(Me.txtFirstName.Value) Then
strFirstName = " Like '*' "
Else
strFirstName = " Like '*" & Me.txtFirstName.Value & "*' "
End If
If IsNull(Me.txtDOB.Value) Then
strDOB = " Like '*' "
Else
strDOB = "='" & Me.txtDOB.Value & "' "
End If
strSQL = "SELECT Clients.* " & _
"FROM Clients " & _
"WHERE Clients.clientid" & strClientID & _
"AND Clients.namelast" & strLastName & _
"AND Clients.namefirst" & strFirstName & _
"AND Clients.birthdate" & strDOB & _
"ORDER BY Clients.namelast,Clients.namefirst;"
Debug.Print strSQL
' check to see if the results form is open and close if it is
DoCmd.Echo False
If Application.SysCmd(acSysCmdGetObjectState, acForm, "frmSearchResults") = acObjStateOpen Then
DoCmd.Close acForm, "frmSearchResults"
End If
' run SQL statment
qdf.sql = strSQL
' check for no matches found
If rs.RecordCount = 0 Then
MsgBox "No clients matching your information were found." & _
vbCrLf & "Please search again.", vbInformation, "No Matches"
Else
DoCmd.OpenForm "frmSearchResults"
Me.Visible = False
End If
'cmdSearch_Click_exit:
' DoCmd.Echo True
' Set qdf = Nothing
' Set db = Nothing
'Exit Sub
'cmdSearch_Click_err:
' MsgBox "An unexpected error has occurred." & _
' vbCrLf & "Please note of the following details and contact the EIIS support desk:" & _
' vbCrLf & "Error Number: " & Err.Number & _
' vbCrLf & "Description: " & Err.Description _
' , vbCritical, "Error"
' Resume cmdSearch_Click_exit
End Sub
The reason that If qdf.sql = 0 then won't perform a proper check is that qdf contains the information about your query such as the SQL text that you are checking in that statement but not the results.
To get the results of the query you need to assign it to a Recordset after you have build your query. So first build your query and then assign it to the record set.
Dim db as DAO.Database
Set db = CurrentDb
Dim qdf as DAO.Querydef
Set qdf = db.CreateQueryDef("qrySearch")
Dim rs as DAO.Recordset
Set rs = CurrentDb.OpenRecordset(qdf.sql)
You can then check what your record set has returned.
If rs.RecordCount = 0 then
So where you have your line ' run SQL statment you would want to place the Set rs line.
If you have any ADO experience you can use something like
dim strSQL as String
dim conn as Connection
dim cmd as Command
dim rs as Recordset
(set up connection/command here)
cmd.commandtext = (your select query)
set rs = Command.execute
if rs.eof then
(or if rs.recordcount = 0 however returning a recordcount requires the correct cursortype - usually adOpenStatic - to be used)
'msgbox no match
else
'do stuff
If any of this is alien, then post your actual query and I'll try and give you the code in full. Good luck!
Just getting to grips some VBA (this stuff's new to me so bear with us!)
From query ContactDetails_SurveySoftOutcomes, I'm trying to first find a list of all the unique values in the DeptName field in that query, hence the rsGroup Dim storing a Grouped query on the DeptName field.
I'm then going to use this grouped list as way of cycling through the same query again, but passing through each unique entry as a filter on the whole recordset and export each filtered recordset to its own Excel spreadsheet... see the Do While Not loop.
My code's tripping up on the DoCmd.TransferSpreadsheet ... rsExport part. I'm a bit new to this, but I guess my Dim name rsExport for the recordset isn't accepted in this method..?
Is there an easy fix to the code I've already started or should I be using a completely different approach to achieve all this?
Code:
Public Sub ExportSoftOutcomes()
Dim rsGroup As DAO.Recordset
Dim Dept As String
Dim myPath As String
myPath = "C:\MyFolder\"
Set rsGroup = CurrentDb.OpenRecordset("SELECT ContactDetails_SurveySoftOutcomes.DeptName " _
& "FROM ContactDetails_SurveySoftOutcomes GROUP BY ContactDetails_SurveySoftOutcomes.DeptName", dbOpenDynaset)
Do While Not rsGroup.EOF
Dept = rsGroup!DeptName
Dim rsExport As DAO.Recordset
Set rsExport = CurrentDb.OpenRecordset("SELECT * FROM ContactDetails_SurveySoftOutcomes " _
& "WHERE (((ContactDetails_SurveySoftOutcomes.DeptName)='" & Dept & "'))", dbOpenDynaset)
DoCmd.TransferSpreadsheet acExport, acSpreadsheetTypeExcel9, rsExport, myPath & Dept & "\" & Dept & " - Soft Outcomes Survey.xls", True
rsGroup.MoveNext
Loop
End Sub
Fixed Code:
Public Sub ExportSoftOutcomes()
Dim rsGroup As DAO.Recordset
Dim Dept As String
Dim myPath As String
myPath = "C:\MyFolder\"
Set rsGroup = CurrentDb.OpenRecordset("SELECT ContactDetails_SurveySoftOutcomes.DeptName " _
& "FROM ContactDetails_SurveySoftOutcomes GROUP BY ContactDetails_SurveySoftOutcomes.DeptName", dbOpenDynaset)
Do While Not rsGroup.EOF
Dept = rsGroup!DeptName
Dim rsExportSQL As String
rsExportSQL = "SELECT * FROM ContactDetails_SurveySoftOutcomes " _
& "WHERE (((ContactDetails_SurveySoftOutcomes.DeptName)='" & Dept & "'))"
Dim rsExport As DAO.QueryDef
Set rsExport = CurrentDb.CreateQueryDef("myExportQueryDef", rsExportSQL)
DoCmd.TransferSpreadsheet acExport, acSpreadsheetTypeExcel9, "myExportQueryDef", myPath & Dept & "\" & Dept & " - Soft Outcomes Survey.xls", True
CurrentDb.QueryDefs.Delete rsExport.Name
rsGroup.MoveNext
Loop
End Sub
You're right that your rsGroup parameter is wrong, Access expects a table name or select query.
Try this code:
strExport = "SELECT * FROM ContactDetails_SurveySoftOutcomes " _
& "WHERE (((ContactDetails_SurveySoftOutcomes.DeptName)='" & Dept & "'))"
Set qdfNew = CurrentDb.CreateQueryDef("myExportQueryDef", strExport)
DoCmd.TransferSpreadsheet acExport, acSpreadsheetTypeExcel9, "myExportQueryDef", myPath & Dept & "\" & Dept & " - Soft Outcomes Survey.xls", True
CurrentDb.QueryDefs.Delete qdfNew.Name 'cleanup
Hope that works
try this hope this will help you
Function Export2XLS(sQuery As String)
Dim oExcel As Object
Dim oExcelWrkBk As Object
Dim oExcelWrSht As Object
Dim bExcelOpened As Boolean
Dim db As DAO.Database
Dim rs As DAO.Recordset
Dim iCols As Integer
Const xlCenter = -4108
'Start Excel
On Error Resume Next
Set oExcel = GetObject(, "Excel.Application") 'Bind to existing instance of Excel
If Err.Number <> 0 Then 'Could not get instance of Excel, so create a new one
Err.Clear
On Error GoTo Error_Handler
Set oExcel = CreateObject("excel.application")
bExcelOpened = False
Else 'Excel was already running
bExcelOpened = True
End If
On Error GoTo Error_Handler
oExcel.ScreenUpdating = False
oExcel.Visible = False 'Keep Excel hidden until we are done with our manipulation
Set oExcelWrkBk = oExcel.Workbooks.Add() 'Start a new workbook
Set oExcelWrSht = oExcelWrkBk.Sheets(1)
'Open our SQL Statement, Table, Query
Set db = CurrentDb
Set rs = db.OpenRecordset(sQuery, dbOpenSnapshot)
With rs
If .RecordCount <> 0 Then
'Build our Header
For iCols = 0 To rs.Fields.Count - 1
oExcelWrSht.Cells(1, iCols + 1).Value = rs.Fields(iCols).Name
Next
With oExcelWrSht.Range(oExcelWrSht.Cells(1, 1), _
oExcelWrSht.Cells(1, rs.Fields.Count))
.Font.Bold = True
.Font.ColorIndex = 2
.Interior.ColorIndex = 1
.HorizontalAlignment = xlCenter
End With
oExcelWrSht.Range(oExcelWrSht.Cells(1, 1), _
oExcelWrSht.Cells(1, rs.Fields.Count)).Columns.AutoFit 'Resize our Columns based on the headings
'Copy the data from our query into Excel
oExcelWrSht.Range("A2").CopyFromRecordset rs
oExcelWrSht.Range("A1").Select 'Return to the top of the page
Else
MsgBox "There are no records returned by the specified queries/SQL statement.", vbCritical + vbOKOnly, "No data to generate an Excel spreadsheet with"
GoTo Error_Handler_Exit
End If
End With
' oExcelWrkBk.Close True, sFileName 'Save and close the generated workbook
' 'Close excel if is wasn't originally running
' If bExcelOpened = False Then
' oExcel.Quit
' End If
Error_Handler_Exit:
On Error Resume Next
oExcel.Visible = True 'Make excel visible to the user
rs.Close
Set rs = Nothing
Set db = Nothing
Set oExcelWrSht = Nothing
Set oExcelWrkBk = Nothing
oExcel.ScreenUpdating = True
Set oExcel = Nothing
Exit Function
Error_Handler:
MsgBox "The following error has occured" & vbCrLf & vbCrLf & _
"Error Number: " & Err.Number & vbCrLf & _
"Error Source: Export2XLS" & vbCrLf & _
"Error Description: " & Err.Description _
, vbOKOnly + vbCritical, "An Error has Occured!"
Resume Error_Handler_Exit
End Function
DoCmd.TransferSpreadsheet expects its third parameter to be a String (variable or literal) specifying the name of a table or query. So, instead of opening a DAO.Recordset you could create a DAO.QueryDef named something like "forExportToExcel" with the same SQL code, then use that name in the TransferSpreadsheet call.