Export Query in VBA loop to select data based on String Value - vba

I have a table called TEST, which I have code below that loops an export query based on unique values in the column Territory.
The code is supposed to export data to excel files based on the unique values in the column Territory. So each Territory value would have it's own file.
I am having trouble with setting up the sql query and how to use the string value to select the data:
Sub TEST()
Dim db As DAO.Database
Dim rs1 As DAO.Recordset
Dim v As String
Set db = CurrentDb()
Set rs1 = db.OpenRecordset("Select Distinct Territory From TEST")
Do While Not rs1.EOF
v = rs1.Fields(0).Value
**DoCmd.TransferSpreadsheet acExport, acSpreadsheetTypeExcel8, _
"WHAT SHOULD MY QUERY BE TO USE STRING v?", "C:\Users\me\Desktop\VBA_TEST\" v & ".xls", True**
rs1.MoveNext
Loop
rs1.Close
End Sub
Can someone guide me into how I may write the query and connect the string v so that it loops out reports?
Thank you!

I think you are required to use an existing query and not just your query as a string for the TransferSpreadsheet method. This means you will need a temporary query object to transfer your spreadsheet.
You can add a variable to query by joining it to the SQL string making sure that for text fields you include an ' on either side and leave it off for numeric fields.
Sub TEST()
Dim db As DAO.Database
Dim rs1 As DAO.Recordset
Dim v As String
Set db = CurrentDb()
Set rs1 = db.OpenRecordset("Select Distinct Territory From TEST")
Dim strQry As String
Dim qdfTemp As DAO.QueryDef
Dim strQDF As String
strQDF = "_TempQuery_"
Do While Not rs1.EOF
v = rs1.Fields(0).Value
strQry = "SELECT * FROM TEST WHERE Territory = '" & v & "'"
Set qdfTemp = CurrentDb.CreateQueryDef(strQDF, strQry)
qdfTemp.Close
Set qdfTemp = Nothing
DoCmd.TransferSpreadsheet acExport, acSpreadsheetTypeExcel8, _
strQDF, "C:\Users\me\Desktop\VBA_TEST\" & v & ".xls", True
CurrentDb.QueryDefs.Delete strQDF
rs1.MoveNext
Loop
rs1.Close
End Sub

Related

Access VBA loop to export Excel files

I have some code that I copied and modified from Export Query in VBA loop to select data based on String Value
The code works although the problem is that when it runs it creates a query in the database which is then deleted at the end. If the code breaks half way through, this query is still in the database. So when the code is run again it gives an error message saying it can't create the query as it already exists.
The query that is created within the database is named "Select * from SalesData"
The objective is that I have a query called "SalesData" which includes sales information for a number of countries. I want to export all the data for each country into an Excel file in a loop without creating any additional Access objects. Is it possible to just filter the existing query within the VBA without creating the temporary object?
Can anyone suggest any modifications to the below code to achieve this?
Sub TEST()
Dim db As DAO.Database
Set db = CurrentDb()
Dim rs1 As DAO.Recordset
Set rs1 = db.OpenRecordset("Select Distinct Country From SalesData")
Dim v As String
Dim strQry As String
Dim qdfTemp As DAO.QueryDef
Dim strQDF As String
strQDF = "select * from SalesData"
Do While Not rs1.EOF
v = rs1.Fields(0).Value
strQry = "SELECT * FROM SalesData WHERE Country = '" & v & "'"
Set qdfTemp = CurrentDb.CreateQueryDef(strQDF, strQry)
qdfTemp.Close
Set qdfTemp = Nothing
DoCmd.TransferSpreadsheet acExport, acSpreadsheetTypeExcel12Xml, _
strQDF, "C:\Users\me\Desktop\VBA_TEST\" & v & ".xlsx", True
CurrentDb.QueryDefs.Delete strQDF
rs1.MoveNext
Loop
rs1.Close
End Sub
As far as I'm aware, it would not be possible to use the TransferSpreadsheet method to extract a parameterised version of your SalesData query without either modifying the SQL of the SalesData query itself or using an additional query with selection criteria applied to the data returned by SalesData.
However, you needn't delete & recreate such query with every iteration of the loop - instead, simply modify the SQL property of the query, e.g.:
Sub test()
Dim qry As String: qry = "salesdata_temp"
Dim sql As String: sql = "select * from salesdata where country = '{0}'"
Dim out As String: out = "C:\Users\me\Desktop\VBA_TEST\"
Dim dbs As DAO.Database
Dim qdf As DAO.QueryDef
On Error Resume Next
DoCmd.DeleteObject acQuery, qry
On Error GoTo error_handler
Set dbs = CurrentDb
Set qdf = dbs.CreateQueryDef(qry, sql)
With dbs.OpenRecordset("select distinct country from salesdata")
If Not .EOF Then
.MoveFirst
Do Until .EOF
qdf.sql = Replace(sql, "{0}", !country)
DoCmd.TransferSpreadsheet acExport, , qry, out & !country & ".xlsx", True
.MoveNext
Loop
End If
.Close
End With
exit_sub:
On Error Resume Next
DoCmd.DeleteObject acQuery, qry
Exit Sub
error_handler:
MsgBox "Error " & Err.Number & ": " & Err.Description, vbExclamation + vbOKOnly, "Error"
Resume exit_sub
End Sub
Thanks to the input here, it seems that the only way to do it is to manipulate an existing query in the database or to create a query in the VBA script and then delete it at the end.
See below for an example of the first approach, the code uses a query already in the database called "blankquery".
Sub TEST()
Dim db As DAO.Database
Set db = CurrentDb()
Dim rs1 As DAO.Recordset
Set rs1 = db.OpenRecordset("Select Distinct Country From SalesData")
Dim qdfTemp As DAO.QueryDef
Dim v As String
Dim strQry As String
Dim strQDF As String
strQDF = "blankquery"
Do While Not rs1.EOF
v = rs1.Fields(0).Value
strQry = "SELECT * FROM SalesData WHERE Country = '" & v & "'"
db.QueryDefs(strQDF).sql = strQry
DoCmd.TransferSpreadsheet acExport, acSpreadsheetTypeExcel12Xml, _
strQDF, "C:\Users\me\Desktop\VBA_TEST\" & v & ".xlsx", True
rs1.MoveNext
Loop
rs1.Close
End Sub

Access VBA change Query criteria via VBA

I am trying to change the SQL statement of a query.
This is the following code:
Dim db As DAO.Database
Dim qdf As DAO.QueryDef
Dim sqlString As String
Set db = CurrentDb()
Set qdf = db.QueryDefs("Query1")
sqlString = "SELECT *all the Tables* FROM tab WHERE (((tab.columname)=*Variable*;"
qdf.SQL = sqlString
so my problem is the value of the Variable is not shown...
but it has to ge out of the string so I tried this:
sqlString = "SELECT *all the Tables* FROM tab WHERE (((tab.columname)= " & " *Variable*" & " ;"
I had to add "Variable" (quotation marks)
this then works half way.
it then uses the value of the variable it is set to but the quotes are missing...
The Goal of this Code is to change the Criteria that shows the data in the query.
The Variable value is as sample LA-85995561.
The way i want to change the value is via SQL statement.
I don't know further from here. thanks for any help!
(I am new to VBA)
Classic example to use parameterization, an industry best practice when using SQL at the application layer like VBA. And since you already use a querydef you can pass parameters easily withe PARAMETERS clause to define data type and placeholder.
SQL (save as a stored query)
PARAMETERS VariableParam Text(255);
SELECT * FROM tab WHERE tab.collumname = [VariableParam];
VBA
Dim db As DAO.Database
Dim rs As DAO.Recordset
Dim qdf As DAO.QueryDef
Dim sqlString As String
Set db = CurrentDb()
Set qdf = db.QueryDefs("mySavedQuery")
qdf!VariableParam = "LA-85995561"
Set rs = qdf.OpenRecordset()
' rs CAN BE USED IN FORMS/REPORTS RECORDSOURCES:
' Set Me.Form.Recordset = rst
' Set Me.Report.Recordset = rst
You could use PARAMETERS:
This passes a text string:
Sub Test()
Dim db As DAO.Database
Dim qdf As DAO.QueryDef
Dim rst As DAO.Recordset
Set db = CurrentDb
Set qdf = db.CreateQueryDef("", "PARAMETERS MyNamedSearchValue TEXT; " & _
"SELECT * FROM MyTable WHERE columname = MyNamedSearchValue")
With qdf
.Parameters("MyNamedSearchValue") = "A"
Set rst = .OpenRecordset
End With
With rst
MsgBox .Fields("MyDateField")
.Close
End With
qdf.Close
End Sub
This passes a number:
Sub Test()
Dim db As DAO.Database
Dim qdf As DAO.QueryDef
Dim rst As DAO.Recordset
Set db = CurrentDb
Set qdf = db.CreateQueryDef("", "PARAMETERS MyNamedSearchValue LONG; " & _
"SELECT * FROM MyTable WHERE columname = MyNamedSearchValue")
With qdf
.Parameters("MyNamedSearchValue") = 100
Set rst = .OpenRecordset
End With
With rst
MsgBox .Fields("MyDateField")
.Close
End With
qdf.Close
End Sub
You'll have to update the SQL to suit your needs. You could also pass it the name of a stored query rather than writing the SQL within the procedure.
If columname is text, then you can use something like this:
sqlString = "SELECT * FROM tab WHERE tab.columname='" & strVariable & "'"
For numeric data type:
sqlString = "SELECT * FROM tab WHERE tab.columname=" & str(lngVariable)
The Anser is that I had to use different marks:
WHERE (((tab.collumname)=""" & strVariable& """));"
it's about the """ & part it never made the " in the SQL thanks for all awnsers! brought me to my solution! <3

Access SQL Enter Parameter Value when trying to export to excel

I Am trying to run this SQL statement and then export the result to an excel spread sheet. I've looked through the the internet and found this, which seemed to work for other users.
It runs but asks me to "Enter Parameter Value" linking to "selecteduser" on line 4 of the code, the message box shows up at the point where the code starts here: DoCmd.TransferSpreadsheet. If I click ok the excel sheet is created but with nothing in except the titles from the selected columns from the tables in the database. If i put valid data into the text box and press ok, then the excel spreadsheet is created with the correct data showing.
I know that the selected data in the ComboBox is been stored, because if I do a Message box it shows the selected data from the combobox.
Any ideas anyone? It's obvious the data isn't been passed through somewhere, but I can't see where.
Private Sub Command12_Click()
Dim strSQL As String
Dim strQry As String
Dim selecteduser As String
Dim db As DAO.Database
Dim Qdf As QueryDef
selecteduser = Me.Combo6.Column(0)
strSQL = "SELECT tblPra.praNo, tblFolder.folder, tblFolder.fullTitle FROM tblPra INNER JOIN (tblFolder INNER JOIN tblRelationship ON tblFolder.folderID = tblRelationship.folderID) ON tblPra.praID = tblRelationship.praID WHERE (((tblPra.praNo)=selecteduser));"
strQry = "tempuser"
Set db = CurrentDb
Set Qdf = db.CreateQueryDef(strQry, strSQL)
On Error Resume Next
DoCmd.DeleteObject acQuery, "strQry"
DoCmd.TransferSpreadsheet acExport, acSpreadsheetTypeExcel8, _
strQry, "C:\Users\prc93\Desktop\test.xls", True
DoCmd.DeleteObject acQuery, strQry
End Sub
the selecteduser in your query needs to be outside of the quotes. as it is a string it needs to be in single quotes like 'selecteduser'. Now if you msgbox your query and you should see that the selecteduser equals your column (0). are you sure that selecteduser needs to be a string and not a number e.g. long?
Private Sub Command12_Click()
Dim strSQL As String
Dim strQry As String
Dim selecteduser As String
Dim db As DAO.Database
Dim Qdf As QueryDef
selecteduser = Me.Combo6.Column(0)
strSQL = "SELECT tblPra.praNo, tblFolder.folder, tblFolder.fullTitle FROM " &_
"tblPra INNER JOIN (tblFolder INNER JOIN tblRelationship ON " &_
"tblFolder.folderID = tblRelationship.folderID) ON " &_
"tblPra.praID = tblRelationship.praID " &_
"WHERE (((tblPra.praNo)='" & selecteduser & "'));"
strQry = "tempuser"
Set db = CurrentDb
Set Qdf = db.CreateQueryDef(strQry, strSQL)
On Error Resume Next
DoCmd.DeleteObject acQuery, "strQry"
DoCmd.TransferSpreadsheet acExport, acSpreadsheetTypeExcel8, _
strQry, "C:\Users\prc93\Desktop\test.xls", True
DoCmd.DeleteObject acQuery, strQry
End Sub

How to use variable initiated in SQL query?

I made a query to get Max value of a certain column
sSQLmax = "SELECT MAX([tablename]!rowname) as MaxNum FROM [tablename]"
I want to use MaxNum value. I tried it in a Msgbox and gave me a blank value. I tried all these:
MsgBox "MaxNum" & MaxNum
MsgBox "MaxNum" & sSQLMAX.MaxNum
MsgBox "MaxNum" & sSQLMAX!MaxNum
More of the code
Dim db As DAO.Database, rst As DAO.Recordset
Set db = CurrentDb
Set rst = db.OpenRecordset(sSQLmax)
but none works, Im sure its simple but it escapes me
With your code you are only setting a variable to a string. You are not actually doing anything with it. This is probably more of what you are looking for:
Dim db As DAO.Database, rst As DAO.Recordset, sSQLmax As String
sSQLmax = "SELECT MAX([tablename].rowname) as MaxNum FROM [tablename]"
Set db = CurrentDb
Set rst = db.OpenRecordset(sSQLmax, dbOpenDynaset)
If (rst.RecordCount <> 0) Then
rst.MoveFirst
MsgBox "MaxNumber: " & rst.Fields("rowname")
End If
Try the DMax function
Dim result as String
result = DMax("[COLUMN NAME]", "[TABLE NAME]")

DSN-Less Connection with multiple tables

Right now I have an MS SQL database with about 50 or so tables in it with which I'd like to link to MS Access using a DSN Less connection. Below is the basic code where I have a parameter of stRemoteTableName which is the table name of the SQL table to import. I could call this function each time for each table but that would take forever; is there anyway to loop through all tables in an SQL database and pass them to this function so that all tables are imported? I'm having a very hard time finding any code online for something like this, so help is much appreciated.
Private Sub ImportAllTables(stRemoteTableName)
On Error GoTo AttachDSNLessTable_Err
Dim td As TableDef
Dim stConnect As String
stServer = "C:\Location"
stDatabase = "DB"
stLocalTableName = stRemoteTableName
stUsername = ""
For Each td In CurrentDb.TableDefs
If td.Name = stLocalTableName Then
CurrentDb.TableDefs.Delete stLocalTableName
End If
Next
stConnect = "ODBC;DRIVER=SQL Server;SERVER=" & stServer & ";DATABASE=" & stDatabase & ";Trusted_Connection=Yes"
Set td = CurrentDb.CreateTableDef(stLocalTableName, stRemoteTableName, stConnect)
CurrentDb.TableDefs.Append td
Exit Sub
AttachDSNLessTable_Err:
AttachDSNLessTable = False
MsgBox "AttachDSNLessTable encountered an unexpected error: " & Err.Description
End Sub
You can use a pass-through query to list the table names from your SQL Server database. Open a recordset based on that query. Then loop through the recordset rows and link each table.
Dim db As DAO.Database
Dim qdf As DAO.QueryDef
Dim rs As DAO.Recordset
Dim strConnect As String
Dim strSelect As String
strSelect = "SELECT t.name FROM sys.tables t;"
'strConnect = <you already have this as stConnect>
Set db = CurrentDb
Set qdf = db.CreateQueryDef("", strSelect)
qdf.Connect = strConnect
Set rs = qdf.OpenRecordset
With rs
Do While Not .EOF
' you want to link; I will just list
' the table names
Debug.Print !name
.MoveNext
Loop
.Close
End With
Set rs = Nothing
Set qdf = Nothing
Set db = Nothing