I am trying to run a stored procedure from Excel. I know how to do it without using dynamic dates but I need the date range to be dynamic.
Sub TestStoredProcedure()
Dim CServer As String
Dim CDatabase As String
Dim CLogon As String
Dim CPass As String
Dim StartDate As Date
Dim EndDate As Date
Dim TStartDate As String
Dim TEndDate As String
CServer = "111111" ' Your server name here
CDatabase = "111111" ' Your database name here
CLogon = "11111111" ' your logon here
CPass = "111111" ' your password here
Dim Cmd1 As New ADODB.Command
Dim rs As New ADODB.Recordset
Dim intTemp As Integer
Set Cmd1 = New ADODB.Command
Cmd1.ActiveConnection = cn
Cmd1.CommandText = "callstatisticsbyQ"
Cmd1.CommandType = adCmdStoredProc
Cmd1.Parameters.Refresh
Cmd1.Parameters(0).Value = Worksheets("Sheet2").Range("A1")
Cmd1.Parameters(1).Value = Worksheets("Sheet2").Range("A2")
Cmd1.Parameters(2).Value = Worksheets("Sheet2").Range("A3")
Set rs = Cmd1.Execute()
rs.Open Cmd1
Worksheets("Procedure Export").Range("A1").CopyFromRecordset rs
Call DumpSP("prcGetData", "", "", Worksheets("Procedure Export").Range("A1"))
End Sub
I get an error saying something about user defined type not defined.
To use ADO you click Tools->references in the VBA IDE & tick "Microsoft ActiveX Data Objects" - preferably the highest version thereof.
Additionally you use cn as the connection but its not defined in that sub (assuming its not global) & you will may need to Set Cmd1.ActiveConnection = cn.
Also take a look at this, it defines the input (adParaminput) paramaters in advance rather than using .Refresh which is pretty inefficient (takes a trip to the server)
Update for example:
rem for create procedure callstatisticsbyQ (#i int, #c varchar(10)) as select 1234;
Dim cn As ADODB.Connection
Dim Cmd1 As ADODB.Command
Dim rs As ADODB.Recordset
Set cn = New ADODB.Connection
Set Cmd1 = New ADODB.Command
Set Cmd1 = New ADODB.Command
cn.Open "Provider=SQLNCLI10;Server=1.2.3.4;Database=x;Uid=x; Pwd=x;"
Set Cmd1.ActiveConnection = cn
Cmd1.CommandText = "callstatisticsbyQ"
Cmd1.CommandType = adCmdStoredProc
Cmd1.Parameters.Append Cmd1.CreateParameter("p1", adInteger, adParamInput, , Worksheets("Sheet2").Range("A1"))
Cmd1.Parameters.Append Cmd1.CreateParameter("p2", adVarChar, adParamInput, 20, Worksheets("Sheet2").Range("A2"))
Set rs = Cmd1.Execute()
MsgBox rs(0)
rs.Close
cn.Close
Related
I'm trying up date an SQL table (Date field) with a date cell in excel and getting an error
Error #-2147217913: Operand type clah int is incompatible with Date
Connection to the database is fine.
This is the code i'm using
Private Sub CommandButton1_Click()
On Error GoTo FormLoadError
Dim conn As ADODB.Connection
Dim rs As ADODB.Recordset
Dim sConnString As String
Dim FromDate As Date
Dim ToDate As Date
Dim FromNumber As String
Sheet2.Range("a2:zz9999").ClearContents
' Create the connection string.
sConnString = "Provider=SQLOLEDB;Data Source=SQL;" & _
"Initial Catalog=M2MTECLIVE;" & _
"Integrated Security=SSPI;"
' Create the Connection and Recordset objects.
Set conn = New ADODB.Connection
Set rs = New ADODB.Recordset
' Open the connection and execute.
conn.Open sConnString
FromDate = Worksheets("Parameters").Range("b4") 'Cell be contains a date in the format YYYY-MM-DD
Set rs = conn.Execute("update dbo.M2MDates set FD = " & FromDate)
conn.Close
Any ideas ?
Consider using ADO parameters via ADO command object which avoids need of concatenating and punctuating values to SQL statement:
conn.Open sConnString
' PREPARED STATEMENT WITH QMARKS ?
strSQL = "update dbo.M2MDates set FD = ?"
FromDate = Worksheets("Parameters").Range("b4")
Set cmd = New ADODB.Command
With cmd
.ActiveConnection = conn
.CommandText = strSQL
.CommandType = adCmdText
' BIND DATE PARAMETER
.Parameters.Append .CreateParameter("date_prm", adDate, adParamInput, , FromDate)
' EXECUTE ACTION QUERY (NO RECORDSET)
.Execute
End With
conn.Close
Set cmd = Nothing: Set conn = Nothing
Seem to be getting unexpected white space when calling the stored procedure from VBA in Excel using ADODB object. The issue does not occur when running the procedure from SQL Server Management Studio.
exec usp_testloginalert '2015-11-29 00:00:00','2015-11-30 00:00:00',N'screen'
UPDATE
Code from vba
Function querylogs(ByVal todate As Date, ByVal fromdate As Date, ByVal desc As String)
Dim cn As ADODB.Connection
Dim cmdProd As ADODB.command
Dim prs As New ADODB.Recordset
sQuery = "usp_testloginalert"
Set cn = New ADODB.Connection
With cn
.Provider = "SQLOLEDB"
sConnection = "dbconn"
.ConnectionString = sConnection
.ConnectionTimeout = 1000
.CommandTimeout = 1000
End With
cn.Open sConnection
Set cmdProd = New ADODB.command
With cmdProd
.ActiveConnection = cn
.CommandType = adCmdStoredProc
.CommandText = "usp_testloginalert"
.CommandTimeout = 1000
End With
Dim prmFromDate As ADODB.Parameter
Set prmFromDate = cmdProd.CreateParameter("#FromDate", adDBDate,adParamInput)
prmFromDate.Value = fromdate
cmdProd.Parameters.Append prmFromDate
Dim prmToDate As ADODB.Parameter
Set prmToDate = cmdProd.CreateParameter("#ToDate", adDBDate, adParamInput)
prmToDate.Value = todate
cmdProd.Parameters.Append prmToDate
Dim prmDescritpion As ADODB.Parameter
cmdProd.Parameters.Append cmdProd.CreateParameter("Descritpion",adBSTR,adParamInput, 100, desc)
Set prs = New Recordset
prs.CursorLocation = adUseClient
prs.Open cmdProd.Execute
Application.EnableCancelKey = True
cn.Close
Set querylogs = prs
End Function
Hard to answer when we not see code of your procedure, but I can suggest you to use LTRIM and RTRIM to remove leading/trailing blanks.
In following: LTRIM(RTRIM( /* character_xpression */ ))
UPDATE
If It's not SQL issue, try to check for related posts:
Remove leading or trailing spaces in an entire column of data
Delete blanks from start and end of a string in vba
http://www.excelitems.com/2009/03/remove-extra-spaces-from-cell-value.html
issues resolved, set the parameter length to the length of the variable passed.
Dim lendesc As Integer
lendesc = Len(desc) + 1
Dim prmDescritpion As ADODB.Parameter
cmdProd.Parameters.Append cmdProd.CreateParameter("Descritpion", adBSTR,adParamInput, lendesc, desc)
I have a Access front end that has an ODBC connection titled fna to the Sybase back end on a server. I can easily reference the tables in the Sybase database but in the vba I need to be able to call stored procedures and functions that are in Sybase.
Function name is CalcStats.
Edit:
After reading through some of the links in the comment, I have gotten to the following code which seems to run but I can't figure out how to find the return value the function is providing.
Dim trash As String
Dim conn As ADODB.Connection
Dim cmd1 As ADODB.Command
Dim rs1 As Recordset
Set conn = New ADODB.Connection
conn.ConnectionString = "datasource=ODBC;DSN=fna"
conn.Open
Set cmd1 = New ADODB.Command
cmd1.ActiveConnection = conn
cmd1.CommandType = adCmdStoredProc
cmd1.CommandText = "CalcStats"
cmd1.Execute
Edit 2:
Finally figured out the output part. Thank you A.S.H for the links and Gord Thompson for the method for getting the connection string that for the ADODB that is needed.
So I can now create a connection, trigger the function and get the return value. However, now I'm working on the last part which is adding input parameters. I've added an input parameter to the function in sybase and saved it but I can't seem to pass an input value into the function on the Access side.
Dim trash As String
Dim conn As ADODB.Connection
Dim cmd1 As ADODB.Command
Set conn = New ADODB.Connection
conn.ConnectionString = "datasource=ODBC;DSN=fna"
conn.Open
Set cmd1 = New ADODB.Command
cmd1.ActiveConnection = conn
cmd1.CommandType = adCmdStoredProc
cmd1.CommandText = "CalcStats"
cmd1.Parameters.Append cmd1.CreateParameter("MeasurementClm", adInteger, adParamInput, , 3)
cmd1.Parameters.Append cmd1.CreateParameter("OutputValue1", adInteger, adParamReturnValue)
cmd1.Execute
trash = cmd1.Parameters.Item(0).Value
conn.Close
So the last problem I was having is that for whatever reason, I could declare an output parameter if there were no inputs but if there are inputs I had to remove the output parameter declaration. The Function output is in the parameters.item(0) position. Thanks to A.S.H and Gord Thompson for the links and suggestions. Here is the code I ended up with that is working now:
Dim trash As String
Dim conn As ADODB.Connection
Dim cmd1 As ADODB.Command
Dim rs1 As Recordset
Set conn = New ADODB.Connection
conn.ConnectionString = "datasource=ODBC;DSN=fna"
conn.Open
Set cmd1 = New ADODB.Command
cmd1.ActiveConnection = conn
cmd1.CommandType = adCmdStoredProc
cmd1.CommandText = "CalcStats"
cmd1.Parameters.Refresh
cmd1.Parameters.Append cmd1.CreateParameter("InputValue1", adInteger, adParamInput, , 3)
'cmd1.Parameters.Append cmd1.CreateParameter("OutputValue3", adInteger, adParamReturnValue)
cmd1.Execute
trash = cmd1.Parameters.Item(0).Value
conn.Close
I am struggling bit here with a stored procedure with parameters in VBA. The code below without parameters working fine but with parameters not working.
My code:
Sub CopyDataFromDatabase()
Dim Conn As ADODB.Connection
Dim Rs As ADODB.Recordset
Dim Fields As ADODB.Field
Dim Cmd As ADODB.Command
Set Conn = New ADODB.Connection
Set Cmd = New ADODB.Command
Set Rs = New ADODB.Recordset
Conn.Open "My connection string here--------"
Cmd.CommandType = adCmdStoredProc
Cmd.Parameters.Append Cmd.CreateParameter("#Division", adVarChar, adParamInput, 40)
Cmd.Parameters("#Division").Value = "South"
Cmd.Parameters.Append Cmd.CreateParameter("#Area", adVarChar, adParamInput, 40)
Cmd.Parameters("#Area").Value = "IT"
Cmd.CommandText = "My SP here------"
Set Rs = Cmd.Execute
On Error GoTo CloseRecordset
Worksheets.Add
For Each Fields In Rs.Fields
ActiveCell.Value = Fields.Name
ActiveCell.Font.Bold = True
ActiveCell.Font.Underline = True
ActiveCell.HorizontalAlignment = xlCenter
ActiveCell.Interior.Color = RGB(0, 128, 255)
ActiveCell.Font.Color = RGB(255, 255, 255)
ActiveCell.Offset(0, 1).Select
Next Fields
Range("A1").Select
Range("A2").CopyFromRecordset Rs
CloseRecordset:
Rs.Close
Set Rs = Nothing
Set Cmd = Nothing
CloseConnection:
Conn.Close
Set Conn = Nothing
End Sub
When I run, its not giving any error, just showing like executing but no result
Can anybody suggest where I am doing wrong? Thanks
I have successfully declared a variant array and populated the parameters (in order!) into that array, then passed to the array into the execute method to execute a stored procedure.
Assuming your stored proc expects 'Division' then 'Area', something like this may do the trick:
Sub CopyDataFromDatabase()
Dim Conn As ADODB.Connection
Dim Rs As ADODB.Recordset
Dim Fields As ADODB.Field
Dim Cmd As ADODB.Command
'New variable
Dim v_Params(1 To 2) As Variant 'assuming you have 2 parameters
Set Conn = New ADODB.Connection
Set Cmd = New ADODB.Command
Set Rs = New ADODB.Recordset
Conn.Open "My connection string here--------"
v_Params(1) = "South"
v_Params(2) = "IT"
With Cmd
.ActiveConnection = Conn
.CommandType = adCmdStoredProc
.CommandText = "My SP here------"
.CommandTimeout = 0
Set rs = .Execute(, v_Params)
End With
See if that works, as I am currently using this method successfully. I didn't see the need to modify the rest of your subroutine.
I used the With Cmd and End With to avoid fully qualifying the reference each time.
Updated
The issue, found by the author of the question, was that the SP was timing out when parameters were passed into it. The resolution was to set the CommandTimeout property to 0.
I am trying to execute a SQL Server stored procedure from Excel VBA. The procedure returns rows into a result set object. However, while running the code, it throws an error:
3704 Operation is not allowed when the object is closed
Note:
There is no problem with the database connection because Select query running on the same connection object are working fine.
Dim cn As ADODB.Connection
Dim rs As ADODB.Recordset
Dim cmd As ADODB.Command
Dim prm As ADODB.Parameter
Dim rst As New ADODB.Recordset
Set cn = New ADODB.Connection
Set cmd = New ADODB.Command
ThisWorkbook.initialize
cn.Provider = "sqloledb"
cn.Properties("Data Source").Value = ThisWorkbook.server
cn.Properties("Initial Catalog").Value = ThisWorkbook.db
cn.Properties("User ID").Value = "xxxxx"
cn.Properties("Password").Value = "xxxxx"
cn.Open
Set cmd = New ADODB.Command
cmd.CommandText = "Generate_KPI_Process_Quality_Check_RunTime"
cmd.CommandType = adCmdStoredProc
cmd.ActiveConnection = cn
Set prm = cmd.CreateParameter("#currentMonth", adChar, adParamInput, 255, cmb_month.Value)
cmd.Parameters.Append prm
Set prm = cmd.CreateParameter("#center", adChar, adParamInput, 255, cmb_center.Value)
cmd.Parameters.Append prm
rst.CursorType = adOpenStatic
rst.CursorLocation = adUseClient
rst.CursorLocation = adUseServer
rst.LockType = adLockOptimistic
rst.Open cmd
If (rst.BOF And rst.EOF) Then
'Some Code
End If
Put
SET NOCOUNT ON
in the stored procedure -- this will prevent output text generation like "1 record(s) updated".
You have to provide more parameters for the Open method of Recordset Object
try rst.Open cmd, cn
Use the Set keyword to assign the object:
Set cmd.ActiveConnection = cn
otherwise, the default property of the Connection object (which happen to be the connection string) will be assigned in lieu of the Connection object itself.
Just put another recordset that will contain resultsets
Dim rst1 As New ADODB.Recordset
SET rst1=rst.NextRecordset 'this will return the first resultset
If rst1.BOF or rst1.EOF Then...
'some code
End If