I am new in VBA via Outlook, so ...
I use Outlook 2016, and SQL Server 2017, and I try to connect a macro to SQL Server Express 2017 via ADODB.
Here is my code
On Error GoTo ErrorHandler
Dim cnnStr As String
cnnStr = "Provider=SQLOLEDB;" & _
"Server=ALTROISIEME\SQLEXPRESS;" & _
"Initial Catalog=XX_Options;" & _
"Trusted_Connection=SSPI;" & _
"uid=xxxx;" & _
"pwd=xxxxxx;"
'GoTo Fin_99
Dim cnn As New ADODB.Connection
cnn.CommandTimeout = 900
cnn.ConnectionString = cnnStr
cnn.Open
GoTo Fin_99
Dim cmd As ADODB.Command
Set cmd.ActiveConnection = cnn
cmd.CommandType = adCmdStoredProc
cmd.CommandText = "USP_Outlook_Add_File_Data"
cmd.Parameters.Append cmd.CreateParameter("#Categorie", adVarWChar, adParamInput, , "IB_DailyTrade")
cmd.Parameters.Append cmd.CreateParameter("#NomDuFichier", adVarWChar, adParamInput, , FileNameExt)
cmd.Parameters.Append cmd.CreateParameter("#Donnee", adVarWChar, adParamInput, , HTMLTxt)
Dim rst As New ADODB.Recordset
rst.CursorType = adOpenStatic
rst.CursorLocation = adUseClient
rst.LockType = adLockOptimistic
rst.Open cmd
Set rst = cmd.Execute
ExitNewItem:
GoTo Fin_99
ErrorHandler:
MsgBox Err.Number & " - " & Err.Description
Resume ExitNewItem
Fin_99:
On Error GoTo CloseRst
cnn.Close
Set cnn = Nothing
CloseRst:
rst.Close
Set rst = Nothing
The macro throws an error on line
Set cmd.ActiveConnection = Cnn
with a message.
91-Variable object or variable of block not defined
Could you help?
Thank you
André
I found all my issues. The code is not so far from my initial post:
On Error GoTo ErrorHandler
Dim cnnStr As String
cnnStr = "Provider=SQLOLEDB;" & _
"Server=?????????\SQLEXPRESS;" & _
"Initial Catalog=???????;" & _
"Trusted_Connection=SSPI;" & _
"uid=???;" & _
"pwd=???;"
Dim cnn As New ADODB.Connection
Set cnn = New ADODB.Connection
cnn.CommandTimeout = 900
cnn.ConnectionString = cnnStr
cnn.Open
Dim cmd As ADODB.Command
Set cmd = New ADODB.Command
cmd.ActiveConnection = cnn
cmd.CommandType = adCmdStoredProc
cmd.CommandText = "USP_Outlook_Add_File_Data"
cmd.Parameters.Append cmd.CreateParameter("#Categorie", adVarWChar, adParamInput, 50, "IB_DailyTrade")
cmd.Parameters.Append cmd.CreateParameter("#NomDuFichier", adLongVarWChar, adParamInput, -1, FileNameExt)
cmd.Parameters.Append cmd.CreateParameter("#Donnee", adLongVarWChar, adParamInput, -1, HTMLTxt)
Dim rst As New ADODB.Recordset
Set rst = New ADODB.Recordset
rst.CursorType = adOpenStatic
rst.CursorLocation = adUseClient
rst.LockType = adLockOptimistic
rst.Open cmd
Set rst = cmd.Execute
ExitNewItem:
GoTo Fin_99
ErrorHandler:
MsgBox Err.Number & " - " & Err.Description
Resume ExitNewItem
Fin_99:
If cnn.State = 1 Then
cnn.Close
Set cnn = Nothing
End If
If rst.State = 1 Then
rst.Close
Set rst = Nothing
End If
Related
This is my stored procedure which works fine in SQL Server Management Studio.
exec GroupCommissions #GroupNumberEntry = '01142'
Should produce a table of data.
I'm trying to run it in vba using the following code:
Dim rs As ADODB.Recordset
Dim cnSQL As ADODB.Connection
Dim sqlcommand As ADODB.Command, prm As Object
Set cnSQL = New ADODB.Connection
cnSQL.Open "Provider=SQLOLEDB; Data Source=bddc1didw1;Initial Catalog=Actuarial; Trusted_connection=Yes; Integrated Security='SSPI'"
Set sqlcommand = New ADODB.Command
sqlcommand.ActiveConnection = cnSQL
sqlcommand.CommandType = adCmdStoredProc
sqlcommand.CommandText = "GroupCommissions"
Set prm = sqlcommand.CreateParameter("GroupNumberEntry", adParamInput)
sqlcommand.Parameters.Append prm
sqlcommand.Parameters("GroupNumberEntry").Value = "01142"
Set rs = New ADODB.Recordset
rs.CursorType = adOpenStatic
rs.LockType = adLockOptimistic
rs.Open sqlcommand
ActiveSheet.Range("a3").CopyFromRecordset rs
But it just returns blank and I can't work out what I'm doing wrong. Also is there a simpler way to do this?
As discussed below i've managed to fix the issue by adding SET NOCOUNT ON to the original stored procedure. My issue now is I want to do a second stored procedure in the same code but it only seems to work for one. They both work individually however. So either I have to reopen the connection or use 2 on the defined variables? Here is the code:
Dim rs As ADODB.Recordset
Dim cnSQL As ADODB.Connection
Dim sqlcommand As ADODB.Command, prm As Object, prm2 As Object
Set cnSQL = New ADODB.Connection
cnSQL.Open "Provider=SQLOLEDB; Data Source=bddc1didw1;Initial Catalog=Actuarial; Trusted_connection=Yes; Integrated Security='SSPI'"
Set sqlcommand = New ADODB.Command
sqlcommand.ActiveConnection = cnSQL
'groupdates
sqlcommand.CommandType = adCmdStoredProc
sqlcommand.CommandText = "GroupDate"
Set prm = sqlcommand.CreateParameter("GroupNumberEntry", adVarChar, adParamInput, 5)
Set prm2 = sqlcommand.CreateParameter("ValuationDateEntry", adDate, adParamInput)
sqlcommand.Parameters.Append prm
sqlcommand.Parameters.Append prm2
sqlcommand.Parameters("GroupNumberEntry").Value = "01132"
sqlcommand.Parameters("ValuationDateEntry").Value = "08-31-2019"
Set rs = New ADODB.Recordset
rs.CursorType = adOpenStatic
rs.LockType = adLockOptimistic
rs.Open sqlcommand
ActiveSheet.Range("a2").CopyFromRecordset rs
'GroupCommissions
sqlcommand.CommandType = adCmdStoredProc
sqlcommand.CommandText = "GroupCommissions"
Set prm = sqlcommand.CreateParameter("GroupNumberEntry", adVarChar, adParamInput, 5)
sqlcommand.Parameters.Append prm
sqlcommand.Parameters("GroupNumberEntry").Value = "01132"
Set rs = New ADODB.Recordset
rs.CursorType = adOpenStatic
rs.LockType = adLockOptimistic
rs.Open sqlcommand
ActiveSheet.Range("DB2").CopyFromRecordset rs
Try replacing that line with something like this:
Set prm = sqlcommand.CreateParameter("GroupNumberEntry", adVarChar, GroupNumberEntry, 255)
Set the field type and length according to how your proc is defined.
Your code looked OK to me so I copied it into Excel (2016...) and tried it. It gave me an error on that line but adding the additional parameter values to CreateParameter fixed the issue. shrug It shouldn't matter since those are optional parameters, unless there is something maybe at the provider level.
you can try just sending the SQL PROCEDURE straight through as a CALL function.
Take a look at this:
Public connDB As New ADODB.Connection
Public rs As New ADODB.Recordset
Public strSQL As String
Public strConnectionstring As String
Public strServer As String
Public strDBase As String
Public strUser As String
Public strPwd As String
Public PayrollDate As String
Sub WriteStoredProcedure()
PayrollDate = "2017/05/25"
Call ConnectDatabase
On Error GoTo errSP
strSQL = "EXEC spAgeRange '" & PayrollDate & "'"
connDB.Execute (strSQL)
Exit Sub
errSP:
MsgBox Err.Description
End Sub
Sub ConnectDatabase()
If connDB.State = 1 Then connDB.Close
On Error GoTo ErrConnect
strServer = "SERVERNAME" ‘The name or IP Address of the SQL Server
strDBase = "TestDB"
strUser = "" 'leave this blank for Windows authentication
strPwd = ""
If strPwd > "" Then
strConnectionstring = "DRIVER={SQL Server};Server=" & strServer & ";Database=" & strDBase & ";Uid=" & strUser & ";Pwd=" & strPwd & ";Connection Timeout=30;"
Else
strConnectionstring = "DRIVER={SQL Server};SERVER=" & strServer & ";Trusted_Connection=yes;DATABASE=" & strDBase 'Windows authentication
End If
connDB.ConnectionTimeout = 30
connDB.Open strConnectionstring
Exit Sub
ErrConnect:
MsgBox Err.Description
End Sub
I'm trying to push a button in an excel worksheet and it should send the data from the a worksheet to the sql table. But this vba code is not uploading the data from excel to the database. I have similar other table and it works fine. Any suggestions or thoughts on this would be great.
Sub Send2SQL()
Dim cmd As New ADODB.Command
Dim rst As ADODB.Recordset
Dim UploadTime, SubmissionNumber, WorkbookSection, DataDescription1, DataDescription2, DataDescription3
Dim iValue, sValue, fValue, bValue, dValue, Omit
Dim UploadRow As Integer
Dim LastRow As Integer
'Establish Error Handler
On Error GoTo ErrorHandler
'Determine UploadTime
UploadTime = Format(Now, "mm\/dd\/yyyy hh\:mm\:ss")
'Loop Through Upload
For UploadRow = 2 To LastRow
With Sheets("DataCapture")
WorkbookSection = .Cells(UploadRow, WorkbookSectionColumn).Value
DataDescription1 = .Cells(UploadRow, DataDescription1Column).Value
DataDescription2 = .Cells(UploadRow, DataDescription2Column).Value
DataDescription3 = .Cells(UploadRow, DataDescription3Column).Value
iValue = .Cells(UploadRow, iValueColumn).Value
sValue = Left(.Cells(UploadRow, sValueColumn).Value, 400)
If sValue = "" Then sValue = Empty
fValue = .Cells(UploadRow, fValueColumn).Value
bValue = .Cells(UploadRow, bValueColumn).Value
dValue = .Cells(UploadRow, dValueColumn).Value
End With
With cmd
.ActiveConnection = conn
.CommandType = adCmdStoredProc
.CommandText = "[DataUpload]"
.Parameters.Append .CreateParameter("#TimeOfUpload", adDBTimeStamp, adParamInput, , UploadTime)
.Parameters.Append .CreateParameter("#WorkbookSection", adVarChar, adParamInput, 60, WorkbookSection)
.Parameters.Append .CreateParameter("#DataDescription1", adVarChar, adParamInput, 255, DataDescription1)
.Parameters.Append .CreateParameter("#DataDescription2", adVarChar, adParamInput, 60, DataDescription2)
.Parameters.Append .CreateParameter("#DataDescription3", adVarChar, adParamInput, 60, DataDescription3)
.Parameters.Append .CreateParameter("#iValue", adBigInt, adParamInput, , iValue)
.Parameters.Append .CreateParameter("#sValue", adVarChar, adParamInput, 400, sValue)
.Parameters.Append .CreateParameter("#fValue", adDouble, adParamInput, , fValue)
.Parameters.Append .CreateParameter("#bValue", adBoolean, adParamInput, , bValue)
.Parameters.Append .CreateParameter("#dValue", adDate, adParamInput, , dValue)
.Parameters.Append .CreateParameter("#FileID", adBigInt, adParamInput, , rstOut)
Set rst = .Execute
End With
Set cmd = New ADODB.Command
Next UploadRow
'Turn off ErrorHandler & Exit Sub
On Error GoTo 0
Exit Sub
ErrorHandler:
MsgBox "There was an Error Uploading your data" & vbNewLine & vbNewLine & "An Automated Email has been sent to Sai Latha Suresh from Acturaial"
On Error GoTo 0
End
End Sub
You are using Execute on your Recordset, when you should be using Execute on your Command object.
From Excel to SQL Server? Try it this way.
Sub Rectangle1_Click()
'TRUSTED CONNECTION
On Error GoTo errH
Dim con As New ADODB.Connection
Dim rs As New ADODB.Recordset
Dim strPath As String
Dim intImportRow As Integer
Dim strFirstName, strLastName As String
Dim server, username, password, table, database As String
With Sheets("Sheet1")
server = .TextBox1.Text
table = .TextBox4.Text
database = .TextBox5.Text
If con.State <> 1 Then
con.Open "Provider=SQLOLEDB;Data Source=" & server & ";Initial Catalog=" & database & ";Integrated Security=SSPI;"
'con.Open
End If
'this is the TRUSTED connection string
Set rs.ActiveConnection = con
'delete all records first if checkbox checked
If .CheckBox1 Then
con.Execute "delete from tbl_demo"
End If
'set first row with records to import
'you could also just loop thru a range if you want.
intImportRow = 10
Do Until .Cells(intImportRow, 1) = ""
strFirstName = .Cells(intImportRow, 1)
strLastName = .Cells(intImportRow, 2)
'insert row into database
con.Execute "insert into tbl_demo (firstname, lastname) values ('" & strFirstName & "', '" & strLastName & "')"
intImportRow = intImportRow + 1
Loop
MsgBox "Done importing", vbInformation
con.Close
Set con = Nothing
End With
Exit Sub
errH:
MsgBox Err.Description
End Sub
My setup looks like this.
Also.......Excel VBA - Update SQL Server Table:
http://www.cnblogs.com/anorthwolf/archive/2012/04/25/2470250.html
http://www.excel-sql-server.com/excel-sql-server-import-export-using-vba.htm
...More
http://www.ozgrid.com/forum/showthread.php?t=169953
http://stackoverflow.com/questions/2567150/excel-vba-sql-data
http://msgroups.net/microsoft.public.excel.programming/vba-to-export-large-tables/61433
http://www.codeproject.com/Questions/475817/Howplustoplusupdateplussqlplusserverplusdataplusfr
http://www.excelguru.ca/forums/showthread.php?992-SQL-Select-Insert-Update-queries-from-Excel-vba
http://www.mrexcel.com/forum/excel-questions/617303-updating-records-access-table-using-excel-visual-basic-applications.html
http://www.excelforum.com/excel-programming-vba-macros/501147-how-to-use-vba-to-update-a-sql-server-table-from-a-spreadsheet.html
I'm trying to run the following:
Sub sendMailViaADO()
Dim cmdStoredFunct As ADODB.Command
Dim r As ADODB.Recordset
Dim strConn As String
strConn = _
"PROVIDER=SQLOLEDB.1;" & _
"P-----D=xxxxx;" & _
"PERSIST SECURITY INFO=True;" & _
"USER ID=yyyyyy;" & _
"INITIAL CATALOG=xxxxx;" & _
"DATA SOURCE=xxxxx;" & _
"USE PROCEDURE FOR PREPARE=1;" & _
"AUTO TRANSLATE=True;" & _
"CONNECT TIMEOUT=0;" & _
"COMMAND TIMEMOUT=0" & _
"PACKET SIZE=4096;" & _
"USE ENCRYPTION FOR DATA=False;" & _
"TAG WITH COLUMN COLLATION WHEN POSSIBLE=False"
Set c= New ADODB.Connection
c.ConnectionString = strConn
c.CommandTimeout = 0
c.Open
Set cmdStoredFunct = New ADODB.Command
Set cmdStoredFunct.ActiveConnection = c
Set r = New ADODB.Recordset
With cmdStoredFunct
.CommandText = "msdb..sp_send_dbmail"
.CommandText = adCmdStoredProc
.Parameters.Append .CreateParameter("#recipients", adVarWChar, adParamInput, 50, "me#me.co.uk;")
.Parameters.Append .CreateParameter("#subject", adVarWChar, adParamInput, 50, "xxx")
.Parameters.Append .CreateParameter("#body", adVarWChar, adParamInput, 50, "yyy")
Set r = .Execute
End With
'>>>
'>>>is there another way like the following ?
'Dim sTemp1
'sTemp1 = "{call msdb.dbo.sp_send_dbmail('me#me.co.uk', 'xxx', 'yyy')}"
'>>>
If Not (cmdStoredFunct Is Nothing) Then
Set cmdStoredFunct.ActiveConnection = Nothing
Set cmdStoredFunct = Nothing
End If
If Not (c Is Nothing) Then
If (c.State And 1) = 1 Then c.Close
End If
End Sub
It is erroring on the execute command Set r = .Execute with this message:
Looks to me like it is finding the stored proc ok but that the string it is using is causing this mysterious exception.
How do I fix this?
As an example if you want to avoid using a command object:
Dim sSQL as String
sSQL =
"EXEC msdb.dbo.sp_send_dbmail " & _
#recipients='me#me.co.uk'," & _
#subject='xxx'," & _
#body='yyy'"
Call r.Open(sSQL,c)
People will huff and puff about SQL injection but thats the least of your worries.
I am making a .MDB file which include a ms access database and a form made with vb 6. I am using ms access 2000, and I need to connect to both my local database in the MDB, and a remote MS SQL 2005 database.
In the below code, I can use a msgbox to display the value return from the result set, but when try to output it in a textBox, e.g: txtStatus.Value = txtStatus.Value & rstRecordSet.Fields(1) & vbCrLf, it just hangs. And the method show in the original example from the tutorial got a method of Debug.Print something, but it turns out didn't do anything which I can see. I mean, VB doesn't have a console panel, where will the print statement goes to?
The code with got error:
Function Testing()
On Error GoTo Error_Handling
Dim conConnection As New ADODB.Connection
Dim cmdCommand As New ADODB.Command
Dim rstRecordSet As New ADODB.Recordset
conConnection.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & _
App.Path & "\" & CurrentDb.Name & ";"
conConnection.CursorLocation = adUseClient
With cmdCommand
.ActiveConnection = conConnection
.CommandText = "SELECT * FROM Opt_In_Customer_Record;"
.CommandType = adCmdText
End With
With rstRecordSet
.CursorType = adOpenStatic
.CursorLocation = adUseClient
.LockType = adLockOptimistic
.Open cmdCommand
End With
If rstRecordSet.EOF = False Then
rstRecordSet.MoveFirst
Do
MsgBox "Record " & rstRecordSet.AbsolutePosition & " " & _
rstRecordSet.Fields(0).Name & "=" & rstRecordSet.Fields(0) & " " & _
rstRecordSet.Fields(1).Name & "=" & rstRecordSet.Fields(1)
rstRecordSet.MoveNext
Loop Until rstRecordSet.EOF = True
End If
conConnection.Close
Set conConnection = Nothing
Set cmdCommand = Nothing
Set rstRecordSet = Nothing
Exit Function
Error_Handling:
MsgBox "Error during function Testing!"
Exit Function
End Function
I thought it was a joke at the beginning ;-)
Anyway I assume you're talking about ADO, as in your title.
Here you can find stuff.
This site will help you with the connection strings for different database.
The difference between access and sql server using ADO it is exactly the connection string.
I would suggest you to avoid Remote Data Controls cause make your life simpler at the beginning but then you have to struggle with them cause they don't work properly.
This is an example of connection and fetch of data:
Dim cnn As New ADODB.Connection
Dim cmd As New ADODB.Command
Dim strSql As String
cnn.ConnectionString = _
"Provider=Microsoft.Jet.OLEDB.4.0;" & _
"Data Source=m:\testdbSource\testSource.mdb;" & _
"User Id=admin;Password=;"
cnn.Open
cmd.ActiveConnection = cnn
cmd.CommandType = adCmdText
cmd.CommandText = "select * from tblSource"
cmd.Execute
Set cmd = Nothing
cnn.Close
Set cnn = Nothing
This sample works for me:
Function Testing()
On Error GoTo Error_Handling
Dim MyDb As String
Dim conConnection As New ADODB.Connection
Dim cmdCommand As New ADODB.Command
Dim rstRecordSet As New ADODB.Recordset
MyDb = "db1.mdb"
With conConnection
.Provider = "Microsoft.Jet.OLEDB.4.0"
.ConnectionString = App.Path & "\" & MyDb
.Open
End With
With cmdCommand
.ActiveConnection = conConnection
.CommandText = "SELECT * FROM Opt_In_Customer_Record;"
.CommandType = adCmdText
End With
With rstRecordSet
.CursorType = adOpenStatic
.CursorLocation = adUseClient
.LockType = adLockOptimistic
.Open cmdCommand
End With
Do While Not rstRecordSet.EOF
MsgBox "Record " & rstRecordSet.AbsolutePosition & " " & _
rstRecordSet.Fields(0).Name & "=" & rstRecordSet.Fields(0) & " " & _
rstRecordSet.Fields(1).Name & "=" & rstRecordSet.Fields(1)
rstRecordSet.MoveNext
Loop
conConnection.Close
Set conConnection = Nothing
Set cmdCommand = Nothing
Set rstRecordSet = Nothing
Exit Function
Error_Handling:
MsgBox "Error during function Testing!"
MsgBox Err.Description
End Function
This code was once working on sql server 2005. Now isolated in a visual basic 6 sub routine using ADODB to connect to a sql server 2008 database it throws an error saying:
"Login failed for user 'admin' "
I have since verified the connection string does work if i replace the body of this sub with the alternative code below this sub. When I run the small program with the button, it stops where it is marked below the asterisk line. Any ideas? thanks in advance.
Private Sub Command1_Click()
Dim cSQLConn As New ADODB.Connection
Dim cmdGetInvoices As New ADODB.Command
Dim myRs As New ADODB.Recordset
Dim dStartDateIn As Date
dStartDateIn = "2010/05/01"
cSQLConn.ConnectionString = "Provider=sqloledb;" _
& "SERVER=NET-BRAIN;" _
& "Database=DB_app;" _
& "User Id=admin;" _
& "Password=mudslinger;"
cSQLConn.Open
cmdGetInvoices.CommandTimeout = 0
sProc = "GetUnconvertedInvoices"
'On Error GoTo GetUnconvertedInvoices_Err
With cmdGetInvoices
.CommandType = adCmdStoredProc
.CommandText = "_sp_cwm5_GetUnCvtdInv"
.Name = "_sp_cwm5_GetUnCvtdInv"
Set oParm1 = .CreateParameter("#StartDate", adDate, adParamInput)
.Parameters.Append oParm1
oParm1.Value = dStartDateIn
.ActiveConnection = cSQLConn
End With
With myRs
.CursorLocation = adUseClient
.LockType = adLockBatchOptimistic
.CursorType = adOpenKeyset
'.CursorType = adOpenStatic
.CacheSize = 5000
'***************************Debug stops here
.Open cmdGetInvoices
End With
If myRs.State = adStateOpen Then
Set GetUnconvertedInvoices = myRs
Else
Set GetUnconvertedInvoices = Nothing
End If
End Sub
Here is the code which validates the connection string is working.
Dim cSQLConn As New ADODB.Connection
Dim cmdGetInvoices As New ADODB.Command
Dim myRs As New ADODB.Recordset
cSQLConn.ConnectionString = "Provider=sqloledb;" _
& "SERVER=NET-BRAIN;" _
& "Database=DB_app;" _
& "User Id=admin;" _
& "Password=mudslinger;"
cSQLConn.Open
cmdGetInvoices.CommandTimeout = 0
sProc = "GetUnconvertedInvoices"
With cmdGetInvoices
.ActiveConnection = cSQLConn
.CommandText = "SELECT top 5 * FROM tarInvoice;"
.CommandType = adCmdText
End With
With myRs
.CursorLocation = adUseClient
.LockType = adLockBatchOptimistic
'.CursorType = adOpenKeyset
.CursorType = adOpenStatic
'.CacheSize = 5000
.Open cmdGetInvoices
End With
If myRs.EOF = False Then
myRs.MoveFirst
Do
MsgBox "Record " & myRs.AbsolutePosition & " " & _
myRs.Fields(0).Name & "=" & myRs.Fields(0) & " " & _
myRs.Fields(1).Name & "=" & myRs.Fields(1)
myRs.MoveNext
Loop Until myRs.EOF = True
End If
This probably shouldn't cause the error you're seeing, but according to http://msdn.microsoft.com/en-us/library/ms677593(VS.85).aspx:
"Only a setting of adOpenStatic is supported if the CursorLocation property is set to adUseClient. If an unsupported value is set, then no error will result; the closest supported CursorType will be used instead."
Turns out it was a linked database permissions error in sql server 2008. I had to delete the link and recreated it with a login/password.