I am beginner to the VBA. Please help.
I have a database named as "Master" saved on shared network folder and it has table named as "logs" .
I have few users who have different data base with the table “logs” and this table structure is like the same as in the table “log” in the database “Master”.
Those users makes entries to their database table “logs” everyday. I want that in the “Master” database, I will create a table named as “UserDb” which will keep address path of all the users database files and I will create a form with the button “Sync”.
I need that once I click on the “Sync” button then it should read path of the user data base from the table “UserDb” and insert all the today’s date entries from all the user’s data base table “logs” to the “Master” database table “logs”.
In the table “Logs” columns names are UserName, Application, TeamName, StartTime, StopTime, LoginDate.
Here's something that you can start with:
Function ConToDataBase(DBPath As String) As Variant
Dim Con As ADODB.Connection
Dim Rs As ADODB.Recordset
Dim SQL As String
SQL = "SELECT * FROM Logs"
Set Con = New ADODB.Connection
With Con
.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data source=" & DBPath & ";"
.Open
End With
Set Rs = New ADODB.Recordset
Rs.Open SQL, Con
Dim Var As Variant
Var = Rs.GetRows
ConToDataBase = Var
Set Rs = Nothing
Con.Close
End Function
Make sure to add the reference Microsoft ActiveX Objects 2.8 from Tools > References so that you can ADODB objects.
The function will return a variant containing the logs table. You can take it from there.
Related
We have a SQL Server Backend with MS ACCESS 2016 Front. We have a general purpose ADO connection object that we use to send SQL commands off to our DB. When we have SQL that returns something, we were using code to build a passthru query object, which was a handly way to get SQL output into the frontend.
We are now in a situation where we have some really complex SQL that returns an output, but consists of several statements, including the construction of several temp tables on the server. We can't use the "build a passthru query object" method because passthrus can't handle multiple SQL Statements, and we can't send the SQL statements one at a time because the temp tables get destroyed after the query finishes.
At present, we are now using our ADO objects to get the output into an ADO recordset, then saving the recordset down as an .XML and then finally importing the .XML file into the DB. But this is a lot of I/O and it goes slow for large outputs.
Is there any better (faster) way to get the output of our complex SQL into a local table in the MS Access Frontend?
Heres a snippit of our vba class object:
Private Const DB_CONNECTION_STRING As String = "<our connection string>"
Private conn As ADODB.Connection
Private cmd As ADODB.Command
Private recAff As Long
______________________________________________________________
Private Sub Class_Initialize()
Set conn = New ADODB.Connection
Set cmd = New ADODB.Command
conn.Open DB_CONNECTION_STRING
With cmd
.ActiveConnection = conn
.CommandTimeout = 0
End With
End Sub
...
<more properties/methods>
...
Public Sub LocalizeOutput(fetchSQL As String, InputTableName As String)
'If the InputTableName does not exist, a new table will be created. All fields will be datatyped as Text
'Otherwise, if the InputTableName does exist, data will be appended. Caller is responsible for handling errors
Dim rs As ADODB.Recordset
Dim XMLFilePath As String
Dim domIn As Object
Dim domOut As Object
Dim domStylesheet As Object
XMLFilePath = Environ("TEMP") & "\TableImport.xml"
fetchSQL = "SET NOCOUNT ON; " & vbNewLine & fetchSQL
Set domIn = CreateObject("Microsoft.XMLDOM")
domIn.async = False
'Execute the query
With cmd
.CommandType = adCmdText
.CommandText = fetchSQL
Set rs = .Execute(recAff)
End With
Dim tbl As TableDef
'Save off the output as xml file
If FileExists(XMLFilePath) Then
Call FileDelete(XMLFilePath)
End If
rs.Save XMLFilePath, adPersistXML
'Write the XML Transformation File
Call WriteXSLTransform(InputTableName)
'Convert the ado_xml file into an Access readable xml file
domIn.Load XMLFilePath
Set domStylesheet = CreateObject("Microsoft.XMLDOM")
domStylesheet.Load Environ("TEMP") & "\ADOXMLToAccess.xsl"
Set domOut = CreateObject("Microsoft.XMLDOM")
domIn.transformNodeToObject domStylesheet, domOut
'Set domIn = Nothing
Call FileDelete(XMLFilePath)
'Save the output
domOut.Save XMLFilePath
'Import the saved document into Access
Application.ImportXML XMLFilePath, acAppendData
'clean up
Call FileDelete(XMLFilePath)
Call FileDelete(Environ("TEMP") & "\ADOXMLToAccess.xsl")
Set rs = Nothing
Set domIn = Nothing
Set domOut = Nothing
Set domStylesheet = Nothing
End Sub
Right now I'm downloading data from a database using ADODB to an Excel table. However I want users to be able to refresh the table so it's updated from my database.
I've been experimenting with creating a new table from an external source and arrived to this code:
Public Sub CreateLiveTable(sql As String, Location As Range, TableName As String)
With Location.Parent.ListObjects.Add(SourceType:=xlSrcExternal, Source:="OLEDB; " & DB_CONNECTION, Destination:=Location).QueryTable
.CommandType = xlCmdSql
.CommandText = sql
.BackgroundQuery = True
.ListObject.DisplayName = "asdfas"
.SourceConnectionFile = "C:\Users\lisandro.h.vaccaro\Documents\My Data Sources\172.19.179.43 Forecasting CostRates.odc"
.Refresh BackgroundQuery:=True
End With
End Sub
However I haven't been able to connect my existing table to SQL Server. I can't just delete and create it again as there are a lot of formulas and named ranges pointing to it that would be broken if I deleted it.
How can I connect my existing table to my database?
I have a project where I need to query a Teradata database and then copy the records returned to a SQL Server database. I can hit the Teradata db no problem and I can get the results into a DataTable. The SQL server db is already setup and has the same columns as the Teradata results (except for the auto id column). I am having trouble figuring out how to take the records in the DataTable and insert them into the SQL server db.
Here is what i have with some pseudo code where I didn't think the details were relevant:
Using cn As New TdConnection("User Id=XYZ12345;Password=XYZ12345;Data Source=teradataserver.company.com;Persist Security Info=False")
cn.Open()
Dim cmd As TdCommand = cn.CreateCommand()
'build the SELECT part of the command we will issue
cmd.CommandText = GetTeradataSqlString()
'setup the DataAdapter
Dim da As New TdDataAdapter(cmd)
' Provider specific types will be used in the data table
da.ReturnProviderSpecificTypes = False 'True=Use Teradata types, False=Use .NET types
' Adapter will determine how many statements will be batched
da.UpdateBatchSize = 0
Dim cb As New TdCommandBuilder(da)
'create a DataTable to hold our returned data
Dim dtCheck As New DataTable("TableCheck")
' Filling the data table with data retrieved from the select statement
da.Fill(dtCheck)
'create a DataSet to hold all of our tables
Dim dsMain As New DataSet("MainDataset")
'now we add the DataTable to our DataSet
dsMain.Tables.Add(dtCheck)
'at this point a cycle through the DataTable to the debug window shows we have the data we need from the Teradata db.
'now we will pump it into our SQL server database
Dim connSqlSvr As New System.Data.SqlClient.SqlConnection
connSqlSvr.ConnectionString = "Data Source=DestSqlServer;Initial Catalog=DestDb;Connect Timeout=15"
connSqlSvr.Open()
'now we create a SQL command to take the data in the Teradata DataTable and insert it into the SQL server table
Dim sqlCmd As New SqlCommand
With sqlCmd
.CommandType = CommandType.Text
Dim sbSqlCmd As New StringBuilder
sbSqlCmd.AppendLine("INSERT INTO [DestDb].[dbo].[Events] ([CityCode],[CarNum],[VIN],[Fleet],[EventItm])")
sbSqlCmd.AppendLine("SELECT City,CarNo,VIN,Fleet,EventDesc FROM #MyTable;")
.CommandText = sbSqlCmd.ToString
Dim sqlParam As New SqlParameter
sqlParam.ParameterName = "#MyTable"
sqlParam.SqlDbType = SqlDbType.Structured
sqlParam.Value = dtCheck
sqlParam.TypeName = "TableCheck"
.Parameters.Add(sqlParam)
.Connection = connSqlSvr
Dim rowsAffectedLoad As Integer = .ExecuteNonQuery()
debug.print(rowsAffectedLoad & " rows were loaded into the SQL server table.")
End With
'close and dispose the SQL server database connection
connSqlSvr.Close()
connSqlSvr.Dispose()
End Using
Running the code I get an exception:
"Column, parameter, or variable #MyTable. : Cannot find data type TableCheck."
I've looked for a method to insert a DataTable into a database and noticed many samples were using the INSERT INTO. I just dont think I am using the SqlParameter properly.
Your example appears to be using a Table Valued Parameter of type TableCheck but you have not defined that type within SQL Server. See http://msdn.microsoft.com/en-us/library/bb510489.aspx
CREATE TYPE LocationTableType AS TABLE
( LocationName VARCHAR(50)
, CostRate INT );
Although I can't guarantee that you can pass a TVP directly into a raw SQL statement.
I would actually suggest you use a different approach using SqlBulkCopy, http://msdn.microsoft.com/en-us/library/ex21zs8x(v=vs.110).aspx .
Im trying to open a SQL stored procedure, which contains a Select top 5* form table, and load the data into an Access table called Table3.
How do I set the Command Object ActiveConnection property to use the current Access DB?
when I provide it with an actual connection string, it says that the user has locked it.
At the moment, it runs and prints prints out the results but it does not insert the values. It does not give me an error either.
'Use this code to run the SP and extract all the records
Public Sub ExecuteSPAsMethod2()
Dim rsData As ADODB.Recordset
Dim sConnectSQL As String 'to create connection to SQL Server
Dim sConnectAccess As String 'to create connection with Access DB (may not be neccessary)
Dim objCommand As ADODB.Command 'for INSERT results of SP into Access table
'Creating the connection string to SQL server
sConnectSQL = "Provider=SQLOLEDB;Data Source=MYSERVER; " & _
"Initial Catalog=SQLDatabase;Integrated Security=SSPI"
'Creating the Connection object and Recordset object
Set objConn = New ADODB.Connection
Set rsData = New ADODB.Recordset
'Opening the connection
objConn.Open sConnectSQL
'Execute the SP and give the results to the Recordset
objConn.SurveyDataSP "4", rsData
Do While Not rsData.EOF
Debug.Print rsData!Stratum
rsData.MoveNext
Loop
'Now write the data into Access Table
'Create connection string to Access DB table
'sConnectAccess = "Provider=Microsoft.ACE.OLEDB.12.0;" & _
"Data Source=C:\Databse1.accdb;" & _
"Mode = Share Exclusive"
'Command object to be used for Access SQL query
Set objCommand = New ADODB.Command
'objCommand.ActiveConnection = sConnectAccess
'Insert new record in the DB
'Load the SQL string into the command object
Do While Not rsData.EOF
objCommand.CommandText = "INSERT INTO table3 (" & rsData!Stratum & ")"
objCommand.Execute
rsData.MoveNext
Loop
End Sub
There is no need to write such large amounts of code and create world poverty. Save the execute command as a pass through query.
Eg:
Exec 4
Assuming the above is called sp1, then this code will append all data from the above into the local table:
CurrentDb.Execute "INSERT INTO sp1Local select sp1.* from sp1"
So all of this code can be done with ONE line of VBA code.
I am retrieving table names using ADOX, but any tables that are within a schema other than DBO are not listed.
Sub ListTablesADOX()
Dim Conn As New ADODB.Connection
'Open connection you want To get database objects
Conn.Provider = "MSDASQL"
Conn.Open "DSN=...;Database=...;", "UID", "PWD"
'Create catalog object
Dim Catalog As New ADOX.Catalog
Set Catalog.ActiveConnection = Conn
'List tables And columns
Dim Table As ADOX.Table
For Each Table In Catalog.Tables
Debug.Print Table.Name
Next
End Sub
I dropped using ADOX, re-coded all my get catalog info procedures using ADO OpenSchema methods instead, I couldn't get ADOX to anything beyond the dbo schema.