executing SQL in workbook - excel

I am unable to execute a simple sql statement. - sorry I am sure this is simple and I am missing something small. Error says missing the object.
dbPath = "C:\Users\User\Documents\test0419.accdb"
tblName = "Wait_Data_Table"
strcon = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source='" & dbPath & "';"
conn.Open strcon
Set wrkSpaceNew = DBEngine.CreateWorkspace("Check", "admin", "", dbUseJet)
rcdDetail = ("SELECT order.ord_id, order.job_id, order.bc_desc, order.ord_amount, order.ord_diff FROM Order")
Set rs = DBEngine.BeginTrans(rcdDetail)

You can use either DAO or ADODB, not normally both. See difference-between-ado-and-dao
Option Explicit
Sub UseDAO()
Const SQL = " SELECT order.ord_id, order.job_id, order.bc_desc, " & _
" order.ord_amount, order.ord_diff " & _
" FROM [Order]"
Const dbpath = "C:\Users\User\Documents\test0419.accdb"
Dim wkspace As workspace, db As DAO.Database, rs As DAO.Recordset
Set wkspace = DBEngine.CreateWorkspace("Check", "admin", "", dbUseJet)
Set db = wkspace.OpenDatabase(dbpath)
Set rs = db.OpenRecordset(SQL)
Sheet1.Range("A1").CopyFromRecordset rs
db.Close
Set db = Nothing
wkspace.Close
Set wkspace = Nothing
MsgBox "Results on sheet " & Sheet1.Name, vbInformation, "DAO"
End Sub
Sub UseADODB()
Const SQL = " SELECT order.ord_id, order.job_id, order.bc_desc, " & _
" order.ord_amount, order.ord_diff " & _
" FROM [Order]"
Const dbpath = "C:\Users\User\Documents\test0419.accdb"
Dim strConn As String, conn As ADODB.Connection, rs As ADODB.Recordset
strConn = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source='" & dbpath & "';"
Set conn = New ADODB.Connection
conn.Open strConn
Set rs = conn.Execute(SQL)
Sheet1.Range("A1").CopyFromRecordset rs
conn.Close
MsgBox "Results on sheet " & Sheet1.Name, vbInformation, "ADODB"
End Sub

Don't forget to add Activex Data Object in Reference Section
Dim baglanti As New ADODB.Connection
Dim rs As New ADODB.Recordset
Dim sunucu, veritabani, id, sifre, sorgu As String
sunucu = "DESKTOP-GF32DLC\SQLEXPRESS"
veritabani = "AdventureWorks2014"
id = ""
sifre = ""
sorgu = "SELECT * FROM [HumanResources].[Department] Where [GroupName]='Manufacturing'"
baglanti.Open "Driver={SQL SERVER};Server=" & sunucu & ";Database=" & veritabani & _
";Uid=" & id & ";Pwd=" & sifre & ";"
rs.Open sorgu, baglanti, adOpenStatic
With Range("A1:AA1000")
.ClearContents
.CopyFromRecordset rs
End With
rs.Close
baglanti.Close
This way you can make a healthy sql connection.
I used to use it to connect sql in the past

Related

Excel function with ADODB connection string to Access database

I've created below Excel function which connects to an access database with ADODB (approx 10k lines).
It generally works but there are two main issues:
It is unreliable: often it returns 0 while the result should be different
It is definitely slow
Any suggestion on how to improve?
Public Function TotaleSQL(Cat As String, SubCat As String, Anno As Integer) As Long
On Error Resume Next
Dim cn As Object, rs As Object, output As String, sql As String
Dim src As String
Dim Total As Long
Dim CatLong As String
src = "Z:\Report.accdb"
'---Connecting to the Data Source---
Set cn = CreateObject("ADODB.Connection")
With cn
.Provider = "Microsoft.ACE.OLEDB.12.0"
.connectionstring = "Data Source=" & src & ";Persist Security Info=False"
.Open
End With
'---Run the SQL SELECT Query---
CatLong = "'" & Cat & ":" & SubCat & "'"
sql = "SELECT Report.Withdrawal, Report.Deposit, Report.Category, Report.Date FROM Report WHERE (((Report.Category)=" & CatLong & ") AND ((Year([date]))=" & Anno & "));"
'sql = "SELECT * FROM [Sheet1$]"
Set rs = cn.Execute(sql)
Total = 0
Do
Total = Total + Val(rs(1) & "") - Val(rs(0) & "")
rs.Movenext
Loop Until rs.EOF
'---Clean up---
rs.Close
cn.Close
Set cn = Nothing
Set rs = Nothing
TotaleSQL = Total
End Function
If Cat, SubCat or Anno are user inputs it is more secure to use parameters in your query. For example
Public Function TotaleSQL(Cat As String, SubCat As String, Anno As Integer)
Const DATABASE = "Z:\Report.accdb"
Const TABLE_NAME = "Report"
Const SQL = " SELECT SUM(iif(Deposit is null,0,Deposit) " & _
" - iif(Withdrawal is null,0,Withdrawal)) " & _
" FROM " & TABLE_NAME & _
" WHERE Category = ? " & _
" AND YEAR(ddate)= ? "
Dim cn As Object, cmd As Object, rs As Object
'---Connecting to the Data Source---
Set cn = CreateObject("ADODB.Connection")
With cn
.Provider = "Microsoft.ACE.OLEDB.12.0"
.connectionstring = "Data Source=" & DATABASE & ";Persist Security Info=False"
.Open
End With
' create command
Set cmd = CreateObject("ADODB.Command")
With cmd
.ActiveConnection = cn
.CommandText = SQL
.CommandType = 1 'adCmdText
.Parameters.Append .CreateParameter("P1", 200, 1, 50) ' 1=adParamInput 200=adVarChar
.Parameters.Append .CreateParameter("P2", 3, 1) ' 3=adInteger
End With
' execute with parameters
With cmd
.Parameters(0).Value = Cat & ":" & SubCat
.Parameters(1).Value = Anno
Set rs = .Execute
End With
TotaleSQL = rs(0)
rs.Close
cn.Close
Set cn = Nothing
Set rs = Nothing
Set cmd = Nothing
End Function
Sub test()
Debug.Print TotaleSQL("Cat", "SubCat", 2020)
End Sub

How to set connection string in excel to import data from sql?

I want to import data from 2 columns in SQL server, im following this code from http://buffalobi.com/excel/excel-vba-import-sql-server-data/, whats wrong?
Private Sub CommandButton2_Click()
Call CommandButton1_Click
Dim conn As New ADODB.Connection, cmd As New ADODB.Command, rs As New ADODB.Recordset
With conn
.ConnectionString = _
"Provider = Microsoft.ACE.OLEDB.12.0; " & _
"data source=localhost; " & _
"initial catalog=PTrails_Core_DB;" & _
"integrated security=True;"
.Open
End With
and i get this message
I would set 'ConnectionString' as variable and use that to open. If this doesn't work, it would have to be the actual link you're referring to that's causing an issue. Maybe because it's ending on semicolon.
Dim ConnectionString as String
ConnectionString = "Provider = Microsoft.ACE.OLEDB.12.0;data source=localhost;initial catalog=PTrails_Core_DB;integrated security=True"
conn.Open ConnectionString
This will do what you want.
Sub ImportFromSQLServer()
Dim Cn As ADODB.Connection
Dim Server_Name As String
Dim Database_Name As String
Dim User_ID As String
Dim Password As String
Dim SQLStr As String
Dim RS As ADODB.Recordset
Set RS = New ADODB.Recordset
Server_Name = "your_server_name"
Database_Name = "Northwind"
'User_ID = "******"
'Password = "****"
SQLStr = "select Field1, Field2 from dbo.TBL" 'and PostingDate = '2006-06-08'"
Set Cn = New ADODB.Connection
Cn.Open "Driver={SQL Server};Server=" & Server_Name & ";Database=" & Database_Name & ";"
'& ";Uid=" & User_ID & ";Pwd=" & Password & ";"
RS.Open SQLStr, Cn, adOpenStatic
With Worksheets("Sheet1").Range("A1")
.ClearContents
.CopyFromRecordset RS
End With
RS.Close
Set RS = Nothing
Cn.Close
Set Cn = Nothing
End Sub

Multiple errors while updating a recordset into Access table

I am putting in place a code for that acts as a time clock. I want to make a "smart" time clock where I store time in/out in different columns. To do that, I have set up a logic that:
1. Updates the "time_in" column when the user has not clocked in yet for the day
2. Updates the "Break Out" column when the "Time in" is not empty and the "Break Out" is empty
3. Updates the "Break In" column when both "Time in" and "Break Out" columns are not empty but "Break In" is
4.Updates the "Time Out" column whenever all the previous column are not empty but "Time Out" column is
I don't know if this is the best to achieve my goal, but that's the logic I am trying to implement.
To achieve this, I found no other solution but to have multiple recordset open for my connection, each one checking for the conditions above but I am getting so many errors that I don't even know where they are coming from. Sometimes the code works fine till the end the field is updated in the Access table, sometimes I get errors like 'Either EOF or BOF is empty...' or "Operation not allowed in this context" when getting to the update statement
Here is the code:
`Private Sub CommandButton1_Click()
Dim conn As Object
Dim rs As Object
Dim rs2 As Object
Dim rs3 As Object
Dim rs4 As Object
Dim rs5 As Object
Dim rs6 As Object
Dim strconn As String
Dim qry As String
Dim sql As String
Dim extrct As String
Dim extrct2 As String
Dim extrct3 As String
Dim extrct4 As String
Dim BadgeId As String
Set conn = CreateObject("ADODB.connection")
Set rs = CreateObject("ADODB.Recordset")
Set rs2 = CreateObject("ADODB.Recordset")
Set rs3 = CreateObject("ADODB.Recordset")
Set rs4 = CreateObject("ADODB.Recordset")
Set rs5 = CreateObject("ADODB.Recordset")
Set rs6 = CreateObject("ADODB.Recordset")
strconn = "Provider=Microsoft.ACE.OLEDB.12.0;" & "Data source = [Path]"
qry = "select * from pointage"
sql = "select * from employes where actif='Yes' and matricule=" & Val(POINTAGE.PointMatricule)
extrct = "select * from pointage where matricule=" & Me.PointMatricule & " " & "and fix(date_prestation)= Date()"
extrct2 = "select * from pointage where matricule=" & Me.PointMatricule & " and fix(date_prestation)= Date()" & " and pause_out is null"
extrct3 = "select * from pointage where matricule=" & Me.PointMatricule & " and fix(date_prestation)= Date()" & " and pause_out is not null" & " and pause_in is null"
extrct4 = "select * from pointage where matricule=" & Me.PointMatricule & " and fix(date_prestation)= Date()" & " and pause_out is not null" & " and pause_in is not null" & " and heure_out is null"
conn.Open (strconn)
rs.Open qry, conn, adOpenKeyset, adLockOptimistic, adCmdText
rs2.Open sql, conn, adOpenKeyset, adLockOptimistic, adCmdText
rs3.Open extrct, conn, adOpenKeyset, adLockOptimistic, adCmdText
rs4.Open extrct2, conn, adOpenKeyset, adLockOptimistic, adCmdText
rs5.Open extrct3, conn, adOpenKeyset, adLockOptimistic, adCmdText
rs6.Open extrct4, conn, adOpenKeyset, adLockOptimistic, adCmdText
If rs3.EOF And rs3.BOF Then
With rs
.AddNew
.Fields("matricule").Value = Me.PointMatricule
.Fields("date_prestation").Value = Format(Date, "dd/mm/yyyy")
.Fields("heure_in").Value = Format(Time, "hh:mm:ss")
End With
GoTo 3
ElseIf Not (rs4.EOF And rs4.BOF) Then
With rs4
.Fields("pause_out").Value = Format(Time, "hh:mm:ss") 'Error: Either EOF or BOF...
End With
ElseIf Not (rs5.EOF And rs5.BOF) Then
With rs5
.Fields("pause_in").Value = Format(Time, "hh:mm:ss")
End With
ElseIf Not (rs6.EOF And rs6.BOF) Then
With rs6
.Fields("pause_out").Value = Format(Time, "hh:mm:ss")
End With
end if
rs.Update
rs.Close
Set rs = Nothing
rs2.Close
Set rs2 = Nothing
rs3.Close
Set rs3 = Nothing ' From here on is where I get errors: Not allowed...
rs4.Close
Set rs4 = Nothing
rs5.Close
Set rs5 = Nothing
rs6.Close
Set rs6 = Nothing
conn.Close
Set conn = Nothing
end sub`
Can someone please me better this code? Or maybe there is a better way to approach this...
PS: There are some words in french, sorry. Translation: Pause: Break. Heure: Hour. Matricule: Unique ID
Untested (and assuming your SQL is correct) but you could probably do it this way with a single recordset:
Private Sub CommandButton1_Click()
Dim conn As Object
Dim rs As Object
Dim strconn As String
Dim extrct As String, tm
Set conn = CreateObject("ADODB.connection")
strconn = "Provider=Microsoft.ACE.OLEDB.12.0;" & _
"Data source = [Path]"
conn.Open strconn
Set rs = CreateObject("ADODB.Recordset")
extrct = "select * from pointage where matricule=" & Me.PointMatricule & _
" and fix(date_prestation)= Date()"
tm = Format(Time, "hh:mm:ss")
rs.Open extrct, conn, adOpenKeyset, adLockOptimistic, adCmdText
With rs
If .EOF Then
'no entry yet for today...
.AddNew
.Fields("matricule").Value = Me.PointMatricule
.Fields("date_prestation").Value = Date ' Format(Date, "dd/mm/yyyy")
.Fields("heure_in").Value = tm
Else
'have an entry for today - figure out which field to update
If IsNull(.Fields("pause_out")) Then
.Fields("pause_out").Value = tm
ElseIf IsNull(.Fields("pause_in")) Then
.Fields("pause_in").Value = tm
ElseIf IsNull(.Fields("heure_out")) Then
.Fields("heure_out").Value = tm
End If
End If
.Update 'save changes
.Close
End With
conn.Close
Set conn = Nothing
End Sub

Exporting from Excel to Access error

I am trying to export a table from Excel to a table in an Access DB, but I keep getting an error "Database or Object is read only". Here is the code in qestion.
dbWB = Application.ActiveWorkbook.FullName
dbWS = Application.ActiveSheet.Name
dsh = "[" & dbWS & "$]"
Set DB = CreateObject("ADODB.Connection")
dbPath = "\\Corpaa.aa.com\CampusHome\IOCADHome02\758673\Projects\Global Analysis Tool\MX Analysis DB\Global Line MX Hub Review DB.accdb"
scn = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & dbPath
DB.Open scn
DB.Execute "DELETE * FROM tblNewSchedule;"
SQLInsert = "INSERT INTO tblNewSchedule "
SQLSelect = "SELECT * "
SQLFrom = "FROM [Excel 8.0; HDR=YES; DATABASE= " & dbWB & "]." & dsh & " "
strQry = SQLInsert & SQLSelect & SQLFrom & ";"
DB.Execute strQry
DB.Close
The DELETE qry executes just fine with no errors. The problem is the strQry execution. I believe it is refrencing that the WB is read-only, but I am running the code from the WB. I am running Office 2010. Thank you for your assistance.
so, after continuing my search, I discovered a different approach that worked perfectly. I found it on this here
Here is my new working code. Thanks for the assistance.
dbWB = Application.ActiveWorkbook.FullName
dbWS = Application.ActiveSheet.Name
dsh = "[" & dbWS & "$]"
Set DB = CreateObject("ADODB.Connection")
dbPath = "\\Corpaa.aa.com\CampusHome\IOCADHome02\758673\Projects\Global Analysis Tool\MX Analysis DB\Global Line MX Hub Review DB.accdb"
scn = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & dbPath
DB.Open scn
Dim rs As ADODB.Recordset
Dim r As Long
Dim y As Long
y = TWB.Cells(1, 1).End(xlDown).Row
r = TWB.Cells(1, 1).End(xlToRight).Column
DB.Execute "DELETE * FROM tblNewSchedule;"
Set rs = New ADODB.Recordset
rs.Open "tblNewSchedule", DB, adOpenKeyset, adLockOptimistic, adCmdTable
For i = 2 To y
With rs
.AddNew
For j = 1 To r
fName = TWB.Cells(1, j)
fData = TWB.Cells(i, j)
.Fields(fName) = fData
Next j
End With
Next i
DB.Close

Run access query from Excel and pass parameters to the query

How to execute a query in MS Access db from Excel VBA code or macro.
MS-Access query accepts some parameters, that needs to be passed from Excel.
Thanks
Here is one possibility:
Dim cn As Object
Dim strFile As String
Dim strCon As String
Dim strSQL As String
strFile = "C:\docs\Test.mdb"
strCon = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & strFile
''Late binding, so no reference is needed
Set cn = CreateObject("ADODB.Connection")
cn.Open strCon
strSQL = "INSERT INTO ATable (AField) " _
& "VALUES (" & Sheet1.[A1] & ")"
cn.Execute strSQL
cn.Close
Set cn = Nothing
You can also refer in-line in the sql to a dataset from Excel.
EDIT re comments
Using a command:
strSQL = "SELECT * FROM ATable " _
& "WHERE AField = #AField"
With cmd
Set .ActiveConnection = cn
.CommandText = strSQL
.CommandType = 1 'adCmdText
''ADO Datatypes are often very particular
''adSmallInt = 2 ; adParamInput = 1
.Parameters.Append .CreateParameter("#AField", 2, 1, , Sheet1.[A1])
End With
Set rs = cmd.Execute
See also: http://support.microsoft.com/kb/181782
This uses ADODB.
Set m_Connection = New Connection
If Application.Version = "12.0" Then
m_Connection.Provider = "Microsoft.ACE.OLEDB.12.0"
Else
m_Connection.Provider = "Microsoft.Jet.OLEDB.4.0"
End If
m_Connection.Open <full path to Access DB>
If m_Connection.State > 0 Then
Dim rsSource As New Recordset
rsSource.Open strQuery, m_Connection, adOpenForwardOnly, adLockReadOnly
Dim result As Long
Dim rngTarget As Range
rngTarget = ThisWorkbook.Worksheets(m_SheetName).Range("A1")
If Not rsSource.BOF Then
result = rngTarget.CopyFromRecordset(rsSource)
End If
If rsSource.State Then rsSource.Close
Set rsSource = Nothing
End If
So it runs the query and puts it where you like. strQuery is the name of a query in the db or an SQL string.

Resources