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
Related
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
I created an install for my database. However it loses the password for the linked tables to the back end.
I need to relink all the tables on load.
I found the below code to add specified table but I need to link all the tables in the back end DB and I don't want to repeat this code for every table.
Dim db As DAO.Database
Dim tdf As DAO.TableDef
Dim strConnect As String
Dim strDbFile As String
Dim strLinkName As String
Dim strPassword As String
Dim strSourceTableName As String
strDbFile = "c:documents\mydb"
strPassword = "mypw"
strSourceTableName = "tblcaseid"
strLinkName = "link_to_caseid"
strConnect = "MS Access;PWD=" & strPassword & _
";DATABASE=" & strDbFile
Debug.Print strConnect
Set db = CurrentDb
Set tdf = db.CreateTableDef
tdf.Connect = strConnect
tdf.SourceTableName = strSourceTableName
tdf.Name = strLinkName
db.TableDefs.Append tdf
End Sub
Figured out that i dont need to remove the table links and add them again just need to loop through the tables refreshing the link including the password in the strconnect
Sub relink()
Dim strDbFile As String
Dim strPassword As String
Dim strConnect As String
strDbFile = "file location"
strPassword = "database password"
strConnect = "MS Access;PWD=" & strPassword & ";DATABASE=" & strDbFile
Dim tdf As DAO.TableDef
Dim db As DAO.Database
Set db = CurrentDb
For Each tdf In db.TableDefs
' ignore system and temp tables
If Not (tdf.Name Like "MSys*" Or tdf.Name Like "~*" Or tdf.Name Like "exl*") Then
tdf.Connect = strConnect
tdf.RefreshLink
End If
Next
End Sub
this worked
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
I am trying to erase some data (values = 0) from a field in access, but without knowing the name, I only know the position of the field in the database (13Âșcolumn) . I thought it would be very simple, but after many tries I still can't manage to find a solution and I am starting to doubt if it's even possible.
So this is the code that I am using:
Sub Erasevalues0()
Dim strQValue As String
Dim i As Integer
Dim db As DAO.Database
Dim sql13 As String
Set db = CurrentDb
sql13 = db.TableDefs("TableName").Fields(13).Name
strQValue = "DELETE FROM TableName WHERE sql13=0;"
db.Execute strQValue
End Sub
I even tried something like:
strQValue = "DELETE FROM TableName WHERE Fields(13)=0;"
But nothing seems to work. Any suggestions?
I think you need to loop through the recordset. The following should work
Sub RemoveZeros()
Dim db As Database
Dim rs As Recordset
Set db = CurrentDb
Set rs = db.OpenRecordset("Table1", dbOpenDynaset)
rs.MoveFirst
With rs
Do Until .EOF
If .Fields(13) = 0 Then .Delete 'Delete row if column 13 = 0
.MoveNext 'Move to next record
Loop
End With
rs.Close
Set rs = Nothing
Set db = Nothing
End Sub
Not sure if there is a direct way to use the index of a field. A workaround:
query = "SELECT * FROM TableName"
columnName = CurrentDb.OpenRecordset(query).Fields(13).Name
strQValue = "UPDATE TableName " & _
"SET " & columnName & "=''"
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